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