1 #ifndef DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
2 #define DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/graphics-api/graphics-command-buffer.h>
25 #include "egl-graphics-controller.h"
26 #include "gles-graphics-buffer.h"
27 #include "gles-graphics-pipeline.h"
28 #include "gles-graphics-types.h"
30 namespace Dali::Graphics::GLES
35 enum class CommandType
50 * Command structure allocates memory to store a single command
63 * @brief Copy constructor
64 * @param[in] rhs Command
66 Command(const Command& rhs)
70 case CommandType::BIND_VERTEX_BUFFERS:
72 bindVertexBuffers = rhs.bindVertexBuffers;
75 case CommandType::BIND_INDEX_BUFFER:
77 bindIndexBuffer = rhs.bindIndexBuffer;
80 case CommandType::BIND_SAMPLERS:
82 bindSamplers = rhs.bindSamplers;
85 case CommandType::BIND_TEXTURES:
87 bindTextures = rhs.bindTextures;
90 case CommandType::BIND_PIPELINE:
92 bindPipeline = rhs.bindPipeline;
95 case CommandType::BIND_UNIFORM_BUFFER:
97 bindUniformBuffers = rhs.bindUniformBuffers;
100 case CommandType::DRAW:
102 draw.type = rhs.draw.type;
103 draw.draw = rhs.draw.draw;
106 case CommandType::DRAW_INDEXED:
108 draw.type = rhs.draw.type;
109 draw.drawIndexed = rhs.draw.drawIndexed;
112 case CommandType::DRAW_INDEXED_INDIRECT:
114 draw.type = rhs.draw.type;
115 draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
118 case CommandType::FLUSH:
128 * @brief Copy constructor
129 * @param[in] rhs Command
131 Command(Command&& rhs) noexcept
135 case CommandType::BIND_VERTEX_BUFFERS:
137 bindVertexBuffers = std::move(rhs.bindVertexBuffers);
140 case CommandType::BIND_INDEX_BUFFER:
142 bindIndexBuffer = rhs.bindIndexBuffer;
145 case CommandType::BIND_UNIFORM_BUFFER:
147 bindUniformBuffers = std::move(rhs.bindUniformBuffers);
150 case CommandType::BIND_SAMPLERS:
152 bindSamplers = std::move(rhs.bindSamplers);
155 case CommandType::BIND_TEXTURES:
157 bindTextures = std::move(rhs.bindTextures);
160 case CommandType::BIND_PIPELINE:
162 bindPipeline = rhs.bindPipeline;
165 case CommandType::DRAW:
167 draw.type = rhs.draw.type;
168 draw.draw = rhs.draw.draw;
171 case CommandType::DRAW_INDEXED:
173 draw.type = rhs.draw.type;
174 draw.drawIndexed = rhs.draw.drawIndexed;
177 case CommandType::DRAW_INDEXED_INDIRECT:
179 draw.type = rhs.draw.type;
180 draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
183 case CommandType::FLUSH:
192 CommandType type{CommandType::FLUSH}; ///< Type of command
198 std::vector<Graphics::TextureBinding> textureBindings;
201 // BindSampler command
204 std::vector<Graphics::SamplerBinding> samplerBindings;
209 using Binding = GLES::VertexBufferBindingDescriptor;
210 std::vector<Binding> vertexBufferBindings;
213 struct : public IndexBufferBindingDescriptor
219 std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
220 UniformBufferBindingDescriptor standaloneUniformsBufferBinding{};
221 } bindUniformBuffers;
225 const GLES::Pipeline* pipeline{nullptr};
228 struct : public DrawCallDescriptor
234 using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::CommandBufferCreateInfo>;
236 class CommandBuffer : public CommandBufferResource
239 CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
240 : CommandBufferResource(createInfo, controller)
244 ~CommandBuffer() override = default;
246 void BindVertexBuffers(uint32_t firstBinding,
247 std::vector<const Graphics::Buffer*> buffers,
248 std::vector<uint32_t> offsets) override
250 mCommands.emplace_back();
251 mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
252 auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
253 if(bindings.size() < firstBinding + buffers.size())
255 bindings.resize(firstBinding + buffers.size());
256 auto index = firstBinding;
257 for(auto& buf : buffers)
259 bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
260 bindings[index].offset = offsets[index - firstBinding];
266 void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
268 mCommands.emplace_back();
269 auto& cmd = mCommands.back();
270 cmd.type = CommandType::BIND_UNIFORM_BUFFER;
271 auto& bindCmd = cmd.bindUniformBuffers;
272 for(const auto& binding : bindings)
276 auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
277 if(glesBuffer->IsCPUAllocated()) // standalone uniforms
279 bindCmd.standaloneUniformsBufferBinding.buffer = glesBuffer;
280 bindCmd.standaloneUniformsBufferBinding.offset = binding.offset;
281 bindCmd.standaloneUniformsBufferBinding.binding = binding.binding;
282 bindCmd.standaloneUniformsBufferBinding.emulated = true;
284 else // Bind regular UBO
286 // resize binding slots
287 if(binding.binding >= bindCmd.uniformBufferBindings.size())
289 bindCmd.uniformBufferBindings.resize(binding.binding + 1);
291 auto& slot = bindCmd.uniformBufferBindings[binding.binding];
292 slot.buffer = glesBuffer;
293 slot.offset = binding.offset;
294 slot.binding = binding.binding;
295 slot.emulated = false;
301 void BindPipeline(const Graphics::Pipeline& pipeline) override
303 mCommands.emplace_back();
304 mCommands.back().type = CommandType::BIND_PIPELINE;
305 mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
308 void BindTextures(std::vector<TextureBinding>& textureBindings) override
310 mCommands.emplace_back();
311 mCommands.back().type = CommandType::BIND_TEXTURES;
312 mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
315 void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override
317 mCommands.emplace_back();
318 mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
321 void BindPushConstants(void* data,
323 uint32_t binding) override
327 void BindIndexBuffer(const Graphics::Buffer& buffer,
329 Format format) override
331 mCommands.emplace_back();
332 mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
333 mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
334 mCommands.back().bindIndexBuffer.offset = offset;
335 mCommands.back().bindIndexBuffer.format = format;
338 void BeginRenderPass(
339 Graphics::RenderPass& renderPass,
340 Graphics::RenderTarget& renderTarget,
342 std::vector<ClearValue> clearValues) override
347 * @brief Ends current render pass
349 * This command must be issued in order to finalize the render pass.
350 * It's up to the implementation whether anything has to be done but
351 * the Controller may use end RP marker in order to resolve resource
352 * dependencies (for example, to know when target texture is ready
353 * before passing it to another render pass).
355 void EndRenderPass() override
360 uint32_t vertexCount,
361 uint32_t instanceCount,
362 uint32_t firstVertex,
363 uint32_t firstInstance) override
365 mCommands.emplace_back();
366 mCommands.back().type = CommandType::DRAW;
367 auto& cmd = mCommands.back().draw;
368 cmd.type = DrawCallDescriptor::Type::DRAW;
369 cmd.draw.vertexCount = vertexCount;
370 cmd.draw.instanceCount = instanceCount;
371 cmd.draw.firstInstance = firstInstance;
372 cmd.draw.firstVertex = firstVertex;
377 uint32_t instanceCount,
379 int32_t vertexOffset,
380 uint32_t firstInstance) override
382 mCommands.emplace_back();
383 mCommands.back().type = CommandType::DRAW_INDEXED;
384 auto& cmd = mCommands.back().draw;
385 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
386 cmd.drawIndexed.firstIndex = firstIndex;
387 cmd.drawIndexed.firstInstance = firstInstance;
388 cmd.drawIndexed.indexCount = indexCount;
389 cmd.drawIndexed.vertexOffset = vertexOffset;
390 cmd.drawIndexed.instanceCount = instanceCount;
393 void DrawIndexedIndirect(
394 Graphics::Buffer& buffer,
397 uint32_t stride) override
399 mCommands.emplace_back();
400 mCommands.back().type = CommandType::DRAW_INDEXED_INDIRECT;
401 auto& cmd = mCommands.back().draw;
402 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
403 cmd.drawIndexedIndirect.buffer = static_cast<const GLES::Buffer*>(&buffer);
404 cmd.drawIndexedIndirect.offset = offset;
405 cmd.drawIndexedIndirect.drawCount = drawCount;
406 cmd.drawIndexedIndirect.stride = stride;
409 void Reset() override
414 void SetScissor(Extent2D value) override
418 void SetScissorTestEnable(bool value) override
422 void SetViewport(Viewport value) override
426 void SetViewportEnable(bool value) override
430 [[nodiscard]] const std::vector<Command>& GetCommands() const
435 void DestroyResource() override
440 bool InitializeResource() override
446 void DiscardResource() override
452 std::vector<Command> mCommands;
454 } // namespace Dali::Graphics::GLES