GLES Pipeline and draw call 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.h>
23
24 // INTERNAL INCLUDES
25 #include "egl-graphics-controller.h"
26 #include "gles-graphics-pipeline.h"
27 #include "gles-graphics-types.h"
28
29 namespace Dali::Graphics::GLES
30 {
31 class Texture;
32 class Buffer;
33 class Sampler;
34 class Pipeline;
35
36 enum class CommandType
37 {
38   FLUSH,
39   BIND_TEXTURES,
40   BIND_SAMPLERS,
41   BIND_VERTEX_BUFFERS,
42   BIND_INDEX_BUFFER,
43   BIND_PIPELINE,
44   DRAW,
45   DRAW_INDEXED,
46   DRAW_INDEXED_INDIRECT
47 };
48
49 /**
50  * Command structure allocates memory to store a single command
51  */
52 struct Command
53 {
54   Command()
55   {
56   }
57
58   ~Command()
59   {
60   }
61
62   /**
63    * @brief Copy constructor
64    * @param[in] rhs Command
65    */
66   Command(const Command& rhs)
67   {
68     switch(rhs.type)
69     {
70       case CommandType::BIND_VERTEX_BUFFERS:
71       {
72         bindVertexBuffers = rhs.bindVertexBuffers;
73         break;
74       }
75       case CommandType::BIND_INDEX_BUFFER:
76       {
77         bindIndexBuffer = rhs.bindIndexBuffer;
78         break;
79       }
80       case CommandType::BIND_SAMPLERS:
81       {
82         bindSamplers = rhs.bindSamplers;
83         break;
84       }
85       case CommandType::BIND_TEXTURES:
86       {
87         bindTextures = rhs.bindTextures;
88         break;
89       }
90       case CommandType::BIND_PIPELINE:
91       {
92         bindPipeline = rhs.bindPipeline;
93         break;
94       }
95       case CommandType::DRAW:
96       {
97         draw.type = rhs.draw.type;
98         draw.draw = rhs.draw.draw;
99         break;
100       }
101       case CommandType::DRAW_INDEXED:
102       {
103         draw.type        = rhs.draw.type;
104         draw.drawIndexed = rhs.draw.drawIndexed;
105         break;
106       }
107       case CommandType::DRAW_INDEXED_INDIRECT:
108       {
109         draw.type                = rhs.draw.type;
110         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
111         break;
112       }
113       case CommandType::FLUSH:
114       {
115         // Nothing to do
116         break;
117       }
118     }
119     type = rhs.type;
120   }
121
122   /**
123    * @brief Copy constructor
124    * @param[in] rhs Command
125    */
126   Command(Command&& rhs) noexcept
127   {
128     switch(rhs.type)
129     {
130       case CommandType::BIND_VERTEX_BUFFERS:
131       {
132         bindVertexBuffers = std::move(rhs.bindVertexBuffers);
133         break;
134       }
135       case CommandType::BIND_INDEX_BUFFER:
136       {
137         bindIndexBuffer = rhs.bindIndexBuffer;
138         break;
139       }
140       case CommandType::BIND_SAMPLERS:
141       {
142         bindSamplers = std::move(rhs.bindSamplers);
143         break;
144       }
145       case CommandType::BIND_TEXTURES:
146       {
147         bindTextures = std::move(rhs.bindTextures);
148         break;
149       }
150       case CommandType::BIND_PIPELINE:
151       {
152         bindPipeline = rhs.bindPipeline;
153         break;
154       }
155       case CommandType::DRAW:
156       {
157         draw.type = rhs.draw.type;
158         draw.draw = rhs.draw.draw;
159         break;
160       }
161       case CommandType::DRAW_INDEXED:
162       {
163         draw.type        = rhs.draw.type;
164         draw.drawIndexed = rhs.draw.drawIndexed;
165         break;
166       }
167       case CommandType::DRAW_INDEXED_INDIRECT:
168       {
169         draw.type                = rhs.draw.type;
170         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
171         break;
172       }
173       case CommandType::FLUSH:
174       {
175         // Nothing to do
176         break;
177       }
178     }
179     type = rhs.type;
180   }
181
182   CommandType type{CommandType::FLUSH}; ///< Type of command
183
184   union
185   {
186     struct
187     {
188       std::vector<Graphics::TextureBinding> textureBindings;
189     } bindTextures{};
190
191     // BindSampler command
192     struct
193     {
194       std::vector<Graphics::SamplerBinding> samplerBindings;
195     } bindSamplers;
196
197     struct
198     {
199       using Binding = GLES::VertexBufferBindingDescriptor;
200       std::vector<Binding> vertexBufferBindings;
201     } bindVertexBuffers;
202
203     struct : public IndexBufferBindingDescriptor
204     {
205     } bindIndexBuffer;
206
207     struct
208     {
209       const GLES::Pipeline* pipeline{nullptr};
210     } bindPipeline;
211
212     struct : public DrawCallDescriptor
213     {
214     } draw;
215   };
216 };
217
218 using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::CommandBufferCreateInfo>;
219
220 class CommandBuffer : public CommandBufferResource
221 {
222 public:
223   CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
224   : CommandBufferResource(createInfo, controller)
225   {
226   }
227
228   ~CommandBuffer() override = default;
229
230   void BindVertexBuffers(uint32_t                             firstBinding,
231                          std::vector<const Graphics::Buffer*> buffers,
232                          std::vector<uint32_t>                offsets) override
233   {
234     mCommands.emplace_back();
235     mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
236     auto& bindings        = mCommands.back().bindVertexBuffers.vertexBufferBindings;
237     if(bindings.size() < firstBinding + buffers.size())
238     {
239       bindings.resize(firstBinding + buffers.size());
240       auto index = firstBinding;
241       for(auto& buf : buffers)
242       {
243         bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
244         bindings[index].offset = offsets[index - firstBinding];
245         index++;
246       }
247     }
248   }
249
250   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
251   {
252   }
253
254   void BindPipeline(const Graphics::Pipeline& pipeline) override
255   {
256     mCommands.emplace_back();
257     mCommands.back().type                  = CommandType::BIND_PIPELINE;
258     mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
259   }
260
261   void BindTextures(std::vector<TextureBinding>& textureBindings) override
262   {
263     mCommands.emplace_back();
264     mCommands.back().type                         = CommandType::BIND_TEXTURES;
265     mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
266   }
267
268   void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override
269   {
270     mCommands.emplace_back();
271     mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
272   }
273
274   void BindPushConstants(void*    data,
275                          uint32_t size,
276                          uint32_t binding) override
277   {
278   }
279
280   void BindIndexBuffer(const Graphics::Buffer& buffer,
281                        uint32_t                offset,
282                        Format                  format) override
283   {
284     mCommands.emplace_back();
285     mCommands.back().type                   = CommandType::BIND_INDEX_BUFFER;
286     mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
287     mCommands.back().bindIndexBuffer.offset = offset;
288     mCommands.back().bindIndexBuffer.format = format;
289   }
290
291   void BeginRenderPass(
292     Graphics::RenderPass&   renderPass,
293     Graphics::RenderTarget& renderTarget,
294     Extent2D                renderArea,
295     std::vector<ClearValue> clearValues) override
296   {
297   }
298
299   /**
300    * @brief Ends current render pass
301    *
302    * This command must be issued in order to finalize the render pass.
303    * It's up to the implementation whether anything has to be done but
304    * the Controller may use end RP marker in order to resolve resource
305    * dependencies (for example, to know when target texture is ready
306    * before passing it to another render pass).
307    */
308   void EndRenderPass() override
309   {
310   }
311
312   void Draw(
313     uint32_t vertexCount,
314     uint32_t instanceCount,
315     uint32_t firstVertex,
316     uint32_t firstInstance) override
317   {
318     mCommands.emplace_back();
319     mCommands.back().type  = CommandType::DRAW;
320     auto& cmd              = mCommands.back().draw;
321     cmd.type               = DrawCallDescriptor::Type::DRAW;
322     cmd.draw.vertexCount   = vertexCount;
323     cmd.draw.instanceCount = instanceCount;
324     cmd.draw.firstInstance = firstInstance;
325     cmd.draw.firstVertex   = firstVertex;
326   }
327
328   void DrawIndexed(
329     uint32_t indexCount,
330     uint32_t instanceCount,
331     uint32_t firstIndex,
332     int32_t  vertexOffset,
333     uint32_t firstInstance) override
334   {
335     mCommands.emplace_back();
336     mCommands.back().type         = CommandType::DRAW_INDEXED;
337     auto& cmd                     = mCommands.back().draw;
338     cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
339     cmd.drawIndexed.firstIndex    = firstIndex;
340     cmd.drawIndexed.firstInstance = firstInstance;
341     cmd.drawIndexed.indexCount    = indexCount;
342     cmd.drawIndexed.vertexOffset  = vertexOffset;
343     cmd.drawIndexed.instanceCount = instanceCount;
344   }
345
346   void DrawIndexedIndirect(
347     Graphics::Buffer& buffer,
348     uint32_t          offset,
349     uint32_t          drawCount,
350     uint32_t          stride) override
351   {
352     mCommands.emplace_back();
353     mCommands.back().type             = CommandType::DRAW_INDEXED_INDIRECT;
354     auto& cmd                         = mCommands.back().draw;
355     cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
356     cmd.drawIndexedIndirect.buffer    = static_cast<const GLES::Buffer*>(&buffer);
357     cmd.drawIndexedIndirect.offset    = offset;
358     cmd.drawIndexedIndirect.drawCount = drawCount;
359     cmd.drawIndexedIndirect.stride    = stride;
360   }
361
362   void Reset(Graphics::CommandBuffer& commandBuffer) override
363   {
364     mCommands.clear();
365   }
366
367   void SetScissor(Extent2D value) override
368   {
369   }
370
371   void SetScissorTestEnable(bool value) override
372   {
373   }
374
375   void SetViewport(Viewport value) override
376   {
377   }
378
379   void SetViewportEnable(bool value) override
380   {
381   }
382
383   [[nodiscard]] const std::vector<Command>& GetCommands() const
384   {
385     return mCommands;
386   }
387
388   void DestroyResource() override
389   {
390     // Nothing to do
391   }
392
393   bool InitializeResource() override
394   {
395     // Nothing to do
396     return true;
397   }
398
399   void DiscardResource() override
400   {
401     // Nothing to do
402   }
403
404 private:
405   std::vector<Command> mCommands;
406 };
407 } // namespace Dali::Graphics::GLES
408
409 #endif