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