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