Syncing test harness
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-command-buffer.h
1 #ifndef DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
2 #define DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
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>
24 #include <cstdint>
25 #include <vector>
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"
30
31 namespace Dali
32 {
33 class TestGraphicsTexture;
34 class TestGraphicsBuffer;
35 class TestGraphicsCommandBuffer;
36 class TestGraphicsSampler;
37 class TestGraphicsPipeline;
38
39 enum class CommandType
40 {
41   FLUSH                   = 1 << 0,
42   BIND_TEXTURES           = 1 << 1,
43   BIND_SAMPLERS           = 1 << 2,
44   BIND_VERTEX_BUFFERS     = 1 << 3,
45   BIND_INDEX_BUFFER       = 1 << 4,
46   BIND_UNIFORM_BUFFER     = 1 << 5,
47   BIND_PIPELINE           = 1 << 6,
48   DRAW                    = 1 << 7,
49   DRAW_INDEXED            = 1 << 8,
50   DRAW_INDEXED_INDIRECT   = 1 << 9,
51   SET_SCISSOR             = 1 << 10,
52   SET_SCISSOR_TEST        = 1 << 11,
53   SET_VIEWPORT            = 1 << 12,
54   SET_VIEWPORT_TEST       = 1 << 13,
55   BEGIN_RENDER_PASS       = 1 << 14,
56   END_RENDER_PASS         = 1 << 15,
57   EXECUTE_COMMAND_BUFFERS = 1 << 16,
58   SET_COLOR_MASK          = 1 << 17,
59   CLEAR_STENCIL_BUFFER    = 1 << 18,
60   CLEAR_DEPTH_BUFFER      = 1 << 19,
61   SET_STENCIL_TEST_ENABLE = 1 << 20,
62   SET_STENCIL_WRITE_MASK  = 1 << 21,
63   SET_STENCIL_OP          = 1 << 22,
64   SET_STENCIL_FUNC        = 1 << 23,
65   SET_DEPTH_COMPARE_OP    = 1 << 24,
66   SET_DEPTH_TEST_ENABLE   = 1 << 25,
67   SET_DEPTH_WRITE_ENABLE  = 1 << 26,
68 };
69
70 std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
71
72 std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op);
73
74 using CommandTypeMask = uint32_t;
75 template<typename T>
76 inline CommandTypeMask operator|(T flags, CommandType bit)
77 {
78   return static_cast<CommandTypeMask>(flags) | static_cast<CommandTypeMask>(bit);
79 }
80
81 /**
82  * @brief Descriptor of single buffer binding within
83  * command buffer.
84  */
85 struct VertexBufferBindingDescriptor
86 {
87   const TestGraphicsBuffer* buffer{nullptr};
88   uint32_t                  offset{0u};
89 };
90
91 /**
92  * @brief Descriptor of ix buffer binding within
93  * command buffer.
94  */
95 struct IndexBufferBindingDescriptor
96 {
97   const TestGraphicsBuffer* buffer{nullptr};
98   uint32_t                  offset{};
99   Graphics::Format          format{};
100 };
101
102 /**
103  * @brief Descriptor of uniform buffer binding within
104  * command buffer.
105  */
106 struct UniformBufferBindingDescriptor
107 {
108   const TestGraphicsBuffer* buffer{nullptr};
109   uint32_t                  binding{0u};
110   uint32_t                  offset{0u};
111   bool                      emulated; ///<true if UBO is emulated for old gfx API
112 };
113
114 /**
115  * @brief The descriptor of draw call
116  */
117 struct DrawCallDescriptor
118 {
119   /**
120    * @brief Enum specifying type of the draw call
121    */
122   enum class Type
123   {
124     DRAW,
125     DRAW_INDEXED,
126     DRAW_INDEXED_INDIRECT
127   };
128
129   Type type{}; ///< Type of the draw call
130
131   /**
132    * Union contains data for all types of draw calls.
133    */
134   union
135   {
136     /**
137      * @brief Vertex array draw
138      */
139     struct
140     {
141       uint32_t vertexCount;
142       uint32_t instanceCount;
143       uint32_t firstVertex;
144       uint32_t firstInstance;
145     } draw;
146
147     /**
148      * @brief Indexed draw
149      */
150     struct
151     {
152       uint32_t indexCount;
153       uint32_t instanceCount;
154       uint32_t firstIndex;
155       int32_t  vertexOffset;
156       uint32_t firstInstance;
157     } drawIndexed;
158
159     /**
160      * @brief Indexed draw indirect
161      */
162     struct
163     {
164       const TestGraphicsBuffer* buffer;
165       uint32_t                  offset;
166       uint32_t                  drawCount;
167       uint32_t                  stride;
168     } drawIndexedIndirect;
169   };
170 };
171
172 /**
173  * Command structure allocates memory to store a single command
174  */
175 struct Command
176 {
177   Command()
178   {
179   }
180
181   Command(CommandType type)
182   : type(type)
183   {
184     // do non-trivial initialization
185     switch(type)
186     {
187       case CommandType::BEGIN_RENDER_PASS:
188       {
189         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor();
190         break;
191       }
192       default:
193       {
194       }
195     }
196   }
197
198   ~Command()
199   {
200     switch(type)
201     {
202       case CommandType::BEGIN_RENDER_PASS:
203       {
204         data.beginRenderPass.~BeginRenderPassDescriptor();
205         break;
206       }
207       default:
208       {
209         break;
210       }
211     }
212   }
213
214   /**
215    * @brief Copy constructor
216    * @param[in] rhs Command
217    */
218   Command(const Command& rhs)
219   {
220     switch(rhs.type)
221     {
222       case CommandType::BEGIN_RENDER_PASS:
223       {
224         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(rhs.data.beginRenderPass);
225         break;
226       }
227       case CommandType::END_RENDER_PASS:
228       {
229         data.endRenderPass = rhs.data.endRenderPass;
230         break;
231       }
232       case CommandType::EXECUTE_COMMAND_BUFFERS:
233       {
234         data.executeCommandBuffers = rhs.data.executeCommandBuffers;
235         break;
236       }
237
238       case CommandType::BIND_VERTEX_BUFFERS:
239       {
240         data.bindVertexBuffers = rhs.data.bindVertexBuffers;
241         break;
242       }
243       case CommandType::BIND_INDEX_BUFFER:
244       {
245         data.bindIndexBuffer = rhs.data.bindIndexBuffer;
246         break;
247       }
248       case CommandType::BIND_SAMPLERS:
249       {
250         data.bindSamplers = rhs.data.bindSamplers;
251         break;
252       }
253       case CommandType::BIND_TEXTURES:
254       {
255         data.bindTextures = rhs.data.bindTextures;
256         break;
257       }
258       case CommandType::BIND_PIPELINE:
259       {
260         data.bindPipeline = rhs.data.bindPipeline;
261         break;
262       }
263       case CommandType::BIND_UNIFORM_BUFFER:
264       {
265         data.bindUniformBuffers = rhs.data.bindUniformBuffers;
266         break;
267       }
268       case CommandType::DRAW:
269       {
270         data.draw.type = rhs.data.draw.type;
271         data.draw.draw = rhs.data.draw.draw;
272         break;
273       }
274       case CommandType::DRAW_INDEXED:
275       {
276         data.draw.type        = rhs.data.draw.type;
277         data.draw.drawIndexed = rhs.data.draw.drawIndexed;
278         break;
279       }
280       case CommandType::DRAW_INDEXED_INDIRECT:
281       {
282         data.draw.type                = rhs.data.draw.type;
283         data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
284         break;
285       }
286       case CommandType::FLUSH:
287       {
288         // Nothing to do
289         break;
290       }
291       case CommandType::SET_SCISSOR:
292       {
293         data.scissor.region = rhs.data.scissor.region;
294         break;
295       }
296       case CommandType::SET_SCISSOR_TEST:
297       {
298         data.scissorTest.enable = rhs.data.scissorTest.enable;
299         break;
300       }
301       case CommandType::SET_VIEWPORT:
302       {
303         data.viewport.region = rhs.data.viewport.region;
304         break;
305       }
306       case CommandType::SET_VIEWPORT_TEST:
307       {
308         data.viewportTest.enable = rhs.data.viewportTest.enable;
309         break;
310       }
311       case CommandType::SET_COLOR_MASK:
312       {
313         data.colorMask.enabled = rhs.data.colorMask.enabled;
314         break;
315       }
316       case CommandType::CLEAR_STENCIL_BUFFER:
317       {
318         break;
319       }
320       case CommandType::CLEAR_DEPTH_BUFFER:
321       {
322         break;
323       }
324       case CommandType::SET_STENCIL_TEST_ENABLE:
325       {
326         data.stencilTest.enabled = rhs.data.stencilTest.enabled;
327         break;
328       }
329       case CommandType::SET_STENCIL_FUNC:
330       {
331         data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
332         data.stencilFunc.compareOp   = rhs.data.stencilFunc.compareOp;
333         data.stencilFunc.reference   = rhs.data.stencilFunc.reference;
334         break;
335       }
336       case CommandType::SET_STENCIL_WRITE_MASK:
337       {
338         data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
339         break;
340       }
341       case CommandType::SET_STENCIL_OP:
342       {
343         data.stencilOp.failOp      = rhs.data.stencilOp.failOp;
344         data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
345         data.stencilOp.passOp      = rhs.data.stencilOp.passOp;
346         break;
347       }
348
349       case CommandType::SET_DEPTH_COMPARE_OP:
350       {
351         data.depth.compareOp = rhs.data.depth.compareOp;
352         break;
353       }
354       case CommandType::SET_DEPTH_TEST_ENABLE:
355       {
356         data.depth.testEnabled = rhs.data.depth.testEnabled;
357         break;
358       }
359       case CommandType::SET_DEPTH_WRITE_ENABLE:
360       {
361         data.depth.writeEnabled = rhs.data.depth.writeEnabled;
362         break;
363       }
364     }
365     type = rhs.type;
366   }
367
368   /**
369    * @brief move constructor
370    * @param[in] rhs Command
371    */
372   Command(Command&& rhs) noexcept
373   {
374     switch(rhs.type)
375     {
376       case CommandType::BEGIN_RENDER_PASS:
377       {
378         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(std::move(rhs.data.beginRenderPass));
379         break;
380       }
381       case CommandType::END_RENDER_PASS:
382       {
383         data.endRenderPass = std::move(rhs.data.endRenderPass);
384         break;
385       }
386       case CommandType::EXECUTE_COMMAND_BUFFERS:
387       {
388         data.executeCommandBuffers = std::move(rhs.data.executeCommandBuffers);
389         break;
390       }
391       case CommandType::BIND_VERTEX_BUFFERS:
392       {
393         data.bindVertexBuffers = std::move(rhs.data.bindVertexBuffers);
394         break;
395       }
396       case CommandType::BIND_INDEX_BUFFER:
397       {
398         data.bindIndexBuffer = rhs.data.bindIndexBuffer;
399         break;
400       }
401       case CommandType::BIND_UNIFORM_BUFFER:
402       {
403         data.bindUniformBuffers = std::move(rhs.data.bindUniformBuffers);
404         break;
405       }
406       case CommandType::BIND_SAMPLERS:
407       {
408         data.bindSamplers = std::move(rhs.data.bindSamplers);
409         break;
410       }
411       case CommandType::BIND_TEXTURES:
412       {
413         data.bindTextures = std::move(rhs.data.bindTextures);
414         break;
415       }
416       case CommandType::BIND_PIPELINE:
417       {
418         data.bindPipeline = rhs.data.bindPipeline;
419         break;
420       }
421       case CommandType::DRAW:
422       {
423         data.draw.type = rhs.data.draw.type;
424         data.draw.draw = rhs.data.draw.draw;
425         break;
426       }
427       case CommandType::DRAW_INDEXED:
428       {
429         data.draw.type        = rhs.data.draw.type;
430         data.draw.drawIndexed = rhs.data.draw.drawIndexed;
431         break;
432       }
433       case CommandType::DRAW_INDEXED_INDIRECT:
434       {
435         data.draw.type                = rhs.data.draw.type;
436         data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
437         break;
438       }
439       case CommandType::FLUSH:
440       {
441         // Nothing to do
442         break;
443       }
444       case CommandType::SET_SCISSOR:
445       {
446         data.scissor.region = rhs.data.scissor.region;
447         break;
448       }
449       case CommandType::SET_SCISSOR_TEST:
450       {
451         data.scissorTest.enable = rhs.data.scissorTest.enable;
452         break;
453       }
454       case CommandType::SET_VIEWPORT:
455       {
456         data.viewport.region = rhs.data.viewport.region;
457         break;
458       }
459       case CommandType::SET_VIEWPORT_TEST:
460       {
461         data.viewportTest.enable = rhs.data.viewportTest.enable;
462         break;
463       }
464
465       case CommandType::SET_COLOR_MASK:
466       {
467         data.colorMask.enabled = rhs.data.colorMask.enabled;
468         break;
469       }
470       case CommandType::CLEAR_STENCIL_BUFFER:
471       {
472         break;
473       }
474       case CommandType::CLEAR_DEPTH_BUFFER:
475       {
476         break;
477       }
478       case CommandType::SET_STENCIL_TEST_ENABLE:
479       {
480         data.stencilTest.enabled = rhs.data.stencilTest.enabled;
481         break;
482       }
483       case CommandType::SET_STENCIL_WRITE_MASK:
484       {
485         data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
486         break;
487       }
488       case CommandType::SET_STENCIL_OP:
489       {
490         data.stencilOp.failOp      = rhs.data.stencilOp.failOp;
491         data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
492         data.stencilOp.passOp      = rhs.data.stencilOp.passOp;
493         break;
494       }
495       case CommandType::SET_STENCIL_FUNC:
496       {
497         data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
498         data.stencilFunc.compareOp   = rhs.data.stencilFunc.compareOp;
499         data.stencilFunc.reference   = rhs.data.stencilFunc.reference;
500         break;
501       }
502       case CommandType::SET_DEPTH_COMPARE_OP:
503       {
504         data.depth.compareOp = rhs.data.depth.compareOp;
505         break;
506       }
507       case CommandType::SET_DEPTH_TEST_ENABLE:
508       {
509         data.depth.testEnabled = rhs.data.depth.testEnabled;
510         break;
511       }
512       case CommandType::SET_DEPTH_WRITE_ENABLE:
513       {
514         data.depth.writeEnabled = rhs.data.depth.writeEnabled;
515         break;
516       }
517     }
518     type = rhs.type;
519   }
520
521   CommandType type{CommandType::FLUSH}; ///< Type of command
522
523   union CommandData
524   {
525     CommandData()
526     {
527     }
528
529     ~CommandData()
530     {
531     } // do nothing
532
533     struct
534     {
535       std::vector<Graphics::TextureBinding> textureBindings;
536     } bindTextures{};
537
538     // BindSampler command
539     struct
540     {
541       std::vector<Graphics::SamplerBinding> samplerBindings;
542     } bindSamplers;
543
544     struct
545     {
546       using Binding = VertexBufferBindingDescriptor;
547       std::vector<Binding> vertexBufferBindings;
548     } bindVertexBuffers;
549
550     struct : public IndexBufferBindingDescriptor
551     {
552     } bindIndexBuffer;
553
554     struct
555     {
556       std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
557       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
558     } bindUniformBuffers;
559
560     struct
561     {
562       const TestGraphicsPipeline* pipeline{nullptr};
563     } bindPipeline;
564
565     struct : public DrawCallDescriptor
566     {
567     } draw;
568
569     struct
570     {
571       Graphics::Rect2D region;
572     } scissor;
573     struct
574     {
575       bool enable;
576     } scissorTest;
577     struct
578     {
579       Graphics::Viewport region;
580     } viewport;
581     struct
582     {
583       bool enable;
584     } viewportTest;
585
586     struct BeginRenderPassDescriptor
587     {
588       Graphics::RenderPass*             renderPass;
589       Graphics::RenderTarget*           renderTarget;
590       Graphics::Rect2D                  renderArea;
591       std::vector<Graphics::ClearValue> clearValues;
592     } beginRenderPass;
593
594     struct
595     {
596     } endRenderPass;
597
598     struct
599     {
600       std::vector<const TestGraphicsCommandBuffer*> buffers;
601     } executeCommandBuffers;
602
603     struct
604     {
605       Graphics::CompareOp compareOp;
606       bool                testEnabled;
607       bool                writeEnabled;
608     } depth;
609
610     struct
611     {
612       Graphics::StencilOp failOp;
613       Graphics::StencilOp passOp;
614       Graphics::StencilOp depthFailOp;
615     } stencilOp;
616
617     struct
618     {
619       uint32_t mask;
620     } stencilWriteMask;
621
622     struct
623     {
624       uint32_t            compareMask;
625       Graphics::CompareOp compareOp;
626       uint32_t            reference;
627     } stencilFunc;
628
629     struct
630     {
631       bool enabled;
632     } stencilTest;
633
634     struct
635     {
636       bool enabled;
637     } colorMask;
638   } data;
639 };
640
641 class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
642 {
643 public:
644   TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
645   ~TestGraphicsCommandBuffer()
646   {
647   }
648
649   void BindVertexBuffers(uint32_t                             firstBinding,
650                          std::vector<const Graphics::Buffer*> buffers,
651                          std::vector<uint32_t>                offsets) override
652   {
653     mCommands.emplace_back();
654     mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
655     auto& bindings        = mCommands.back().data.bindVertexBuffers.vertexBufferBindings;
656     if(bindings.size() < firstBinding + buffers.size())
657     {
658       bindings.resize(firstBinding + buffers.size());
659       auto index = firstBinding;
660       for(auto& buf : buffers)
661       {
662         bindings[index].buffer = static_cast<const TestGraphicsBuffer*>(buf);
663         bindings[index].offset = offsets[index - firstBinding];
664         index++;
665       }
666     }
667     mCallStack.PushCall("BindVertexBuffers", "");
668   }
669
670   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
671   {
672     mCommands.emplace_back();
673     auto& cmd     = mCommands.back();
674     cmd.type      = CommandType::BIND_UNIFORM_BUFFER;
675     auto& bindCmd = cmd.data.bindUniformBuffers;
676     for(const auto& binding : bindings)
677     {
678       if(binding.buffer)
679       {
680         auto testBuffer = static_cast<const TestGraphicsBuffer*>(binding.buffer);
681         if(testBuffer->IsCPUAllocated()) // standalone uniforms
682         {
683           bindCmd.standaloneUniformsBufferBinding.buffer   = testBuffer;
684           bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
685           bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
686           bindCmd.standaloneUniformsBufferBinding.emulated = true;
687         }
688         else // Bind regular UBO
689         {
690           // resize binding slots
691           if(binding.binding >= bindCmd.uniformBufferBindings.size())
692           {
693             bindCmd.uniformBufferBindings.resize(binding.binding + 1);
694           }
695           auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
696           slot.buffer   = testBuffer;
697           slot.offset   = binding.offset;
698           slot.binding  = binding.binding;
699           slot.emulated = false;
700         }
701       }
702     }
703     mCallStack.PushCall("BindUniformBuffers", "");
704   }
705
706   void BindPipeline(const Graphics::Pipeline& pipeline) override
707   {
708     mCommands.emplace_back();
709     mCommands.back().type                       = CommandType::BIND_PIPELINE;
710     mCommands.back().data.bindPipeline.pipeline = static_cast<const TestGraphicsPipeline*>(&pipeline);
711     mCallStack.PushCall("BindPipeline", "");
712   }
713
714   void BindTextures(std::vector<Graphics::TextureBinding>& textureBindings) override
715   {
716     mCommands.emplace_back();
717     mCommands.back().type                              = CommandType::BIND_TEXTURES;
718     mCommands.back().data.bindTextures.textureBindings = std::move(textureBindings);
719     mCallStack.PushCall("BindTextures", "");
720   }
721
722   void BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings) override
723   {
724     mCommands.emplace_back();
725     mCommands.back().data.bindSamplers.samplerBindings = std::move(samplerBindings);
726     mCallStack.PushCall("BindSamplers", "");
727   }
728
729   void BindPushConstants(void*    data,
730                          uint32_t size,
731                          uint32_t binding) override
732   {
733     mCallStack.PushCall("BindPushConstants", "");
734   }
735
736   void BindIndexBuffer(const Graphics::Buffer& buffer,
737                        uint32_t                offset,
738                        Graphics::Format        format) override
739   {
740     mCommands.emplace_back();
741     mCommands.back().type                        = CommandType::BIND_INDEX_BUFFER;
742     mCommands.back().data.bindIndexBuffer.buffer = static_cast<const TestGraphicsBuffer*>(&buffer);
743     mCommands.back().data.bindIndexBuffer.offset = offset;
744     mCommands.back().data.bindIndexBuffer.format = format;
745     mCallStack.PushCall("BindIndexBuffer", "");
746   }
747
748   void BeginRenderPass(
749     Graphics::RenderPass*             renderPass,
750     Graphics::RenderTarget*           renderTarget,
751     Graphics::Rect2D                  renderArea,
752     std::vector<Graphics::ClearValue> clearValues) override
753   {
754     mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS);
755     auto& cmd                             = mCommands.back();
756     cmd.data.beginRenderPass.renderPass   = renderPass;
757     cmd.data.beginRenderPass.renderTarget = renderTarget;
758     cmd.data.beginRenderPass.renderArea   = renderArea;
759     cmd.data.beginRenderPass.clearValues  = clearValues;
760
761     TraceCallStack::NamedParams namedParams;
762     namedParams["renderPass"] << std::hex << renderPass;
763     namedParams["renderTarget"] << std::hex << renderTarget;
764     namedParams["renderArea"] << renderArea.width << ", " << renderArea.height;
765     mCallStack.PushCall("BeginRenderPass", namedParams.str(), namedParams);
766   }
767
768   /**
769    * @brief Ends current render pass
770    *
771    * This command must be issued in order to finalize the render pass.
772    * It's up to the implementation whether anything has to be done but
773    * the Controller may use end RP marker in order to resolve resource
774    * dependencies (for example, to know when target texture is ready
775    * before passing it to another render pass).
776    */
777   void EndRenderPass() override
778   {
779     mCallStack.PushCall("EndRenderPass", "");
780   }
781
782   void ExecuteCommandBuffers(std::vector<const CommandBuffer*>&& commandBuffers) override
783   {
784     mCommands.emplace_back();
785     auto& cmd = mCommands.back();
786     cmd.type  = CommandType::EXECUTE_COMMAND_BUFFERS;
787     cmd.data.executeCommandBuffers.buffers.reserve(commandBuffers.size());
788     for(auto&& item : commandBuffers)
789     {
790       cmd.data.executeCommandBuffers.buffers.emplace_back(static_cast<const TestGraphicsCommandBuffer*>(item));
791     }
792     mCallStack.PushCall("ExecuteCommandBuffers", "");
793   }
794
795   void Draw(
796     uint32_t vertexCount,
797     uint32_t instanceCount,
798     uint32_t firstVertex,
799     uint32_t firstInstance) override
800   {
801     mCommands.emplace_back();
802     mCommands.back().type  = CommandType::DRAW;
803     auto& cmd              = mCommands.back().data.draw;
804     cmd.type               = DrawCallDescriptor::Type::DRAW;
805     cmd.draw.vertexCount   = vertexCount;
806     cmd.draw.instanceCount = instanceCount;
807     cmd.draw.firstInstance = firstInstance;
808     cmd.draw.firstVertex   = firstVertex;
809     mCallStack.PushCall("Draw", "");
810   }
811
812   void DrawIndexed(
813     uint32_t indexCount,
814     uint32_t instanceCount,
815     uint32_t firstIndex,
816     int32_t  vertexOffset,
817     uint32_t firstInstance) override
818   {
819     mCommands.emplace_back();
820     mCommands.back().type         = CommandType::DRAW_INDEXED;
821     auto& cmd                     = mCommands.back().data.draw;
822     cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
823     cmd.drawIndexed.firstIndex    = firstIndex;
824     cmd.drawIndexed.firstInstance = firstInstance;
825     cmd.drawIndexed.indexCount    = indexCount;
826     cmd.drawIndexed.vertexOffset  = vertexOffset;
827     cmd.drawIndexed.instanceCount = instanceCount;
828     mCallStack.PushCall("DrawIndexed", "");
829   }
830
831   void DrawIndexedIndirect(
832     Graphics::Buffer& buffer,
833     uint32_t          offset,
834     uint32_t          drawCount,
835     uint32_t          stride) override
836   {
837     mCommands.emplace_back();
838     mCommands.back().type             = CommandType::DRAW_INDEXED_INDIRECT;
839     auto& cmd                         = mCommands.back().data.draw;
840     cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
841     cmd.drawIndexedIndirect.buffer    = static_cast<const TestGraphicsBuffer*>(&buffer);
842     cmd.drawIndexedIndirect.offset    = offset;
843     cmd.drawIndexedIndirect.drawCount = drawCount;
844     cmd.drawIndexedIndirect.stride    = stride;
845     mCallStack.PushCall("DrawIndexedIndirect", "");
846   }
847
848   void Reset() override
849   {
850     mCommands.clear();
851     mCallStack.PushCall("Reset", "");
852   }
853
854   void SetScissor(Graphics::Rect2D value) override
855   {
856     TraceCallStack::NamedParams params;
857     params["x"] << value.x;
858     params["y"] << value.y;
859     params["width"] << value.width;
860     params["height"] << value.height;
861     mCallStack.PushCall("SetScissor", params.str(), params);
862
863     mCommands.emplace_back();
864     mCommands.back().type                = CommandType::SET_SCISSOR;
865     mCommands.back().data.scissor.region = value;
866   }
867
868   void SetScissorTestEnable(bool value) override
869   {
870     TraceCallStack::NamedParams params;
871     params["value"] << (value ? "T" : "F");
872     mCallStack.PushCall("SetScissorTestEnable", params.str(), params);
873
874     mCommands.emplace_back();
875     mCommands.back().type                    = CommandType::SET_SCISSOR_TEST;
876     mCommands.back().data.scissorTest.enable = value;
877   }
878
879   void SetViewport(Graphics::Viewport value) override
880   {
881     TraceCallStack::NamedParams params;
882     params["x"] << value.x;
883     params["y"] << value.y;
884     params["width"] << value.width;
885     params["height"] << value.height;
886     params["minDepth"] << value.minDepth;
887     params["maxDepth"] << value.maxDepth;
888     mCallStack.PushCall("SetViewport", params.str(), params);
889
890     mCommands.emplace_back();
891     mCommands.back().type                 = CommandType::SET_VIEWPORT;
892     mCommands.back().data.viewport.region = value;
893   }
894
895   void SetViewportEnable(bool value) override
896   {
897     TraceCallStack::NamedParams params;
898     params["value"] << (value ? "T" : "F");
899     mCallStack.PushCall("SetViewportEnable", params.str(), params);
900
901     mCommands.emplace_back();
902     mCommands.back().type                     = CommandType::SET_VIEWPORT_TEST;
903     mCommands.back().data.viewportTest.enable = value;
904   }
905
906   void SetColorMask(bool enabled) override
907   {
908     TraceCallStack::NamedParams params;
909     params["enabled"] << (enabled ? "T" : "F");
910     mCallStack.PushCall("SetColorMask", params.str(), params);
911     mCommands.emplace_back();
912     mCommands.back().type                   = CommandType::SET_COLOR_MASK;
913     mCommands.back().data.colorMask.enabled = enabled;
914   }
915
916   void ClearStencilBuffer() override
917   {
918     mCallStack.PushCall("SetStencilMask", "");
919     mCommands.emplace_back();
920     mCommands.back().type = CommandType::CLEAR_STENCIL_BUFFER;
921   }
922
923   void SetStencilTestEnable(bool stencilEnable) override
924   {
925     TraceCallStack::NamedParams params;
926     params["enabled"] << (stencilEnable ? "T" : "F");
927     mCallStack.PushCall("SetStencilTestEnable", params.str(), params);
928     mCommands.emplace_back();
929     mCommands.back().type                     = CommandType::SET_STENCIL_TEST_ENABLE;
930     mCommands.back().data.stencilTest.enabled = stencilEnable;
931   }
932
933   void SetStencilWriteMask(uint32_t writeMask) override
934   {
935     TraceCallStack::NamedParams params;
936     params["writeMask"] << std::hex << writeMask;
937     mCallStack.PushCall("SetStencilWriteMask", params.str(), params);
938     mCommands.emplace_back();
939     mCommands.back().type                       = CommandType::SET_STENCIL_WRITE_MASK;
940     mCommands.back().data.stencilWriteMask.mask = writeMask;
941   }
942
943   void SetStencilOp(Graphics::StencilOp failOp,
944                     Graphics::StencilOp passOp,
945                     Graphics::StencilOp depthFailOp) override
946   {
947     TraceCallStack::NamedParams params;
948     params["failOp"] << failOp;
949     params["passOp"] << passOp;
950     params["depthFailOp"] << depthFailOp;
951     mCallStack.PushCall("SetStencilOp", params.str(), params);
952     mCommands.emplace_back();
953     mCommands.back().type                       = CommandType::SET_STENCIL_OP;
954     mCommands.back().data.stencilOp.failOp      = failOp;
955     mCommands.back().data.stencilOp.passOp      = passOp;
956     mCommands.back().data.stencilOp.depthFailOp = depthFailOp;
957   }
958
959   void SetStencilFunc(Graphics::CompareOp compareOp,
960                       uint32_t            reference,
961                       uint32_t            compareMask) override
962   {
963     TraceCallStack::NamedParams params;
964     params["compareOp"] << compareOp;
965     params["compareMask"] << std::hex << compareMask;
966     params["reference"] << std::hex << reference;
967     mCallStack.PushCall("SetStencilFunc", params.str(), params);
968
969     mCommands.emplace_back();
970     mCommands.back().type = CommandType::SET_STENCIL_FUNC;
971
972     mCommands.back().data.stencilFunc.compareOp   = compareOp;
973     mCommands.back().data.stencilFunc.compareMask = compareMask;
974     mCommands.back().data.stencilFunc.reference   = reference;
975   }
976
977   void SetDepthCompareOp(Graphics::CompareOp compareOp) override
978   {
979     TraceCallStack::NamedParams params;
980     params["compareOp"] << compareOp;
981     mCallStack.PushCall("SetDepthCompareOp", params.str(), params);
982     mCommands.emplace_back();
983     mCommands.back().type                 = CommandType::SET_DEPTH_COMPARE_OP;
984     mCommands.back().data.depth.compareOp = compareOp;
985   }
986
987   void SetDepthTestEnable(bool depthTestEnable) override
988   {
989     TraceCallStack::NamedParams params;
990     params["enabled"] << (depthTestEnable ? "T" : "F");
991     mCallStack.PushCall("SetDepthTestEnable", params.str(), params);
992     mCommands.emplace_back();
993     mCommands.back().type                   = CommandType::SET_DEPTH_TEST_ENABLE;
994     mCommands.back().data.depth.testEnabled = depthTestEnable;
995   }
996   void SetDepthWriteEnable(bool depthWriteEnable) override
997   {
998     TraceCallStack::NamedParams params;
999     params["enabled"] << (depthWriteEnable ? "T" : "F");
1000     mCallStack.PushCall("SetDepthWriteEnable", params.str(), params);
1001     mCommands.emplace_back();
1002     mCommands.back().type                    = CommandType::SET_DEPTH_WRITE_ENABLE;
1003     mCommands.back().data.depth.writeEnabled = depthWriteEnable;
1004   }
1005   void ClearDepthBuffer() override
1006   {
1007     mCallStack.PushCall("ClearDepthBuffer", "");
1008     mCommands.emplace_back();
1009     mCommands.back().type = CommandType::CLEAR_DEPTH_BUFFER;
1010   }
1011
1012   [[nodiscard]] const std::vector<Command>& GetCommands() const
1013   {
1014     return mCommands;
1015   }
1016
1017   /**
1018    * Returns number of draw commands
1019    * @return
1020    */
1021   int GetDrawCallsCount();
1022
1023   /**
1024    * Retrieves state resolve for selected draw call
1025    * @param drawCommandIndex
1026    */
1027   void GetStateForDrawCall(int drawCallIndex);
1028
1029   /**
1030    * Retrieves commands of specified type
1031    */
1032   std::vector<const Command*> GetCommandsByType(CommandTypeMask mask) const;
1033
1034   std::vector<const Command*> GetChildCommandsByType(CommandTypeMask mask) const;
1035
1036 private:
1037   TraceCallStack&    mCallStack;
1038   TestGlAbstraction& mGlAbstraction;
1039
1040   std::vector<Command> mCommands;
1041 };
1042
1043 } // namespace Dali
1044
1045 #endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H