Sync tests for sync
[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       Graphics::SyncObject* syncObject;
597     } endRenderPass;
598
599     struct
600     {
601       std::vector<const TestGraphicsCommandBuffer*> buffers;
602     } executeCommandBuffers;
603
604     struct
605     {
606       Graphics::CompareOp compareOp;
607       bool                testEnabled;
608       bool                writeEnabled;
609     } depth;
610
611     struct
612     {
613       Graphics::StencilOp failOp;
614       Graphics::StencilOp passOp;
615       Graphics::StencilOp depthFailOp;
616     } stencilOp;
617
618     struct
619     {
620       uint32_t mask;
621     } stencilWriteMask;
622
623     struct
624     {
625       uint32_t            compareMask;
626       Graphics::CompareOp compareOp;
627       uint32_t            reference;
628     } stencilFunc;
629
630     struct
631     {
632       bool enabled;
633     } stencilTest;
634
635     struct
636     {
637       bool enabled;
638     } colorMask;
639   } data;
640 };
641
642 class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
643 {
644 public:
645   TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
646   ~TestGraphicsCommandBuffer()
647   {
648   }
649
650   void BindVertexBuffers(uint32_t                             firstBinding,
651                          std::vector<const Graphics::Buffer*> buffers,
652                          std::vector<uint32_t>                offsets) override
653   {
654     mCommands.emplace_back();
655     mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
656     auto& bindings        = mCommands.back().data.bindVertexBuffers.vertexBufferBindings;
657     if(bindings.size() < firstBinding + buffers.size())
658     {
659       bindings.resize(firstBinding + buffers.size());
660       auto index = firstBinding;
661       for(auto& buf : buffers)
662       {
663         bindings[index].buffer = static_cast<const TestGraphicsBuffer*>(buf);
664         bindings[index].offset = offsets[index - firstBinding];
665         index++;
666       }
667     }
668     mCallStack.PushCall("BindVertexBuffers", "");
669   }
670
671   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
672   {
673     mCommands.emplace_back();
674     auto& cmd     = mCommands.back();
675     cmd.type      = CommandType::BIND_UNIFORM_BUFFER;
676     auto& bindCmd = cmd.data.bindUniformBuffers;
677     for(const auto& binding : bindings)
678     {
679       if(binding.buffer)
680       {
681         auto testBuffer = static_cast<const TestGraphicsBuffer*>(binding.buffer);
682         if(testBuffer->IsCPUAllocated()) // standalone uniforms
683         {
684           bindCmd.standaloneUniformsBufferBinding.buffer   = testBuffer;
685           bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
686           bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
687           bindCmd.standaloneUniformsBufferBinding.emulated = true;
688         }
689         else // Bind regular UBO
690         {
691           // resize binding slots
692           if(binding.binding >= bindCmd.uniformBufferBindings.size())
693           {
694             bindCmd.uniformBufferBindings.resize(binding.binding + 1);
695           }
696           auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
697           slot.buffer   = testBuffer;
698           slot.offset   = binding.offset;
699           slot.binding  = binding.binding;
700           slot.emulated = false;
701         }
702       }
703     }
704     mCallStack.PushCall("BindUniformBuffers", "");
705   }
706
707   void BindPipeline(const Graphics::Pipeline& pipeline) override
708   {
709     mCommands.emplace_back();
710     mCommands.back().type                       = CommandType::BIND_PIPELINE;
711     mCommands.back().data.bindPipeline.pipeline = static_cast<const TestGraphicsPipeline*>(&pipeline);
712     mCallStack.PushCall("BindPipeline", "");
713   }
714
715   void BindTextures(std::vector<Graphics::TextureBinding>& textureBindings) override
716   {
717     mCommands.emplace_back();
718     mCommands.back().type                              = CommandType::BIND_TEXTURES;
719     mCommands.back().data.bindTextures.textureBindings = std::move(textureBindings);
720     mCallStack.PushCall("BindTextures", "");
721   }
722
723   void BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings) override
724   {
725     mCommands.emplace_back();
726     mCommands.back().data.bindSamplers.samplerBindings = std::move(samplerBindings);
727     mCallStack.PushCall("BindSamplers", "");
728   }
729
730   void BindPushConstants(void*    data,
731                          uint32_t size,
732                          uint32_t binding) override
733   {
734     mCallStack.PushCall("BindPushConstants", "");
735   }
736
737   void BindIndexBuffer(const Graphics::Buffer& buffer,
738                        uint32_t                offset,
739                        Graphics::Format        format) override
740   {
741     mCommands.emplace_back();
742     mCommands.back().type                        = CommandType::BIND_INDEX_BUFFER;
743     mCommands.back().data.bindIndexBuffer.buffer = static_cast<const TestGraphicsBuffer*>(&buffer);
744     mCommands.back().data.bindIndexBuffer.offset = offset;
745     mCommands.back().data.bindIndexBuffer.format = format;
746     mCallStack.PushCall("BindIndexBuffer", "");
747   }
748
749   void BeginRenderPass(
750     Graphics::RenderPass*             renderPass,
751     Graphics::RenderTarget*           renderTarget,
752     Graphics::Rect2D                  renderArea,
753     std::vector<Graphics::ClearValue> clearValues) override
754   {
755     mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS);
756     auto& cmd                             = mCommands.back();
757     cmd.data.beginRenderPass.renderPass   = renderPass;
758     cmd.data.beginRenderPass.renderTarget = renderTarget;
759     cmd.data.beginRenderPass.renderArea   = renderArea;
760     cmd.data.beginRenderPass.clearValues  = clearValues;
761
762     TraceCallStack::NamedParams namedParams;
763     namedParams["renderPass"] << std::hex << renderPass;
764     namedParams["renderTarget"] << std::hex << renderTarget;
765     namedParams["renderArea"] << renderArea.width << ", " << renderArea.height;
766     mCallStack.PushCall("BeginRenderPass", namedParams.str(), namedParams);
767   }
768
769   /**
770    * @brief Ends current render pass
771    *
772    * This command must be issued in order to finalize the render pass.
773    * It's up to the implementation whether anything has to be done but
774    * the Controller may use end RP marker in order to resolve resource
775    * dependencies (for example, to know when target texture is ready
776    * before passing it to another render pass).
777    */
778   void EndRenderPass(Graphics::SyncObject* syncObject) override
779   {
780     mCommands.emplace_back(CommandType::END_RENDER_PASS);
781     auto& cmd = mCommands.back();
782
783     cmd.data.endRenderPass.syncObject = syncObject;
784
785     TraceCallStack::NamedParams namedParams;
786     namedParams["syncObject"] << std::hex << syncObject;
787     mCallStack.PushCall("EndRenderPass", namedParams.str(), namedParams);
788   }
789
790   void ExecuteCommandBuffers(std::vector<const CommandBuffer*>&& commandBuffers) override
791   {
792     mCommands.emplace_back();
793     auto& cmd = mCommands.back();
794     cmd.type  = CommandType::EXECUTE_COMMAND_BUFFERS;
795     cmd.data.executeCommandBuffers.buffers.reserve(commandBuffers.size());
796     for(auto&& item : commandBuffers)
797     {
798       cmd.data.executeCommandBuffers.buffers.emplace_back(static_cast<const TestGraphicsCommandBuffer*>(item));
799     }
800     mCallStack.PushCall("ExecuteCommandBuffers", "");
801   }
802
803   void Draw(
804     uint32_t vertexCount,
805     uint32_t instanceCount,
806     uint32_t firstVertex,
807     uint32_t firstInstance) override
808   {
809     mCommands.emplace_back();
810     mCommands.back().type  = CommandType::DRAW;
811     auto& cmd              = mCommands.back().data.draw;
812     cmd.type               = DrawCallDescriptor::Type::DRAW;
813     cmd.draw.vertexCount   = vertexCount;
814     cmd.draw.instanceCount = instanceCount;
815     cmd.draw.firstInstance = firstInstance;
816     cmd.draw.firstVertex   = firstVertex;
817     mCallStack.PushCall("Draw", "");
818   }
819
820   void DrawIndexed(
821     uint32_t indexCount,
822     uint32_t instanceCount,
823     uint32_t firstIndex,
824     int32_t  vertexOffset,
825     uint32_t firstInstance) override
826   {
827     mCommands.emplace_back();
828     mCommands.back().type         = CommandType::DRAW_INDEXED;
829     auto& cmd                     = mCommands.back().data.draw;
830     cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
831     cmd.drawIndexed.firstIndex    = firstIndex;
832     cmd.drawIndexed.firstInstance = firstInstance;
833     cmd.drawIndexed.indexCount    = indexCount;
834     cmd.drawIndexed.vertexOffset  = vertexOffset;
835     cmd.drawIndexed.instanceCount = instanceCount;
836     mCallStack.PushCall("DrawIndexed", "");
837   }
838
839   void DrawIndexedIndirect(
840     Graphics::Buffer& buffer,
841     uint32_t          offset,
842     uint32_t          drawCount,
843     uint32_t          stride) override
844   {
845     mCommands.emplace_back();
846     mCommands.back().type             = CommandType::DRAW_INDEXED_INDIRECT;
847     auto& cmd                         = mCommands.back().data.draw;
848     cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
849     cmd.drawIndexedIndirect.buffer    = static_cast<const TestGraphicsBuffer*>(&buffer);
850     cmd.drawIndexedIndirect.offset    = offset;
851     cmd.drawIndexedIndirect.drawCount = drawCount;
852     cmd.drawIndexedIndirect.stride    = stride;
853     mCallStack.PushCall("DrawIndexedIndirect", "");
854   }
855
856   void Reset() override
857   {
858     mCommands.clear();
859     mCallStack.PushCall("Reset", "");
860   }
861
862   void SetScissor(Graphics::Rect2D value) override
863   {
864     TraceCallStack::NamedParams params;
865     params["x"] << value.x;
866     params["y"] << value.y;
867     params["width"] << value.width;
868     params["height"] << value.height;
869     mCallStack.PushCall("SetScissor", params.str(), params);
870
871     mCommands.emplace_back();
872     mCommands.back().type                = CommandType::SET_SCISSOR;
873     mCommands.back().data.scissor.region = value;
874   }
875
876   void SetScissorTestEnable(bool value) override
877   {
878     TraceCallStack::NamedParams params;
879     params["value"] << (value ? "T" : "F");
880     mCallStack.PushCall("SetScissorTestEnable", params.str(), params);
881
882     mCommands.emplace_back();
883     mCommands.back().type                    = CommandType::SET_SCISSOR_TEST;
884     mCommands.back().data.scissorTest.enable = value;
885   }
886
887   void SetViewport(Graphics::Viewport value) override
888   {
889     TraceCallStack::NamedParams params;
890     params["x"] << value.x;
891     params["y"] << value.y;
892     params["width"] << value.width;
893     params["height"] << value.height;
894     params["minDepth"] << value.minDepth;
895     params["maxDepth"] << value.maxDepth;
896     mCallStack.PushCall("SetViewport", params.str(), params);
897
898     mCommands.emplace_back();
899     mCommands.back().type                 = CommandType::SET_VIEWPORT;
900     mCommands.back().data.viewport.region = value;
901   }
902
903   void SetViewportEnable(bool value) override
904   {
905     TraceCallStack::NamedParams params;
906     params["value"] << (value ? "T" : "F");
907     mCallStack.PushCall("SetViewportEnable", params.str(), params);
908
909     mCommands.emplace_back();
910     mCommands.back().type                     = CommandType::SET_VIEWPORT_TEST;
911     mCommands.back().data.viewportTest.enable = value;
912   }
913
914   void SetColorMask(bool enabled) override
915   {
916     TraceCallStack::NamedParams params;
917     params["enabled"] << (enabled ? "T" : "F");
918     mCallStack.PushCall("SetColorMask", params.str(), params);
919     mCommands.emplace_back();
920     mCommands.back().type                   = CommandType::SET_COLOR_MASK;
921     mCommands.back().data.colorMask.enabled = enabled;
922   }
923
924   void ClearStencilBuffer() override
925   {
926     mCallStack.PushCall("SetStencilMask", "");
927     mCommands.emplace_back();
928     mCommands.back().type = CommandType::CLEAR_STENCIL_BUFFER;
929   }
930
931   void SetStencilTestEnable(bool stencilEnable) override
932   {
933     TraceCallStack::NamedParams params;
934     params["enabled"] << (stencilEnable ? "T" : "F");
935     mCallStack.PushCall("SetStencilTestEnable", params.str(), params);
936     mCommands.emplace_back();
937     mCommands.back().type                     = CommandType::SET_STENCIL_TEST_ENABLE;
938     mCommands.back().data.stencilTest.enabled = stencilEnable;
939   }
940
941   void SetStencilWriteMask(uint32_t writeMask) override
942   {
943     TraceCallStack::NamedParams params;
944     params["writeMask"] << std::hex << writeMask;
945     mCallStack.PushCall("SetStencilWriteMask", params.str(), params);
946     mCommands.emplace_back();
947     mCommands.back().type                       = CommandType::SET_STENCIL_WRITE_MASK;
948     mCommands.back().data.stencilWriteMask.mask = writeMask;
949   }
950
951   void SetStencilOp(Graphics::StencilOp failOp,
952                     Graphics::StencilOp passOp,
953                     Graphics::StencilOp depthFailOp) override
954   {
955     TraceCallStack::NamedParams params;
956     params["failOp"] << failOp;
957     params["passOp"] << passOp;
958     params["depthFailOp"] << depthFailOp;
959     mCallStack.PushCall("SetStencilOp", params.str(), params);
960     mCommands.emplace_back();
961     mCommands.back().type                       = CommandType::SET_STENCIL_OP;
962     mCommands.back().data.stencilOp.failOp      = failOp;
963     mCommands.back().data.stencilOp.passOp      = passOp;
964     mCommands.back().data.stencilOp.depthFailOp = depthFailOp;
965   }
966
967   void SetStencilFunc(Graphics::CompareOp compareOp,
968                       uint32_t            reference,
969                       uint32_t            compareMask) override
970   {
971     TraceCallStack::NamedParams params;
972     params["compareOp"] << compareOp;
973     params["compareMask"] << std::hex << compareMask;
974     params["reference"] << std::hex << reference;
975     mCallStack.PushCall("SetStencilFunc", params.str(), params);
976
977     mCommands.emplace_back();
978     mCommands.back().type = CommandType::SET_STENCIL_FUNC;
979
980     mCommands.back().data.stencilFunc.compareOp   = compareOp;
981     mCommands.back().data.stencilFunc.compareMask = compareMask;
982     mCommands.back().data.stencilFunc.reference   = reference;
983   }
984
985   void SetDepthCompareOp(Graphics::CompareOp compareOp) override
986   {
987     TraceCallStack::NamedParams params;
988     params["compareOp"] << compareOp;
989     mCallStack.PushCall("SetDepthCompareOp", params.str(), params);
990     mCommands.emplace_back();
991     mCommands.back().type                 = CommandType::SET_DEPTH_COMPARE_OP;
992     mCommands.back().data.depth.compareOp = compareOp;
993   }
994
995   void SetDepthTestEnable(bool depthTestEnable) override
996   {
997     TraceCallStack::NamedParams params;
998     params["enabled"] << (depthTestEnable ? "T" : "F");
999     mCallStack.PushCall("SetDepthTestEnable", params.str(), params);
1000     mCommands.emplace_back();
1001     mCommands.back().type                   = CommandType::SET_DEPTH_TEST_ENABLE;
1002     mCommands.back().data.depth.testEnabled = depthTestEnable;
1003   }
1004   void SetDepthWriteEnable(bool depthWriteEnable) override
1005   {
1006     TraceCallStack::NamedParams params;
1007     params["enabled"] << (depthWriteEnable ? "T" : "F");
1008     mCallStack.PushCall("SetDepthWriteEnable", params.str(), params);
1009     mCommands.emplace_back();
1010     mCommands.back().type                    = CommandType::SET_DEPTH_WRITE_ENABLE;
1011     mCommands.back().data.depth.writeEnabled = depthWriteEnable;
1012   }
1013   void ClearDepthBuffer() override
1014   {
1015     mCallStack.PushCall("ClearDepthBuffer", "");
1016     mCommands.emplace_back();
1017     mCommands.back().type = CommandType::CLEAR_DEPTH_BUFFER;
1018   }
1019
1020   [[nodiscard]] const std::vector<Command>& GetCommands() const
1021   {
1022     return mCommands;
1023   }
1024
1025   /**
1026    * Returns number of draw commands
1027    * @return
1028    */
1029   int GetDrawCallsCount();
1030
1031   /**
1032    * Retrieves state resolve for selected draw call
1033    * @param drawCommandIndex
1034    */
1035   void GetStateForDrawCall(int drawCallIndex);
1036
1037   /**
1038    * Retrieves commands of specified type
1039    */
1040   std::vector<const Command*> GetCommandsByType(CommandTypeMask mask) const;
1041
1042   std::vector<const Command*> GetChildCommandsByType(CommandTypeMask mask) const;
1043
1044 private:
1045   TraceCallStack&    mCallStack;
1046   TestGlAbstraction& mGlAbstraction;
1047
1048   std::vector<Command> mCommands;
1049 };
1050
1051 } // namespace Dali
1052
1053 #endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H