Added RenderPass and RenderTarget support
[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 };
55
56 /**
57  * @brief Helper function to invoke destructor on anonymous struct
58  */
59 template<class T>
60 static void InvokeDestructor(T& object)
61 {
62   object.~T();
63 }
64
65 /**
66  * Command structure allocates memory to store a single command
67  */
68 struct Command
69 {
70   Command() = delete;
71
72   Command(CommandType commandType)
73   {
74     type = commandType;
75     switch(type)
76     {
77       case CommandType::BIND_VERTEX_BUFFERS:
78       {
79         new(&bindVertexBuffers) decltype(bindVertexBuffers);
80         break;
81       }
82       case CommandType::BIND_TEXTURES:
83       {
84         new(&bindTextures) decltype(bindTextures);
85         break;
86       }
87       case CommandType::BEGIN_RENDERPASS:
88       {
89         // run destructor
90         new(&beginRenderPass) decltype(beginRenderPass);
91         break;
92       }
93       default:
94       {
95       }
96     }
97   }
98
99   ~Command()
100   {
101     switch(type)
102     {
103       case CommandType::BIND_VERTEX_BUFFERS:
104       {
105         InvokeDestructor(bindVertexBuffers);
106         break;
107       }
108       case CommandType::BIND_TEXTURES:
109       {
110         InvokeDestructor(bindTextures);
111         break;
112       }
113       case CommandType::BEGIN_RENDERPASS:
114       {
115         // run destructor
116         InvokeDestructor(beginRenderPass);
117         break;
118       }
119       default:
120       {
121       }
122     }
123   }
124
125   /**
126    * @brief Copy constructor
127    * @param[in] rhs Command
128    */
129   Command(const Command& rhs)
130   {
131     switch(rhs.type)
132     {
133       case CommandType::BIND_VERTEX_BUFFERS:
134       {
135         new(&bindVertexBuffers) decltype(bindVertexBuffers);
136         bindVertexBuffers = rhs.bindVertexBuffers;
137         break;
138       }
139       case CommandType::BIND_INDEX_BUFFER:
140       {
141         bindIndexBuffer = rhs.bindIndexBuffer;
142         break;
143       }
144       case CommandType::BIND_SAMPLERS:
145       {
146         bindSamplers = rhs.bindSamplers;
147         break;
148       }
149       case CommandType::BIND_TEXTURES:
150       {
151         new(&bindTextures) decltype(bindTextures);
152         bindTextures = rhs.bindTextures;
153         break;
154       }
155       case CommandType::BIND_PIPELINE:
156       {
157         bindPipeline = rhs.bindPipeline;
158         break;
159       }
160       case CommandType::BIND_UNIFORM_BUFFER:
161       {
162         bindUniformBuffers = rhs.bindUniformBuffers;
163         break;
164       }
165       case CommandType::DRAW:
166       {
167         draw.type = rhs.draw.type;
168         draw.draw = rhs.draw.draw;
169         break;
170       }
171       case CommandType::DRAW_INDEXED:
172       {
173         draw.type        = rhs.draw.type;
174         draw.drawIndexed = rhs.draw.drawIndexed;
175         break;
176       }
177       case CommandType::DRAW_INDEXED_INDIRECT:
178       {
179         draw.type                = rhs.draw.type;
180         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
181         break;
182       }
183       case CommandType::BEGIN_RENDERPASS:
184       {
185         new(&beginRenderPass) BeginRenderPassDescriptor(rhs.beginRenderPass);
186         break;
187       }
188       case CommandType::END_RENDERPASS:
189       {
190         break;
191       }
192       case CommandType::EXECUTE_COMMAND_BUFFERS:
193       {
194         executeCommandBuffers = rhs.executeCommandBuffers;
195         break;
196       }
197       case CommandType::FLUSH:
198       {
199         // Nothing to do
200         break;
201       }
202       case CommandType::SET_SCISSOR:
203       {
204         scissor.region = rhs.scissor.region;
205         break;
206       }
207       case CommandType::SET_SCISSOR_TEST:
208       {
209         scissorTest.enable = rhs.scissorTest.enable;
210         break;
211       }
212       case CommandType::SET_VIEWPORT:
213       {
214         viewport.region = rhs.viewport.region;
215         break;
216       }
217     }
218     type = rhs.type;
219   }
220
221   /**
222    * @brief Copy constructor
223    * @param[in] rhs Command
224    */
225   Command(Command&& rhs) noexcept
226   {
227     switch(rhs.type)
228     {
229       case CommandType::BIND_VERTEX_BUFFERS:
230       {
231         new(&bindVertexBuffers) decltype(bindVertexBuffers);
232         bindVertexBuffers = std::move(rhs.bindVertexBuffers);
233         break;
234       }
235       case CommandType::BIND_INDEX_BUFFER:
236       {
237         bindIndexBuffer = rhs.bindIndexBuffer;
238         break;
239       }
240       case CommandType::BIND_UNIFORM_BUFFER:
241       {
242         bindUniformBuffers = std::move(rhs.bindUniformBuffers);
243         break;
244       }
245       case CommandType::BIND_SAMPLERS:
246       {
247         bindSamplers = std::move(rhs.bindSamplers);
248         break;
249       }
250       case CommandType::BIND_TEXTURES:
251       {
252         new(&bindTextures) decltype(bindTextures);
253         bindTextures = std::move(rhs.bindTextures);
254         break;
255       }
256       case CommandType::BIND_PIPELINE:
257       {
258         bindPipeline = rhs.bindPipeline;
259         break;
260       }
261       case CommandType::DRAW:
262       {
263         draw.type = rhs.draw.type;
264         draw.draw = rhs.draw.draw;
265         break;
266       }
267       case CommandType::DRAW_INDEXED:
268       {
269         draw.type        = rhs.draw.type;
270         draw.drawIndexed = rhs.draw.drawIndexed;
271         break;
272       }
273       case CommandType::DRAW_INDEXED_INDIRECT:
274       {
275         draw.type                = rhs.draw.type;
276         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
277         break;
278       }
279       case CommandType::BEGIN_RENDERPASS:
280       {
281         new(&beginRenderPass) BeginRenderPassDescriptor(std::move(rhs.beginRenderPass));
282         break;
283       }
284       case CommandType::END_RENDERPASS:
285       {
286         break;
287       }
288       case CommandType::EXECUTE_COMMAND_BUFFERS:
289       {
290         executeCommandBuffers = std::move(rhs.executeCommandBuffers);
291         break;
292       }
293       case CommandType::FLUSH:
294       {
295         // Nothing to do
296         break;
297       }
298       case CommandType::SET_SCISSOR:
299       {
300         scissor.region = rhs.scissor.region;
301         break;
302       }
303       case CommandType::SET_SCISSOR_TEST:
304       {
305         scissorTest.enable = rhs.scissorTest.enable;
306         break;
307       }
308       case CommandType::SET_VIEWPORT:
309       {
310         viewport.region = rhs.viewport.region;
311         break;
312       }
313     }
314     type = rhs.type;
315   }
316
317   CommandType type{CommandType::FLUSH}; ///< Type of command
318
319   union
320   {
321     struct
322     {
323       std::vector<Graphics::TextureBinding> textureBindings;
324     } bindTextures{};
325
326     // BindSampler command
327     struct
328     {
329       std::vector<Graphics::SamplerBinding> samplerBindings;
330     } bindSamplers;
331
332     struct
333     {
334       using Binding = GLES::VertexBufferBindingDescriptor;
335       std::vector<Binding> vertexBufferBindings;
336     } bindVertexBuffers;
337
338     struct : public IndexBufferBindingDescriptor
339     {
340     } bindIndexBuffer;
341
342     struct
343     {
344       std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
345       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
346     } bindUniformBuffers;
347
348     struct
349     {
350       const GLES::Pipeline* pipeline{nullptr};
351     } bindPipeline;
352
353     struct : public DrawCallDescriptor
354     {
355     } draw;
356
357     struct
358     {
359       Graphics::Rect2D region;
360     } scissor;
361
362     struct
363     {
364       bool enable;
365     } scissorTest;
366
367     struct
368     {
369       Graphics::Viewport region;
370     } viewport;
371
372     struct BeginRenderPassDescriptor
373       beginRenderPass;
374
375     struct
376     {
377     } endRenderPass;
378
379     struct
380     {
381       std::vector<GLES::CommandBuffer*> buffers;
382     } executeCommandBuffers;
383   };
384 };
385
386 using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::CommandBufferCreateInfo>;
387
388 class CommandBuffer : public CommandBufferResource
389 {
390 public:
391   CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
392
393   ~CommandBuffer() override;
394
395   void BindVertexBuffers(uint32_t                             firstBinding,
396                          std::vector<const Graphics::Buffer*> buffers,
397                          std::vector<uint32_t>                offsets) override;
398
399   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
400
401   void BindPipeline(const Graphics::Pipeline& pipeline) override;
402
403   void BindTextures(std::vector<TextureBinding>& textureBindings) override;
404
405   void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
406
407   void BindPushConstants(void*    data,
408                          uint32_t size,
409                          uint32_t binding) override;
410
411   void BindIndexBuffer(const Graphics::Buffer& buffer,
412                        uint32_t                offset,
413                        Format                  format) override;
414
415   void BeginRenderPass(
416     Graphics::RenderPass*   renderPass,
417     Graphics::RenderTarget* renderTarget,
418     Extent2D                renderArea,
419     std::vector<ClearValue> clearValues) override;
420
421   /**
422    * @brief Ends current render pass
423    *
424    * This command must be issued in order to finalize the render pass.
425    * It's up to the implementation whether anything has to be done but
426    * the Controller may use end RP marker in order to resolve resource
427    * dependencies (for example, to know when target texture is ready
428    * before passing it to another render pass).
429    */
430   void EndRenderPass() override;
431
432   void ExecuteCommandBuffers(std::vector<Graphics::CommandBuffer*>&& commandBuffers) override;
433
434   void Draw(
435     uint32_t vertexCount,
436     uint32_t instanceCount,
437     uint32_t firstVertex,
438     uint32_t firstInstance) override;
439
440   void DrawIndexed(
441     uint32_t indexCount,
442     uint32_t instanceCount,
443     uint32_t firstIndex,
444     int32_t  vertexOffset,
445     uint32_t firstInstance) override;
446
447   void DrawIndexedIndirect(
448     Graphics::Buffer& buffer,
449     uint32_t          offset,
450     uint32_t          drawCount,
451     uint32_t          stride) override;
452
453   void Reset() override;
454
455   void SetScissor(Graphics::Rect2D value) override;
456
457   void SetScissorTestEnable(bool value) override;
458
459   void SetViewport(Viewport value) override;
460
461   void SetViewportEnable(bool value) override;
462
463   [[nodiscard]] const std::vector<Command>& GetCommands() const;
464
465   void DestroyResource() override;
466   bool InitializeResource() override;
467
468   void DiscardResource() override;
469
470 private:
471   std::vector<Command> mCommands;
472 };
473 } // namespace Dali::Graphics::GLES
474
475 #endif