1 #ifndef DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
2 #define DALI_TEST_GRAPHICS_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.
20 #include <dali/graphics-api/graphics-command-buffer-create-info.h>
21 #include <dali/graphics-api/graphics-command-buffer.h>
22 #include <dali/graphics-api/graphics-pipeline.h>
23 #include <dali/graphics-api/graphics-types.h>
26 #include "test-gl-abstraction.h"
27 #include "test-graphics-buffer.h"
28 #include "test-graphics-pipeline.h"
29 #include "test-trace-call-stack.h"
33 class TestGraphicsTexture;
34 class TestGraphicsBuffer;
35 class TestGraphicsSampler;
36 class TestGraphicsPipeline;
38 enum class CommandType
41 BIND_TEXTURES = 1 << 1,
42 BIND_SAMPLERS = 1 << 2,
43 BIND_VERTEX_BUFFERS = 1 << 3,
44 BIND_INDEX_BUFFER = 1 << 4,
45 BIND_UNIFORM_BUFFER = 1 << 5,
46 BIND_PIPELINE = 1 << 6,
48 DRAW_INDEXED = 1 << 8,
49 DRAW_INDEXED_INDIRECT = 1 << 9,
50 SET_SCISSOR = 1 << 10,
51 SET_SCISSOR_TEST = 1 << 11,
52 SET_VIEWPORT = 1 << 12,
53 SET_VIEWPORT_TEST = 1 << 13
56 using CommandTypeMask = uint32_t;
58 inline CommandTypeMask operator|(T flags, CommandType bit)
60 return static_cast<CommandTypeMask>(flags) | static_cast<CommandTypeMask>(bit);
64 * @brief Descriptor of single buffer binding within
67 struct VertexBufferBindingDescriptor
69 const TestGraphicsBuffer* buffer{nullptr};
74 * @brief Descriptor of ix buffer binding within
77 struct IndexBufferBindingDescriptor
79 const TestGraphicsBuffer* buffer{nullptr};
81 Graphics::Format format{};
85 * @brief Descriptor of uniform buffer binding within
88 struct UniformBufferBindingDescriptor
90 const TestGraphicsBuffer* buffer{nullptr};
93 bool emulated; ///<true if UBO is emulated for old gfx API
97 * @brief The descriptor of draw call
99 struct DrawCallDescriptor
102 * @brief Enum specifying type of the draw call
108 DRAW_INDEXED_INDIRECT
111 Type type{}; ///< Type of the draw call
114 * Union contains data for all types of draw calls.
119 * @brief Vertex array draw
123 uint32_t vertexCount;
124 uint32_t instanceCount;
125 uint32_t firstVertex;
126 uint32_t firstInstance;
130 * @brief Indexed draw
135 uint32_t instanceCount;
137 int32_t vertexOffset;
138 uint32_t firstInstance;
142 * @brief Indexed draw indirect
146 const TestGraphicsBuffer* buffer;
150 } drawIndexedIndirect;
155 * Command structure allocates memory to store a single command
168 * @brief Copy constructor
169 * @param[in] rhs Command
171 Command(const Command& rhs)
175 case CommandType::BIND_VERTEX_BUFFERS:
177 data.bindVertexBuffers = rhs.data.bindVertexBuffers;
180 case CommandType::BIND_INDEX_BUFFER:
182 data.bindIndexBuffer = rhs.data.bindIndexBuffer;
185 case CommandType::BIND_SAMPLERS:
187 data.bindSamplers = rhs.data.bindSamplers;
190 case CommandType::BIND_TEXTURES:
192 data.bindTextures = rhs.data.bindTextures;
195 case CommandType::BIND_PIPELINE:
197 data.bindPipeline = rhs.data.bindPipeline;
200 case CommandType::BIND_UNIFORM_BUFFER:
202 data.bindUniformBuffers = rhs.data.bindUniformBuffers;
205 case CommandType::DRAW:
207 data.draw.type = rhs.data.draw.type;
208 data.draw.draw = rhs.data.draw.draw;
211 case CommandType::DRAW_INDEXED:
213 data.draw.type = rhs.data.draw.type;
214 data.draw.drawIndexed = rhs.data.draw.drawIndexed;
217 case CommandType::DRAW_INDEXED_INDIRECT:
219 data.draw.type = rhs.data.draw.type;
220 data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
223 case CommandType::FLUSH:
228 case CommandType::SET_SCISSOR:
230 data.scissor.region = rhs.data.scissor.region;
233 case CommandType::SET_SCISSOR_TEST:
235 data.scissorTest.enable = rhs.data.scissorTest.enable;
238 case CommandType::SET_VIEWPORT:
240 data.viewport.region = rhs.data.viewport.region;
243 case CommandType::SET_VIEWPORT_TEST:
245 data.viewportTest.enable = rhs.data.viewportTest.enable;
253 * @brief move constructor
254 * @param[in] rhs Command
256 Command(Command&& rhs) noexcept
260 case CommandType::BIND_VERTEX_BUFFERS:
262 data.bindVertexBuffers = std::move(rhs.data.bindVertexBuffers);
265 case CommandType::BIND_INDEX_BUFFER:
267 data.bindIndexBuffer = rhs.data.bindIndexBuffer;
270 case CommandType::BIND_UNIFORM_BUFFER:
272 data.bindUniformBuffers = std::move(rhs.data.bindUniformBuffers);
275 case CommandType::BIND_SAMPLERS:
277 data.bindSamplers = std::move(rhs.data.bindSamplers);
280 case CommandType::BIND_TEXTURES:
282 data.bindTextures = std::move(rhs.data.bindTextures);
285 case CommandType::BIND_PIPELINE:
287 data.bindPipeline = rhs.data.bindPipeline;
290 case CommandType::DRAW:
292 data.draw.type = rhs.data.draw.type;
293 data.draw.draw = rhs.data.draw.draw;
296 case CommandType::DRAW_INDEXED:
298 data.draw.type = rhs.data.draw.type;
299 data.draw.drawIndexed = rhs.data.draw.drawIndexed;
302 case CommandType::DRAW_INDEXED_INDIRECT:
304 data.draw.type = rhs.data.draw.type;
305 data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
308 case CommandType::FLUSH:
313 case CommandType::SET_SCISSOR:
315 data.scissor.region = rhs.data.scissor.region;
318 case CommandType::SET_SCISSOR_TEST:
320 data.scissorTest.enable = rhs.data.scissorTest.enable;
323 case CommandType::SET_VIEWPORT:
325 data.viewport.region = rhs.data.viewport.region;
328 case CommandType::SET_VIEWPORT_TEST:
330 data.viewportTest.enable = rhs.data.viewportTest.enable;
337 CommandType type{CommandType::FLUSH}; ///< Type of command
351 std::vector<Graphics::TextureBinding> textureBindings;
354 // BindSampler command
357 std::vector<Graphics::SamplerBinding> samplerBindings;
362 using Binding = VertexBufferBindingDescriptor;
363 std::vector<Binding> vertexBufferBindings;
366 struct : public IndexBufferBindingDescriptor
372 std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
373 UniformBufferBindingDescriptor standaloneUniformsBufferBinding{};
374 } bindUniformBuffers;
378 const TestGraphicsPipeline* pipeline{nullptr};
381 struct : public DrawCallDescriptor
387 Graphics::Rect2D region;
395 Graphics::Viewport region;
404 class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
407 TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
408 ~TestGraphicsCommandBuffer()
412 void BindVertexBuffers(uint32_t firstBinding,
413 std::vector<const Graphics::Buffer*> buffers,
414 std::vector<uint32_t> offsets) override
416 mCommands.emplace_back();
417 mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
418 auto& bindings = mCommands.back().data.bindVertexBuffers.vertexBufferBindings;
419 if(bindings.size() < firstBinding + buffers.size())
421 bindings.resize(firstBinding + buffers.size());
422 auto index = firstBinding;
423 for(auto& buf : buffers)
425 bindings[index].buffer = static_cast<const TestGraphicsBuffer*>(buf);
426 bindings[index].offset = offsets[index - firstBinding];
430 mCallStack.PushCall("BindVertexBuffers", "");
433 void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
435 mCommands.emplace_back();
436 auto& cmd = mCommands.back();
437 cmd.type = CommandType::BIND_UNIFORM_BUFFER;
438 auto& bindCmd = cmd.data.bindUniformBuffers;
439 for(const auto& binding : bindings)
443 auto testBuffer = static_cast<const TestGraphicsBuffer*>(binding.buffer);
444 if(testBuffer->IsCPUAllocated()) // standalone uniforms
446 bindCmd.standaloneUniformsBufferBinding.buffer = testBuffer;
447 bindCmd.standaloneUniformsBufferBinding.offset = binding.offset;
448 bindCmd.standaloneUniformsBufferBinding.binding = binding.binding;
449 bindCmd.standaloneUniformsBufferBinding.emulated = true;
451 else // Bind regular UBO
453 // resize binding slots
454 if(binding.binding >= bindCmd.uniformBufferBindings.size())
456 bindCmd.uniformBufferBindings.resize(binding.binding + 1);
458 auto& slot = bindCmd.uniformBufferBindings[binding.binding];
459 slot.buffer = testBuffer;
460 slot.offset = binding.offset;
461 slot.binding = binding.binding;
462 slot.emulated = false;
466 mCallStack.PushCall("BindUniformBuffers", "");
469 void BindPipeline(const Graphics::Pipeline& pipeline) override
471 mCommands.emplace_back();
472 mCommands.back().type = CommandType::BIND_PIPELINE;
473 mCommands.back().data.bindPipeline.pipeline = static_cast<const TestGraphicsPipeline*>(&pipeline);
474 mCallStack.PushCall("BindPipeline", "");
477 void BindTextures(std::vector<Graphics::TextureBinding>& textureBindings) override
479 mCommands.emplace_back();
480 mCommands.back().type = CommandType::BIND_TEXTURES;
481 mCommands.back().data.bindTextures.textureBindings = std::move(textureBindings);
482 mCallStack.PushCall("BindTextures", "");
485 void BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings) override
487 mCommands.emplace_back();
488 mCommands.back().data.bindSamplers.samplerBindings = std::move(samplerBindings);
489 mCallStack.PushCall("BindSamplers", "");
492 void BindPushConstants(void* data,
494 uint32_t binding) override
496 mCallStack.PushCall("BindPushConstants", "");
499 void BindIndexBuffer(const Graphics::Buffer& buffer,
501 Graphics::Format format) override
503 mCommands.emplace_back();
504 mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
505 mCommands.back().data.bindIndexBuffer.buffer = static_cast<const TestGraphicsBuffer*>(&buffer);
506 mCommands.back().data.bindIndexBuffer.offset = offset;
507 mCommands.back().data.bindIndexBuffer.format = format;
508 mCallStack.PushCall("BindIndexBuffer", "");
511 void BeginRenderPass(
512 Graphics::RenderPass& renderPass,
513 Graphics::RenderTarget& renderTarget,
514 Graphics::Extent2D renderArea,
515 std::vector<Graphics::ClearValue> clearValues) override
517 mCallStack.PushCall("BeginRenderPass", "");
521 * @brief Ends current render pass
523 * This command must be issued in order to finalize the render pass.
524 * It's up to the implementation whether anything has to be done but
525 * the Controller may use end RP marker in order to resolve resource
526 * dependencies (for example, to know when target texture is ready
527 * before passing it to another render pass).
529 void EndRenderPass() override
531 mCallStack.PushCall("EndRenderPass", "");
535 uint32_t vertexCount,
536 uint32_t instanceCount,
537 uint32_t firstVertex,
538 uint32_t firstInstance) override
540 mCommands.emplace_back();
541 mCommands.back().type = CommandType::DRAW;
542 auto& cmd = mCommands.back().data.draw;
543 cmd.type = DrawCallDescriptor::Type::DRAW;
544 cmd.draw.vertexCount = vertexCount;
545 cmd.draw.instanceCount = instanceCount;
546 cmd.draw.firstInstance = firstInstance;
547 cmd.draw.firstVertex = firstVertex;
548 mCallStack.PushCall("Draw", "");
553 uint32_t instanceCount,
555 int32_t vertexOffset,
556 uint32_t firstInstance) override
558 mCommands.emplace_back();
559 mCommands.back().type = CommandType::DRAW_INDEXED;
560 auto& cmd = mCommands.back().data.draw;
561 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
562 cmd.drawIndexed.firstIndex = firstIndex;
563 cmd.drawIndexed.firstInstance = firstInstance;
564 cmd.drawIndexed.indexCount = indexCount;
565 cmd.drawIndexed.vertexOffset = vertexOffset;
566 cmd.drawIndexed.instanceCount = instanceCount;
567 mCallStack.PushCall("DrawIndexed", "");
570 void DrawIndexedIndirect(
571 Graphics::Buffer& buffer,
574 uint32_t stride) override
576 mCommands.emplace_back();
577 mCommands.back().type = CommandType::DRAW_INDEXED_INDIRECT;
578 auto& cmd = mCommands.back().data.draw;
579 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
580 cmd.drawIndexedIndirect.buffer = static_cast<const TestGraphicsBuffer*>(&buffer);
581 cmd.drawIndexedIndirect.offset = offset;
582 cmd.drawIndexedIndirect.drawCount = drawCount;
583 cmd.drawIndexedIndirect.stride = stride;
584 mCallStack.PushCall("DrawIndexedIndirect", "");
587 void Reset() override
590 mCallStack.PushCall("Reset", "");
593 void SetScissor(Graphics::Rect2D value) override
595 TraceCallStack::NamedParams params;
596 params["x"] << value.x;
597 params["y"] << value.y;
598 params["width"] << value.width;
599 params["height"] << value.height;
600 mCallStack.PushCall("SetScissor", params.str(), params);
602 mCommands.emplace_back();
603 mCommands.back().type = CommandType::SET_SCISSOR;
604 mCommands.back().data.scissor.region = value;
607 void SetScissorTestEnable(bool value) override
609 TraceCallStack::NamedParams params;
610 params["value"] << (value ? "T" : "F");
611 mCallStack.PushCall("SetScissorTestEnable", params.str(), params);
613 mCommands.emplace_back();
614 mCommands.back().type = CommandType::SET_SCISSOR_TEST;
615 mCommands.back().data.scissorTest.enable = value;
618 void SetViewport(Graphics::Viewport value) override
620 TraceCallStack::NamedParams params;
621 params["x"] << value.x;
622 params["y"] << value.y;
623 params["width"] << value.width;
624 params["height"] << value.height;
625 params["minDepth"] << value.minDepth;
626 params["maxDepth"] << value.maxDepth;
627 mCallStack.PushCall("SetViewport", params.str(), params);
629 mCommands.emplace_back();
630 mCommands.back().type = CommandType::SET_VIEWPORT;
631 mCommands.back().data.viewport.region = value;
634 void SetViewportEnable(bool value) override
636 TraceCallStack::NamedParams params;
637 params["value"] << (value ? "T" : "F");
638 mCallStack.PushCall("SetViewportEnable", params.str(), params);
640 mCommands.emplace_back();
641 mCommands.back().type = CommandType::SET_VIEWPORT_TEST;
642 mCommands.back().data.viewportTest.enable = value;
645 [[nodiscard]] const std::vector<Command>& GetCommands() const
651 * Returns number of draw commands
654 int GetDrawCallsCount();
657 * Retrieves state resolve for selected draw call
658 * @param drawCommandIndex
660 void GetStateForDrawCall(int drawCallIndex);
663 * Retrieves commands of specified type
665 std::vector<Command*> GetCommandsByType(CommandTypeMask mask);
668 TraceCallStack& mCallStack;
669 TestGlAbstraction& mGlAbstraction;
671 std::vector<Command> mCommands;
676 #endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H