Adding Depth/Stencil implementation
[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   void BindVertexBuffers(uint32_t                             firstBinding,
564                          std::vector<const Graphics::Buffer*> buffers,
565                          std::vector<uint32_t>                offsets) override;
566
567   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
568
569   void BindPipeline(const Graphics::Pipeline& pipeline) override;
570
571   void BindTextures(std::vector<TextureBinding>& textureBindings) override;
572
573   void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
574
575   void BindPushConstants(void*    data,
576                          uint32_t size,
577                          uint32_t binding) override;
578
579   void BindIndexBuffer(const Graphics::Buffer& buffer,
580                        uint32_t                offset,
581                        Format                  format) override;
582
583   void BeginRenderPass(
584     Graphics::RenderPass*   renderPass,
585     Graphics::RenderTarget* renderTarget,
586     Rect2D                  renderArea,
587     std::vector<ClearValue> clearValues) override;
588
589   /**
590    * @brief Ends current render pass
591    *
592    * This command must be issued in order to finalize the render pass.
593    * It's up to the implementation whether anything has to be done but
594    * the Controller may use end RP marker in order to resolve resource
595    * dependencies (for example, to know when target texture is ready
596    * before passing it to another render pass).
597    */
598   void EndRenderPass() override;
599
600   void ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers) override;
601
602   void Draw(
603     uint32_t vertexCount,
604     uint32_t instanceCount,
605     uint32_t firstVertex,
606     uint32_t firstInstance) override;
607
608   void DrawIndexed(
609     uint32_t indexCount,
610     uint32_t instanceCount,
611     uint32_t firstIndex,
612     int32_t  vertexOffset,
613     uint32_t firstInstance) override;
614
615   void DrawIndexedIndirect(
616     Graphics::Buffer& buffer,
617     uint32_t          offset,
618     uint32_t          drawCount,
619     uint32_t          stride) override;
620
621   void Reset() override;
622
623   void SetScissor(Graphics::Rect2D value) override;
624
625   void SetScissorTestEnable(bool value) override;
626
627   void SetViewport(Viewport value) override;
628
629   void SetViewportEnable(bool value) override;
630
631   void SetColorMask(bool enabled) override;
632
633   void ClearStencilBuffer() override;
634
635   void SetStencilTestEnable(bool stencilEnable) override;
636
637   void SetStencilWriteMask(uint32_t writeMask) override;
638
639   void SetStencilOp(Graphics::StencilOp failOp,
640                     Graphics::StencilOp passOp,
641                     Graphics::StencilOp depthFailOp) override;
642
643   void SetStencilFunc(Graphics::CompareOp compareOp,
644                       uint32_t            reference,
645                       uint32_t            compareMask) override;
646
647   void SetDepthCompareOp(Graphics::CompareOp compareOp) override;
648
649   void SetDepthTestEnable(bool depthTestEnable) override;
650
651   void SetDepthWriteEnable(bool depthWriteEnable) override;
652
653   void ClearDepthBuffer() override;
654
655   /**
656    * @brief Presents specified render target
657    *
658    * @param[in] renderTarget Valid pointer to a RenderTarget
659    *
660    * It's internal command that schedules presentation of
661    * specified render target.
662    */
663   void PresentRenderTarget(GLES::RenderTarget* renderTarget);
664
665   [[nodiscard]] const std::vector<Command>& GetCommands() const;
666
667   void DestroyResource() override;
668   bool InitializeResource() override;
669
670   void DiscardResource() override;
671
672 private:
673   std::vector<Command> mCommands;
674 };
675 } // namespace Dali::Graphics::GLES
676
677 #endif