#define DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
// EXTERNAL INCLUDES
+#include <dali/graphics-api/graphics-command-buffer-create-info.h>
#include <dali/graphics-api/graphics-command-buffer.h>
+#include <dali/graphics-api/graphics-types.h>
// INTERNAL INCLUDES
-#include "egl-graphics-controller.h"
-#include "gles-graphics-pipeline.h"
+#include "gles-graphics-resource.h"
#include "gles-graphics-types.h"
+#include "gles-sync-object.h"
+
+#include <cstring>
namespace Dali::Graphics::GLES
{
-class Texture;
-class Buffer;
-class Sampler;
class Pipeline;
-
+class RenderPass;
+class Framebuffer;
+class CommandBuffer;
+class CommandPool;
enum class CommandType
{
FLUSH,
BIND_SAMPLERS,
BIND_VERTEX_BUFFERS,
BIND_INDEX_BUFFER,
+ BIND_UNIFORM_BUFFER,
BIND_PIPELINE,
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
+ SET_SCISSOR,
+ SET_SCISSOR_TEST,
+ SET_VIEWPORT,
+ BEGIN_RENDERPASS,
+ END_RENDERPASS,
+ EXECUTE_COMMAND_BUFFERS,
+ PRESENT_RENDER_TARGET,
+ SET_COLOR_MASK,
+ CLEAR_STENCIL_BUFFER,
+ CLEAR_DEPTH_BUFFER,
+ SET_STENCIL_TEST_ENABLE,
+ SET_STENCIL_WRITE_MASK,
+ SET_STENCIL_OP,
+ SET_STENCIL_FUNC,
+ SET_DEPTH_COMPARE_OP,
+ SET_DEPTH_TEST_ENABLE,
+ SET_DEPTH_WRITE_ENABLE,
+ DRAW_NATIVE,
};
/**
+ * @brief Helper function to invoke destructor on anonymous struct
+ */
+template<class T>
+static void InvokeDestructor(T& object)
+{
+ object.~T();
+}
+
+/**
* Command structure allocates memory to store a single command
*/
struct Command
{
}
- ~Command()
+ explicit Command(CommandType commandType)
{
+ type = commandType;
}
- /**
- * @brief Copy constructor
- * @param[in] rhs Command
- */
- Command(const Command& rhs)
- {
- switch(rhs.type)
- {
- case CommandType::BIND_VERTEX_BUFFERS:
- {
- bindVertexBuffers = rhs.bindVertexBuffers;
- break;
- }
- case CommandType::BIND_INDEX_BUFFER:
- {
- bindIndexBuffer = rhs.bindIndexBuffer;
- break;
- }
- case CommandType::BIND_SAMPLERS:
- {
- bindSamplers = rhs.bindSamplers;
- break;
- }
- case CommandType::BIND_TEXTURES:
- {
- bindTextures = rhs.bindTextures;
- break;
- }
- case CommandType::BIND_PIPELINE:
- {
- bindPipeline = rhs.bindPipeline;
- break;
- }
- case CommandType::DRAW:
- {
- draw.type = rhs.draw.type;
- draw.draw = rhs.draw.draw;
- break;
- }
- case CommandType::DRAW_INDEXED:
- {
- draw.type = rhs.draw.type;
- draw.drawIndexed = rhs.draw.drawIndexed;
- break;
- }
- case CommandType::DRAW_INDEXED_INDIRECT:
- {
- draw.type = rhs.draw.type;
- draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
- break;
- }
- case CommandType::FLUSH:
- {
- // Nothing to do
- break;
- }
- }
- type = rhs.type;
- }
+ ~Command() = default;
/**
* @brief Copy constructor
* @param[in] rhs Command
*/
- Command(Command&& rhs) noexcept
- {
- switch(rhs.type)
- {
- case CommandType::BIND_VERTEX_BUFFERS:
- {
- bindVertexBuffers = std::move(rhs.bindVertexBuffers);
- break;
- }
- case CommandType::BIND_INDEX_BUFFER:
- {
- bindIndexBuffer = rhs.bindIndexBuffer;
- break;
- }
- case CommandType::BIND_SAMPLERS:
- {
- bindSamplers = std::move(rhs.bindSamplers);
- break;
- }
- case CommandType::BIND_TEXTURES:
- {
- bindTextures = std::move(rhs.bindTextures);
- break;
- }
- case CommandType::BIND_PIPELINE:
- {
- bindPipeline = rhs.bindPipeline;
- break;
- }
- case CommandType::DRAW:
- {
- draw.type = rhs.draw.type;
- draw.draw = rhs.draw.draw;
- break;
- }
- case CommandType::DRAW_INDEXED:
- {
- draw.type = rhs.draw.type;
- draw.drawIndexed = rhs.draw.drawIndexed;
- break;
- }
- case CommandType::DRAW_INDEXED_INDIRECT:
- {
- draw.type = rhs.draw.type;
- draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
- break;
- }
- case CommandType::FLUSH:
- {
- // Nothing to do
- break;
- }
- }
- type = rhs.type;
- }
+ Command(const Command& rhs) = default;
+ Command& operator=(const Command& rhs) = default;
+ Command(Command&& rhs) noexcept = delete;
+ Command& operator=(Command&& rhs) = delete;
CommandType type{CommandType::FLUSH}; ///< Type of command
{
struct
{
- std::vector<Graphics::TextureBinding> textureBindings;
+ IndirectPtr<Graphics::TextureBinding> textureBindings;
+ uint32_t textureBindingsCount;
} bindTextures{};
// BindSampler command
struct
{
- std::vector<Graphics::SamplerBinding> samplerBindings;
+ IndirectPtr<Graphics::SamplerBinding> samplerBindings;
+ uint32_t samplerBindingsCount;
} bindSamplers;
struct
{
using Binding = GLES::VertexBufferBindingDescriptor;
- std::vector<Binding> vertexBufferBindings;
+ IndirectPtr<Binding> vertexBufferBindings;
+ uint32_t vertexBufferBindingsCount;
} bindVertexBuffers;
struct : public IndexBufferBindingDescriptor
struct
{
+ IndirectPtr<UniformBufferBindingDescriptor> uniformBufferBindings;
+ uint32_t uniformBufferBindingsCount;
+ UniformBufferBindingDescriptor standaloneUniformsBufferBinding{};
+ } bindUniformBuffers;
+
+ struct
+ {
const GLES::Pipeline* pipeline{nullptr};
} bindPipeline;
struct : public DrawCallDescriptor
{
} draw;
+
+ struct
+ {
+ Graphics::Rect2D region;
+ } scissor;
+
+ struct
+ {
+ bool enable;
+ } scissorTest;
+
+ struct
+ {
+ Graphics::Viewport region;
+ } viewport;
+
+ struct BeginRenderPassDescriptor
+ beginRenderPass;
+
+ struct
+ {
+ Graphics::SyncObject* syncObject;
+ } endRenderPass;
+
+ struct
+ {
+ IndirectPtr<const GLES::CommandBuffer*> buffers;
+ uint32_t buffersCount;
+ } executeCommandBuffers;
+
+ struct
+ {
+ GLES::RenderTarget* targetToPresent;
+ } presentRenderTarget;
+
+ struct
+ {
+ Graphics::CompareOp compareOp;
+ bool testEnabled;
+ bool writeEnabled;
+ } depth;
+
+ struct
+ {
+ Graphics::StencilOp failOp;
+ Graphics::StencilOp passOp;
+ Graphics::StencilOp depthFailOp;
+ } stencilOp;
+
+ struct
+ {
+ uint32_t mask;
+ } stencilWriteMask;
+
+ struct
+ {
+ uint32_t compareMask;
+ Graphics::CompareOp compareOp;
+ uint32_t reference;
+ } stencilFunc;
+
+ struct
+ {
+ bool enabled;
+ } stencilTest;
+
+ struct
+ {
+ bool enabled;
+ } colorMask;
+
+ struct
+ {
+ DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
class CommandBuffer : public CommandBufferResource
{
public:
- CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
- : CommandBufferResource(createInfo, controller)
- {
- }
+ CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
- ~CommandBuffer() override = default;
+ ~CommandBuffer() override;
- void BindVertexBuffers(uint32_t firstBinding,
- std::vector<const Graphics::Buffer*> buffers,
- std::vector<uint32_t> offsets) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
- auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
- if(bindings.size() < firstBinding + buffers.size())
- {
- bindings.resize(firstBinding + buffers.size());
- auto index = firstBinding;
- for(auto& buf : buffers)
- {
- bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
- bindings[index].offset = offsets[index - firstBinding];
- index++;
- }
- }
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindVertexBuffers
+ */
+ void BindVertexBuffers(uint32_t firstBinding,
+ const std::vector<const Graphics::Buffer*>& buffers,
+ const std::vector<uint32_t>& offsets) override;
- void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
- {
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindUniformBuffers
+ */
+ void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
- void BindPipeline(const Graphics::Pipeline& pipeline) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_PIPELINE;
- mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindPipeline
+ */
+ void BindPipeline(const Graphics::Pipeline& pipeline) override;
- void BindTextures(std::vector<TextureBinding>& textureBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_TEXTURES;
- mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindTextures
+ */
+ void BindTextures(const std::vector<TextureBinding>& textureBindings) override;
- void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindSamplers
+ */
+ void BindSamplers(const std::vector<SamplerBinding>& samplerBindings) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindPushConstants
+ */
void BindPushConstants(void* data,
uint32_t size,
- uint32_t binding) override
- {
- }
+ uint32_t binding) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BindIndexBuffer
+ */
void BindIndexBuffer(const Graphics::Buffer& buffer,
uint32_t offset,
- Format format) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
- mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
- mCommands.back().bindIndexBuffer.offset = offset;
- mCommands.back().bindIndexBuffer.format = format;
- }
+ Format format) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::BeginRenderPass
+ */
void BeginRenderPass(
- Graphics::RenderPass& renderPass,
- Graphics::RenderTarget& renderTarget,
- Extent2D renderArea,
- std::vector<ClearValue> clearValues) override
- {
- }
+ Graphics::RenderPass* renderPass,
+ Graphics::RenderTarget* renderTarget,
+ Rect2D renderArea,
+ const std::vector<ClearValue>& clearValues) override;
/**
- * @brief Ends current render pass
- *
- * This command must be issued in order to finalize the render pass.
- * It's up to the implementation whether anything has to be done but
- * the Controller may use end RP marker in order to resolve resource
- * dependencies (for example, to know when target texture is ready
- * before passing it to another render pass).
+ * @copydoc Dali::Graphics::CommandBuffer::EndRenderPass
*/
- void EndRenderPass() override
- {
- }
+ void EndRenderPass(Graphics::SyncObject* syncObject) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::ExecuteCommandBuffers
+ */
+ void ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::Draw
+ */
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
- uint32_t firstInstance) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW;
- cmd.draw.vertexCount = vertexCount;
- cmd.draw.instanceCount = instanceCount;
- cmd.draw.firstInstance = firstInstance;
- cmd.draw.firstVertex = firstVertex;
- }
+ uint32_t firstInstance) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::DrawIndexed
+ */
void DrawIndexed(
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
- uint32_t firstInstance) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW_INDEXED;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
- cmd.drawIndexed.firstIndex = firstIndex;
- cmd.drawIndexed.firstInstance = firstInstance;
- cmd.drawIndexed.indexCount = indexCount;
- cmd.drawIndexed.vertexOffset = vertexOffset;
- cmd.drawIndexed.instanceCount = instanceCount;
- }
+ uint32_t firstInstance) override;
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::DrawIndexedIndirect
+ */
void DrawIndexedIndirect(
Graphics::Buffer& buffer,
uint32_t offset,
uint32_t drawCount,
- uint32_t stride) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::DRAW_INDEXED_INDIRECT;
- auto& cmd = mCommands.back().draw;
- cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
- cmd.drawIndexedIndirect.buffer = static_cast<const GLES::Buffer*>(&buffer);
- cmd.drawIndexedIndirect.offset = offset;
- cmd.drawIndexedIndirect.drawCount = drawCount;
- cmd.drawIndexedIndirect.stride = stride;
- }
+ uint32_t stride) override;
- void Reset(Graphics::CommandBuffer& commandBuffer) override
- {
- mCommands.clear();
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::DrawNative
+ */
+ void DrawNative(const DrawNativeInfo* drawNativeInfo) override;
- void SetScissor(Extent2D value) override
- {
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::Reset
+ */
+ void Reset() override;
- void SetScissorTestEnable(bool value) override
- {
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetScissor
+ */
+ void SetScissor(Graphics::Rect2D value) override;
- void SetViewport(Viewport value) override
- {
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetScissorTestEnable
+ */
+ void SetScissorTestEnable(bool value) override;
- void SetViewportEnable(bool value) override
- {
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetViewport
+ */
+ void SetViewport(Viewport value) override;
- [[nodiscard]] const std::vector<Command>& GetCommands() const
- {
- return mCommands;
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetViewportEnable
+ */
+ void SetViewportEnable(bool value) override;
- void DestroyResource() override
- {
- // Nothing to do
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetColorMask
+ */
+ void SetColorMask(bool enabled) override;
- bool InitializeResource() override
- {
- // Nothing to do
- return true;
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::ClearStencilBuffer
+ */
+ void ClearStencilBuffer() override;
- void DiscardResource() override
- {
- // Nothing to do
- }
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetStencilTestEnable
+ */
+ void SetStencilTestEnable(bool stencilEnable) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetStencilWriteMask
+ */
+ void SetStencilWriteMask(uint32_t writeMask) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetStencilOp
+ */
+ void SetStencilOp(Graphics::StencilOp failOp,
+ Graphics::StencilOp passOp,
+ Graphics::StencilOp depthFailOp) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetStencilFunc
+ */
+ void SetStencilFunc(Graphics::CompareOp compareOp,
+ uint32_t reference,
+ uint32_t compareMask) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetDepthCompareOp
+ */
+ void SetDepthCompareOp(Graphics::CompareOp compareOp) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetDepthTestEnable
+ */
+ void SetDepthTestEnable(bool depthTestEnable) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::SetDepthWriteEnable
+ */
+ void SetDepthWriteEnable(bool depthWriteEnable) override;
+
+ /**
+ * @copydoc Dali::Graphics::CommandBuffer::ClearDepthBuffer
+ */
+ void ClearDepthBuffer() override;
+
+ /**
+ * @brief Presents specified render target
+ *
+ * @param[in] renderTarget Valid pointer to a RenderTarget
+ *
+ * It's internal command that schedules presentation of
+ * specified render target.
+ */
+ void PresentRenderTarget(GLES::RenderTarget* renderTarget);
+
+ /**
+ * @brief Returns pointer to the list of command and size of the list
+ *
+ * @param[out] size Size of the list
+ * @return Valid pointer to the list of commands
+ */
+ [[nodiscard]] const Command* GetCommands(uint32_t& size) const;
+
+ /**
+ * @brief Destroy the associated resources
+ */
+ void DestroyResource() override;
+
+ /**
+ * @brief Initialize associated resources
+ */
+ bool InitializeResource() override;
+
+ /**
+ * @brief Add this resource to the discard queue
+ */
+ void DiscardResource() override;
+
+ // Get the total memory usage of this command buffer
+ std::size_t GetCapacity();
private:
- std::vector<Command> mCommands;
+ std::unique_ptr<CommandPool> mCommandPool; ///< Pool of commands and transient memory
};
} // namespace Dali::Graphics::GLES
-#endif
\ No newline at end of file
+#endif