Adding Depth/Stencil implementation
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-command-buffer.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "gles-graphics-command-buffer.h"
20
21 // INTERNAL INCLUDES
22 #include "egl-graphics-controller.h"
23 #include "gles-graphics-buffer.h"
24 #include "gles-graphics-framebuffer.h"
25 #include "gles-graphics-pipeline.h"
26 #include "gles-graphics-render-pass.h"
27 #include "gles-graphics-render-target.h"
28 #include "gles-graphics-texture.h"
29
30 namespace Dali::Graphics::GLES
31 {
32 CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
33 : CommandBufferResource(createInfo, controller)
34 {
35 }
36
37 CommandBuffer::~CommandBuffer() = default;
38
39 void CommandBuffer::BindVertexBuffers(uint32_t                             firstBinding,
40                                       std::vector<const Graphics::Buffer*> buffers,
41                                       std::vector<uint32_t>                offsets)
42 {
43   mCommands.emplace_back(CommandType::BIND_VERTEX_BUFFERS);
44   auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
45   if(bindings.size() < firstBinding + buffers.size())
46   {
47     bindings.resize(firstBinding + buffers.size());
48     auto index = firstBinding;
49     for(auto& buf : buffers)
50     {
51       bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
52       bindings[index].offset = offsets[index - firstBinding];
53       index++;
54     }
55   }
56 }
57
58 void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings)
59 {
60   mCommands.emplace_back(CommandType::BIND_UNIFORM_BUFFER);
61   auto& cmd     = mCommands.back();
62   auto& bindCmd = cmd.bindUniformBuffers;
63   for(const auto& binding : bindings)
64   {
65     if(binding.buffer)
66     {
67       auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
68       if(glesBuffer->IsCPUAllocated()) // standalone uniforms
69       {
70         bindCmd.standaloneUniformsBufferBinding.buffer   = glesBuffer;
71         bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
72         bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
73         bindCmd.standaloneUniformsBufferBinding.emulated = true;
74       }
75       else // Bind regular UBO
76       {
77         // resize binding slots
78         if(binding.binding >= bindCmd.uniformBufferBindings.size())
79         {
80           bindCmd.uniformBufferBindings.resize(binding.binding + 1);
81         }
82         auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
83         slot.buffer   = glesBuffer;
84         slot.offset   = binding.offset;
85         slot.binding  = binding.binding;
86         slot.emulated = false;
87       }
88     }
89   }
90 }
91
92 void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
93 {
94   mCommands.emplace_back(CommandType::BIND_PIPELINE);
95   mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
96 }
97
98 void CommandBuffer::BindTextures(std::vector<TextureBinding>& textureBindings)
99 {
100   mCommands.emplace_back(CommandType::BIND_TEXTURES);
101   mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
102 }
103
104 void CommandBuffer::BindSamplers(std::vector<SamplerBinding>& samplerBindings)
105 {
106   mCommands.emplace_back(CommandType::BIND_SAMPLERS);
107   mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
108 }
109
110 void CommandBuffer::BindPushConstants(void*    data,
111                                       uint32_t size,
112                                       uint32_t binding)
113 {
114 }
115
116 void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
117                                     uint32_t                offset,
118                                     Format                  format)
119 {
120   mCommands.emplace_back(CommandType::BIND_INDEX_BUFFER);
121   mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
122   mCommands.back().bindIndexBuffer.offset = offset;
123   mCommands.back().bindIndexBuffer.format = format;
124 }
125
126 void CommandBuffer::BeginRenderPass(
127   Graphics::RenderPass*   renderPass,
128   Graphics::RenderTarget* renderTarget,
129   Rect2D                  renderArea,
130   std::vector<ClearValue> clearValues)
131 {
132   mCommands.emplace_back(CommandType::BEGIN_RENDERPASS);
133   auto& cmd                        = mCommands.back();
134   cmd.beginRenderPass.renderPass   = static_cast<GLES::RenderPass*>(renderPass);
135   cmd.beginRenderPass.renderTarget = static_cast<GLES::RenderTarget*>(renderTarget);
136   cmd.beginRenderPass.renderArea   = renderArea;
137   cmd.beginRenderPass.clearValues  = clearValues;
138 }
139
140 void CommandBuffer::EndRenderPass()
141 {
142   mCommands.emplace_back(CommandType::END_RENDERPASS);
143 }
144
145 void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
146 {
147   mCommands.emplace_back(CommandType::EXECUTE_COMMAND_BUFFERS);
148   auto& cmd = mCommands.back();
149   cmd.executeCommandBuffers.buffers.reserve(commandBuffers.size());
150   for(auto&& item : commandBuffers)
151   {
152     cmd.executeCommandBuffers.buffers.emplace_back(static_cast<const GLES::CommandBuffer*>(item));
153   }
154 }
155
156 void CommandBuffer::Draw(
157   uint32_t vertexCount,
158   uint32_t instanceCount,
159   uint32_t firstVertex,
160   uint32_t firstInstance)
161 {
162   mCommands.emplace_back(CommandType::DRAW);
163   auto& cmd              = mCommands.back().draw;
164   cmd.type               = DrawCallDescriptor::Type::DRAW;
165   cmd.draw.vertexCount   = vertexCount;
166   cmd.draw.instanceCount = instanceCount;
167   cmd.draw.firstInstance = firstInstance;
168   cmd.draw.firstVertex   = firstVertex;
169 }
170
171 void CommandBuffer::DrawIndexed(
172   uint32_t indexCount,
173   uint32_t instanceCount,
174   uint32_t firstIndex,
175   int32_t  vertexOffset,
176   uint32_t firstInstance)
177 {
178   mCommands.emplace_back(CommandType::DRAW_INDEXED);
179   auto& cmd                     = mCommands.back().draw;
180   cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
181   cmd.drawIndexed.firstIndex    = firstIndex;
182   cmd.drawIndexed.firstInstance = firstInstance;
183   cmd.drawIndexed.indexCount    = indexCount;
184   cmd.drawIndexed.vertexOffset  = vertexOffset;
185   cmd.drawIndexed.instanceCount = instanceCount;
186 }
187
188 void CommandBuffer::DrawIndexedIndirect(
189   Graphics::Buffer& buffer,
190   uint32_t          offset,
191   uint32_t          drawCount,
192   uint32_t          stride)
193 {
194   mCommands.emplace_back(CommandType::DRAW_INDEXED_INDIRECT);
195   auto& cmd                         = mCommands.back().draw;
196   cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
197   cmd.drawIndexedIndirect.buffer    = static_cast<const GLES::Buffer*>(&buffer);
198   cmd.drawIndexedIndirect.offset    = offset;
199   cmd.drawIndexedIndirect.drawCount = drawCount;
200   cmd.drawIndexedIndirect.stride    = stride;
201 }
202
203 void CommandBuffer::Reset()
204 {
205   mCommands.clear();
206 }
207
208 void CommandBuffer::SetScissor(Graphics::Rect2D value)
209 {
210   mCommands.emplace_back(CommandType::SET_SCISSOR);
211   mCommands.back().scissor.region = value;
212 }
213
214 void CommandBuffer::SetScissorTestEnable(bool value)
215 {
216   mCommands.emplace_back(CommandType::SET_SCISSOR_TEST);
217   mCommands.back().scissorTest.enable = value;
218 }
219
220 void CommandBuffer::SetViewport(Viewport value)
221 {
222   mCommands.emplace_back(CommandType::SET_VIEWPORT);
223   mCommands.back().viewport.region = value;
224 }
225
226 void CommandBuffer::SetViewportEnable(bool value)
227 {
228   // There is no GL equivalent
229 }
230
231 void CommandBuffer::SetColorMask(bool enabled)
232 {
233   mCommands.emplace_back(CommandType::SET_COLOR_MASK);
234   auto& cmd = mCommands.back().colorMask;
235   ;
236   cmd.enabled = enabled;
237 }
238
239 void CommandBuffer::ClearStencilBuffer()
240 {
241   mCommands.emplace_back(CommandType::CLEAR_STENCIL_BUFFER);
242 }
243
244 void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
245 {
246   mCommands.emplace_back(CommandType::SET_STENCIL_TEST_ENABLE);
247   mCommands.back().stencilTest.enabled = stencilEnable;
248 }
249
250 void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
251 {
252   mCommands.emplace_back(CommandType::SET_STENCIL_WRITE_MASK);
253   mCommands.back().stencilWriteMask.mask = writeMask;
254 }
255
256 void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
257                                  Graphics::StencilOp passOp,
258                                  Graphics::StencilOp depthFailOp)
259 {
260   mCommands.emplace_back(CommandType::SET_STENCIL_OP);
261   auto& cmd       = mCommands.back().stencilOp;
262   cmd.failOp      = failOp;
263   cmd.passOp      = passOp;
264   cmd.depthFailOp = depthFailOp;
265 }
266
267 void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
268                                    uint32_t            reference,
269                                    uint32_t            compareMask)
270 {
271   mCommands.emplace_back(CommandType::SET_STENCIL_FUNC);
272   auto& cmd       = mCommands.back().stencilFunc;
273   cmd.compareOp   = compareOp;
274   cmd.compareMask = compareMask;
275   cmd.reference   = reference;
276 }
277
278 void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
279 {
280   mCommands.emplace_back(CommandType::SET_DEPTH_COMPARE_OP);
281   mCommands.back().depth.compareOp = compareOp;
282 }
283
284 void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
285 {
286   mCommands.emplace_back(CommandType::SET_DEPTH_TEST_ENABLE);
287   mCommands.back().depth.testEnabled = depthTestEnable;
288 }
289 void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
290 {
291   mCommands.emplace_back(CommandType::SET_DEPTH_WRITE_ENABLE);
292   mCommands.back().depth.writeEnabled = depthWriteEnable;
293 }
294 void CommandBuffer::ClearDepthBuffer()
295 {
296   mCommands.emplace_back(CommandType::CLEAR_DEPTH_BUFFER);
297 }
298
299 void CommandBuffer::PresentRenderTarget(GLES::RenderTarget* renderTarget)
300 {
301   mCommands.emplace_back(CommandType::PRESENT_RENDER_TARGET);
302   mCommands.back().presentRenderTarget.targetToPresent = renderTarget;
303 }
304
305 [[nodiscard]] const std::vector<Command>& CommandBuffer::GetCommands() const
306 {
307   return mCommands;
308 }
309
310 void CommandBuffer::DestroyResource()
311 {
312   // Nothing to do
313 }
314
315 bool CommandBuffer::InitializeResource()
316 {
317   // Nothing to do
318   return true;
319 }
320
321 void CommandBuffer::DiscardResource()
322 {
323   GetController().DiscardResource(this);
324 }
325
326 } // namespace Dali::Graphics::GLES