Merge branch 'devel/master' into devel/graphics
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-command-buffer.h
1 #ifndef DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
2 #define DALI_GRAPHICS_GLES_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
21 // EXTERNAL INCLUDES
22 #include <dali/graphics-api/graphics-command-buffer-create-info.h>
23 #include <dali/graphics-api/graphics-command-buffer.h>
24 #include <dali/graphics-api/graphics-types.h>
25
26 // INTERNAL INCLUDES
27 #include "gles-graphics-resource.h"
28 #include "gles-graphics-types.h"
29
30 namespace Dali::Graphics::GLES
31 {
32 class Pipeline;
33 class RenderPass;
34 class Framebuffer;
35 class CommandBuffer;
36 enum class CommandType
37 {
38   FLUSH,
39   BIND_TEXTURES,
40   BIND_SAMPLERS,
41   BIND_VERTEX_BUFFERS,
42   BIND_INDEX_BUFFER,
43   BIND_UNIFORM_BUFFER,
44   BIND_PIPELINE,
45   DRAW,
46   DRAW_INDEXED,
47   DRAW_INDEXED_INDIRECT,
48   SET_SCISSOR,
49   SET_SCISSOR_TEST,
50   SET_VIEWPORT,
51   BEGIN_RENDERPASS,
52   END_RENDERPASS,
53   EXECUTE_COMMAND_BUFFERS,
54   PRESENT_RENDER_TARGET,
55   SET_COLOR_MASK,
56   CLEAR_STENCIL_BUFFER,
57   CLEAR_DEPTH_BUFFER,
58   SET_STENCIL_TEST_ENABLE,
59   SET_STENCIL_WRITE_MASK,
60   SET_STENCIL_OP,
61   SET_STENCIL_FUNC,
62   SET_DEPTH_COMPARE_OP,
63   SET_DEPTH_TEST_ENABLE,
64   SET_DEPTH_WRITE_ENABLE,
65 };
66
67 /**
68  * @brief Helper function to invoke destructor on anonymous struct
69  */
70 template<class T>
71 static void InvokeDestructor(T& object)
72 {
73   object.~T();
74 }
75
76 /**
77  * Command structure allocates memory to store a single command
78  */
79 struct Command
80 {
81   Command() = delete;
82
83   Command(CommandType commandType)
84   {
85     type = commandType;
86     switch(type)
87     {
88       case CommandType::BIND_VERTEX_BUFFERS:
89       {
90         new(&bindVertexBuffers) decltype(bindVertexBuffers);
91         break;
92       }
93       case CommandType::BIND_TEXTURES:
94       {
95         new(&bindTextures) decltype(bindTextures);
96         break;
97       }
98       case CommandType::BEGIN_RENDERPASS:
99       {
100         // run destructor
101         new(&beginRenderPass) decltype(beginRenderPass);
102         break;
103       }
104       default:
105       {
106       }
107     }
108   }
109
110   ~Command()
111   {
112     switch(type)
113     {
114       case CommandType::BIND_VERTEX_BUFFERS:
115       {
116         InvokeDestructor(bindVertexBuffers);
117         break;
118       }
119       case CommandType::BIND_TEXTURES:
120       {
121         InvokeDestructor(bindTextures);
122         break;
123       }
124       case CommandType::BEGIN_RENDERPASS:
125       {
126         // run destructor
127         InvokeDestructor(beginRenderPass);
128         break;
129       }
130       default:
131       {
132       }
133     }
134   }
135
136   /**
137    * @brief Copy constructor
138    * @param[in] rhs Command
139    */
140   Command(const Command& rhs)
141   {
142     switch(rhs.type)
143     {
144       case CommandType::BIND_VERTEX_BUFFERS:
145       {
146         new(&bindVertexBuffers) decltype(bindVertexBuffers);
147         bindVertexBuffers = rhs.bindVertexBuffers;
148         break;
149       }
150       case CommandType::BIND_INDEX_BUFFER:
151       {
152         bindIndexBuffer = rhs.bindIndexBuffer;
153         break;
154       }
155       case CommandType::BIND_SAMPLERS:
156       {
157         bindSamplers = rhs.bindSamplers;
158         break;
159       }
160       case CommandType::BIND_TEXTURES:
161       {
162         new(&bindTextures) decltype(bindTextures);
163         bindTextures = rhs.bindTextures;
164         break;
165       }
166       case CommandType::BIND_PIPELINE:
167       {
168         bindPipeline = rhs.bindPipeline;
169         break;
170       }
171       case CommandType::BIND_UNIFORM_BUFFER:
172       {
173         bindUniformBuffers = rhs.bindUniformBuffers;
174         break;
175       }
176       case CommandType::DRAW:
177       {
178         draw.type = rhs.draw.type;
179         draw.draw = rhs.draw.draw;
180         break;
181       }
182       case CommandType::DRAW_INDEXED:
183       {
184         draw.type        = rhs.draw.type;
185         draw.drawIndexed = rhs.draw.drawIndexed;
186         break;
187       }
188       case CommandType::DRAW_INDEXED_INDIRECT:
189       {
190         draw.type                = rhs.draw.type;
191         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
192         break;
193       }
194       case CommandType::BEGIN_RENDERPASS:
195       {
196         new(&beginRenderPass) BeginRenderPassDescriptor(rhs.beginRenderPass);
197         break;
198       }
199       case CommandType::END_RENDERPASS:
200       {
201         break;
202       }
203       case CommandType::EXECUTE_COMMAND_BUFFERS:
204       {
205         executeCommandBuffers = rhs.executeCommandBuffers;
206         break;
207       }
208       case CommandType::FLUSH:
209       {
210         // Nothing to do
211         break;
212       }
213       case CommandType::SET_SCISSOR:
214       {
215         scissor.region = rhs.scissor.region;
216         break;
217       }
218       case CommandType::SET_SCISSOR_TEST:
219       {
220         scissorTest.enable = rhs.scissorTest.enable;
221         break;
222       }
223       case CommandType::SET_VIEWPORT:
224       {
225         viewport.region = rhs.viewport.region;
226         break;
227       }
228       case CommandType::PRESENT_RENDER_TARGET:
229       {
230         presentRenderTarget = rhs.presentRenderTarget;
231         break;
232       }
233       case CommandType::SET_COLOR_MASK:
234       {
235         colorMask.enabled = rhs.colorMask.enabled;
236         break;
237       }
238       case CommandType::CLEAR_STENCIL_BUFFER:
239       {
240         break;
241       }
242       case CommandType::CLEAR_DEPTH_BUFFER:
243       {
244         break;
245       }
246       case CommandType::SET_STENCIL_TEST_ENABLE:
247       {
248         stencilTest.enabled = rhs.stencilTest.enabled;
249         break;
250       }
251       case CommandType::SET_STENCIL_FUNC:
252       {
253         stencilFunc.compareMask = rhs.stencilFunc.compareMask;
254         stencilFunc.compareOp   = rhs.stencilFunc.compareOp;
255         stencilFunc.reference   = rhs.stencilFunc.reference;
256         break;
257       }
258       case CommandType::SET_STENCIL_WRITE_MASK:
259       {
260         stencilWriteMask.mask = rhs.stencilWriteMask.mask;
261         break;
262       }
263       case CommandType::SET_STENCIL_OP:
264       {
265         stencilOp.failOp      = rhs.stencilOp.failOp;
266         stencilOp.depthFailOp = rhs.stencilOp.depthFailOp;
267         stencilOp.passOp      = rhs.stencilOp.passOp;
268         break;
269       }
270
271       case CommandType::SET_DEPTH_COMPARE_OP:
272       {
273         depth.compareOp = rhs.depth.compareOp;
274         break;
275       }
276       case CommandType::SET_DEPTH_TEST_ENABLE:
277       {
278         depth.testEnabled = rhs.depth.testEnabled;
279         break;
280       }
281       case CommandType::SET_DEPTH_WRITE_ENABLE:
282       {
283         depth.writeEnabled = rhs.depth.writeEnabled;
284         break;
285       }
286     }
287     type = rhs.type;
288   }
289
290   /**
291    * @brief Move constructor
292    * @param[in] rhs Command
293    */
294   Command(Command&& rhs) noexcept
295   {
296     switch(rhs.type)
297     {
298       case CommandType::BIND_VERTEX_BUFFERS:
299       {
300         new(&bindVertexBuffers) decltype(bindVertexBuffers);
301         bindVertexBuffers = std::move(rhs.bindVertexBuffers);
302         break;
303       }
304       case CommandType::BIND_INDEX_BUFFER:
305       {
306         bindIndexBuffer = rhs.bindIndexBuffer;
307         break;
308       }
309       case CommandType::BIND_UNIFORM_BUFFER:
310       {
311         bindUniformBuffers = std::move(rhs.bindUniformBuffers);
312         break;
313       }
314       case CommandType::BIND_SAMPLERS:
315       {
316         bindSamplers = std::move(rhs.bindSamplers);
317         break;
318       }
319       case CommandType::BIND_TEXTURES:
320       {
321         new(&bindTextures) decltype(bindTextures);
322         bindTextures = std::move(rhs.bindTextures);
323         break;
324       }
325       case CommandType::BIND_PIPELINE:
326       {
327         bindPipeline = rhs.bindPipeline;
328         break;
329       }
330       case CommandType::DRAW:
331       {
332         draw.type = rhs.draw.type;
333         draw.draw = rhs.draw.draw;
334         break;
335       }
336       case CommandType::DRAW_INDEXED:
337       {
338         draw.type        = rhs.draw.type;
339         draw.drawIndexed = rhs.draw.drawIndexed;
340         break;
341       }
342       case CommandType::DRAW_INDEXED_INDIRECT:
343       {
344         draw.type                = rhs.draw.type;
345         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
346         break;
347       }
348       case CommandType::BEGIN_RENDERPASS:
349       {
350         new(&beginRenderPass) BeginRenderPassDescriptor(std::move(rhs.beginRenderPass));
351         break;
352       }
353       case CommandType::END_RENDERPASS:
354       {
355         break;
356       }
357       case CommandType::EXECUTE_COMMAND_BUFFERS:
358       {
359         executeCommandBuffers = std::move(rhs.executeCommandBuffers);
360         break;
361       }
362       case CommandType::FLUSH:
363       {
364         // Nothing to do
365         break;
366       }
367       case CommandType::SET_SCISSOR:
368       {
369         scissor.region = rhs.scissor.region;
370         break;
371       }
372       case CommandType::SET_SCISSOR_TEST:
373       {
374         scissorTest.enable = rhs.scissorTest.enable;
375         break;
376       }
377       case CommandType::SET_VIEWPORT:
378       {
379         viewport.region = rhs.viewport.region;
380         break;
381       }
382       case CommandType::PRESENT_RENDER_TARGET:
383       {
384         presentRenderTarget = rhs.presentRenderTarget;
385         break;
386       }
387       case CommandType::SET_COLOR_MASK:
388       {
389         colorMask.enabled = rhs.colorMask.enabled;
390         break;
391       }
392       case CommandType::CLEAR_STENCIL_BUFFER:
393       {
394         break;
395       }
396       case CommandType::CLEAR_DEPTH_BUFFER:
397       {
398         break;
399       }
400       case CommandType::SET_STENCIL_TEST_ENABLE:
401       {
402         stencilTest.enabled = rhs.stencilTest.enabled;
403         break;
404       }
405       case CommandType::SET_STENCIL_FUNC:
406       {
407         stencilFunc.compareMask = rhs.stencilFunc.compareMask;
408         stencilFunc.compareOp   = rhs.stencilFunc.compareOp;
409         stencilFunc.reference   = rhs.stencilFunc.reference;
410         break;
411       }
412       case CommandType::SET_STENCIL_WRITE_MASK:
413       {
414         stencilWriteMask.mask = rhs.stencilWriteMask.mask;
415         break;
416       }
417       case CommandType::SET_STENCIL_OP:
418       {
419         stencilOp.failOp      = rhs.stencilOp.failOp;
420         stencilOp.depthFailOp = rhs.stencilOp.depthFailOp;
421         stencilOp.passOp      = rhs.stencilOp.passOp;
422         break;
423       }
424
425       case CommandType::SET_DEPTH_COMPARE_OP:
426       {
427         depth.compareOp = rhs.depth.compareOp;
428         break;
429       }
430       case CommandType::SET_DEPTH_TEST_ENABLE:
431       {
432         depth.testEnabled = rhs.depth.testEnabled;
433         break;
434       }
435       case CommandType::SET_DEPTH_WRITE_ENABLE:
436       {
437         depth.writeEnabled = rhs.depth.writeEnabled;
438         break;
439       }
440     }
441     type = rhs.type;
442   }
443
444   CommandType type{CommandType::FLUSH}; ///< Type of command
445
446   union
447   {
448     struct
449     {
450       std::vector<Graphics::TextureBinding> textureBindings;
451     } bindTextures{};
452
453     // BindSampler command
454     struct
455     {
456       std::vector<Graphics::SamplerBinding> samplerBindings;
457     } bindSamplers;
458
459     struct
460     {
461       using Binding = GLES::VertexBufferBindingDescriptor;
462       std::vector<Binding> vertexBufferBindings;
463     } bindVertexBuffers;
464
465     struct : public IndexBufferBindingDescriptor
466     {
467     } bindIndexBuffer;
468
469     struct
470     {
471       std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
472       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
473     } bindUniformBuffers;
474
475     struct
476     {
477       const GLES::Pipeline* pipeline{nullptr};
478     } bindPipeline;
479
480     struct : public DrawCallDescriptor
481     {
482     } draw;
483
484     struct
485     {
486       Graphics::Rect2D region;
487     } scissor;
488
489     struct
490     {
491       bool enable;
492     } scissorTest;
493
494     struct
495     {
496       Graphics::Viewport region;
497     } viewport;
498
499     struct BeginRenderPassDescriptor
500       beginRenderPass;
501
502     struct
503     {
504     } endRenderPass;
505
506     struct
507     {
508       std::vector<const GLES::CommandBuffer*> buffers;
509     } executeCommandBuffers;
510
511     struct
512     {
513       GLES::RenderTarget* targetToPresent;
514     } presentRenderTarget;
515
516     struct
517     {
518       Graphics::CompareOp compareOp;
519       bool                testEnabled;
520       bool                writeEnabled;
521     } depth;
522
523     struct
524     {
525       Graphics::StencilOp failOp;
526       Graphics::StencilOp passOp;
527       Graphics::StencilOp depthFailOp;
528     } stencilOp;
529
530     struct
531     {
532       uint32_t mask;
533     } stencilWriteMask;
534
535     struct
536     {
537       uint32_t            compareMask;
538       Graphics::CompareOp compareOp;
539       uint32_t            reference;
540     } stencilFunc;
541
542     struct
543     {
544       bool enabled;
545     } stencilTest;
546
547     struct
548     {
549       bool enabled;
550     } colorMask;
551   };
552 };
553
554 using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::CommandBufferCreateInfo>;
555
556 class CommandBuffer : public CommandBufferResource
557 {
558 public:
559   CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
560
561   ~CommandBuffer() override;
562
563   /**
564    * @copydoc Dali::Graphics::CommandBuffer::BindVertexBuffers
565    */
566   void BindVertexBuffers(uint32_t                             firstBinding,
567                          std::vector<const Graphics::Buffer*> buffers,
568                          std::vector<uint32_t>                offsets) override;
569
570   /**
571    * @copydoc Dali::Graphics::CommandBuffer::BindUniformBuffers
572    */
573   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
574
575   /**
576    * @copydoc Dali::Graphics::CommandBuffer::BindPipeline
577    */
578   void BindPipeline(const Graphics::Pipeline& pipeline) override;
579
580   /**
581    * @copydoc Dali::Graphics::CommandBuffer::BindTextures
582    */
583   void BindTextures(std::vector<TextureBinding>& textureBindings) override;
584
585   /**
586    * @copydoc Dali::Graphics::CommandBuffer::BindSamplers
587    */
588   void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
589
590   /**
591    * @copydoc Dali::Graphics::CommandBuffer::BindPushConstants
592    */
593   void BindPushConstants(void*    data,
594                          uint32_t size,
595                          uint32_t binding) override;
596
597   /**
598    * @copydoc Dali::Graphics::CommandBuffer::BindIndexBuffer
599    */
600   void BindIndexBuffer(const Graphics::Buffer& buffer,
601                        uint32_t                offset,
602                        Format                  format) override;
603
604   /**
605    * @copydoc Dali::Graphics::CommandBuffer::BeginRenderPass
606    */
607   void BeginRenderPass(
608     Graphics::RenderPass*   renderPass,
609     Graphics::RenderTarget* renderTarget,
610     Rect2D                  renderArea,
611     std::vector<ClearValue> clearValues) override;
612
613   /**
614    * @copydoc Dali::Graphics::CommandBuffer::EndRenderPass
615    */
616   void EndRenderPass() override;
617
618   /**
619    * @copydoc Dali::Graphics::CommandBuffer::ExecuteCommandBuffers
620    */
621   void ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers) override;
622
623   /**
624    * @copydoc Dali::Graphics::CommandBuffer::Draw
625    */
626   void Draw(
627     uint32_t vertexCount,
628     uint32_t instanceCount,
629     uint32_t firstVertex,
630     uint32_t firstInstance) override;
631
632   /**
633    * @copydoc Dali::Graphics::CommandBuffer::DrawIndexed
634    */
635   void DrawIndexed(
636     uint32_t indexCount,
637     uint32_t instanceCount,
638     uint32_t firstIndex,
639     int32_t  vertexOffset,
640     uint32_t firstInstance) override;
641
642   /**
643    * @copydoc Dali::Graphics::CommandBuffer::DrawIndexedIndirect
644    */
645   void DrawIndexedIndirect(
646     Graphics::Buffer& buffer,
647     uint32_t          offset,
648     uint32_t          drawCount,
649     uint32_t          stride) override;
650
651   /**
652    * @copydoc Dali::Graphics::CommandBuffer::Reset
653    */
654   void Reset() override;
655
656   /**
657    * @copydoc Dali::Graphics::CommandBuffer::SetScissor
658    */
659   void SetScissor(Graphics::Rect2D value) override;
660
661   /**
662    * @copydoc Dali::Graphics::CommandBuffer::SetScissorTestEnable
663    */
664   void SetScissorTestEnable(bool value) override;
665
666   /**
667    * @copydoc Dali::Graphics::CommandBuffer::SetViewport
668    */
669   void SetViewport(Viewport value) override;
670
671   /**
672    * @copydoc Dali::Graphics::CommandBuffer::SetViewportEnable
673    */
674   void SetViewportEnable(bool value) override;
675
676   /**
677    * @copydoc Dali::Graphics::CommandBuffer::SetColorMask
678    */
679   void SetColorMask(bool enabled) override;
680
681   /**
682    * @copydoc Dali::Graphics::CommandBuffer::ClearStencilBuffer
683    */
684   void ClearStencilBuffer() override;
685
686   /**
687    * @copydoc Dali::Graphics::CommandBuffer::SetStencilTestEnable
688    */
689   void SetStencilTestEnable(bool stencilEnable) override;
690
691   /**
692    * @copydoc Dali::Graphics::CommandBuffer::SetStencilWriteMask
693    */
694   void SetStencilWriteMask(uint32_t writeMask) override;
695
696   /**
697    * @copydoc Dali::Graphics::CommandBuffer::SetStencilOp
698    */
699   void SetStencilOp(Graphics::StencilOp failOp,
700                     Graphics::StencilOp passOp,
701                     Graphics::StencilOp depthFailOp) override;
702
703   /**
704    * @copydoc Dali::Graphics::CommandBuffer::SetStencilFunc
705    */
706   void SetStencilFunc(Graphics::CompareOp compareOp,
707                       uint32_t            reference,
708                       uint32_t            compareMask) override;
709
710   /**
711    * @copydoc Dali::Graphics::CommandBuffer::SetDepthCompareOp
712    */
713   void SetDepthCompareOp(Graphics::CompareOp compareOp) override;
714
715   /**
716    * @copydoc Dali::Graphics::CommandBuffer::SetDepthTestEnable
717    */
718   void SetDepthTestEnable(bool depthTestEnable) override;
719
720   /**
721    * @copydoc Dali::Graphics::CommandBuffer::SetDepthWriteEnable
722    */
723   void SetDepthWriteEnable(bool depthWriteEnable) override;
724
725   /**
726    * @copydoc Dali::Graphics::CommandBuffer::ClearDepthBuffer
727    */
728   void ClearDepthBuffer() override;
729
730   /**
731    * @brief Presents specified render target
732    *
733    * @param[in] renderTarget Valid pointer to a RenderTarget
734    *
735    * It's internal command that schedules presentation of
736    * specified render target.
737    */
738   void PresentRenderTarget(GLES::RenderTarget* renderTarget);
739
740   [[nodiscard]] const std::vector<Command>& GetCommands() const;
741
742   /**
743    * @brief Destroy the associated resources
744    */
745   void DestroyResource() override;
746
747   /**
748    * @brief Initialize associated resources
749    */
750   bool InitializeResource() override;
751
752   /**
753    * @brief Add this resource to the discard queue
754    */
755   void DiscardResource() override;
756
757 private:
758   std::vector<Command> mCommands; ///< List of commands in this command buffer
759 };
760 } // namespace Dali::Graphics::GLES
761
762 #endif