2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "gles-graphics-command-buffer.h"
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"
30 namespace Dali::Graphics::GLES
32 CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
33 : CommandBufferResource(createInfo, controller)
37 CommandBuffer::~CommandBuffer() = default;
39 void CommandBuffer::BindVertexBuffers(uint32_t firstBinding,
40 std::vector<const Graphics::Buffer*> buffers,
41 std::vector<uint32_t> offsets)
43 mCommands.emplace_back(CommandType::BIND_VERTEX_BUFFERS);
44 auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
45 if(bindings.size() < firstBinding + buffers.size())
47 bindings.resize(firstBinding + buffers.size());
48 auto index = firstBinding;
49 for(auto& buf : buffers)
51 bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
52 bindings[index].offset = offsets[index - firstBinding];
58 void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings)
60 mCommands.emplace_back(CommandType::BIND_UNIFORM_BUFFER);
61 auto& cmd = mCommands.back();
62 auto& bindCmd = cmd.bindUniformBuffers;
63 for(const auto& binding : bindings)
67 auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
68 if(glesBuffer->IsCPUAllocated()) // standalone uniforms
70 bindCmd.standaloneUniformsBufferBinding.buffer = glesBuffer;
71 bindCmd.standaloneUniformsBufferBinding.offset = binding.offset;
72 bindCmd.standaloneUniformsBufferBinding.binding = binding.binding;
73 bindCmd.standaloneUniformsBufferBinding.emulated = true;
75 else // Bind regular UBO
77 // resize binding slots
78 if(binding.binding >= bindCmd.uniformBufferBindings.size())
80 bindCmd.uniformBufferBindings.resize(binding.binding + 1);
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;
92 void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
94 mCommands.emplace_back(CommandType::BIND_PIPELINE);
95 mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
98 void CommandBuffer::BindTextures(std::vector<TextureBinding>& textureBindings)
100 mCommands.emplace_back(CommandType::BIND_TEXTURES);
101 mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
104 void CommandBuffer::BindSamplers(std::vector<SamplerBinding>& samplerBindings)
106 mCommands.emplace_back(CommandType::BIND_SAMPLERS);
107 mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
110 void CommandBuffer::BindPushConstants(void* data,
116 void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
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;
126 void CommandBuffer::BeginRenderPass(
127 Graphics::RenderPass* renderPass,
128 Graphics::RenderTarget* renderTarget,
130 std::vector<ClearValue> clearValues)
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;
140 void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
142 mCommands.emplace_back(CommandType::END_RENDERPASS);
143 auto& cmd = mCommands.back();
145 cmd.endRenderPass.syncObject = static_cast<GLES::SyncObject*>(syncObject);
148 void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
150 mCommands.emplace_back(CommandType::EXECUTE_COMMAND_BUFFERS);
151 auto& cmd = mCommands.back();
152 cmd.executeCommandBuffers.buffers.reserve(commandBuffers.size());
153 for(auto&& item : commandBuffers)
155 cmd.executeCommandBuffers.buffers.emplace_back(static_cast<const GLES::CommandBuffer*>(item));
159 void CommandBuffer::Draw(
160 uint32_t vertexCount,
161 uint32_t instanceCount,
162 uint32_t firstVertex,
163 uint32_t firstInstance)
165 mCommands.emplace_back(CommandType::DRAW);
166 auto& cmd = mCommands.back().draw;
167 cmd.type = DrawCallDescriptor::Type::DRAW;
168 cmd.draw.vertexCount = vertexCount;
169 cmd.draw.instanceCount = instanceCount;
170 cmd.draw.firstInstance = firstInstance;
171 cmd.draw.firstVertex = firstVertex;
174 void CommandBuffer::DrawIndexed(
176 uint32_t instanceCount,
178 int32_t vertexOffset,
179 uint32_t firstInstance)
181 mCommands.emplace_back(CommandType::DRAW_INDEXED);
182 auto& cmd = mCommands.back().draw;
183 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED;
184 cmd.drawIndexed.firstIndex = firstIndex;
185 cmd.drawIndexed.firstInstance = firstInstance;
186 cmd.drawIndexed.indexCount = indexCount;
187 cmd.drawIndexed.vertexOffset = vertexOffset;
188 cmd.drawIndexed.instanceCount = instanceCount;
191 void CommandBuffer::DrawIndexedIndirect(
192 Graphics::Buffer& buffer,
197 mCommands.emplace_back(CommandType::DRAW_INDEXED_INDIRECT);
198 auto& cmd = mCommands.back().draw;
199 cmd.type = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
200 cmd.drawIndexedIndirect.buffer = static_cast<const GLES::Buffer*>(&buffer);
201 cmd.drawIndexedIndirect.offset = offset;
202 cmd.drawIndexedIndirect.drawCount = drawCount;
203 cmd.drawIndexedIndirect.stride = stride;
206 void CommandBuffer::Reset()
211 void CommandBuffer::SetScissor(Graphics::Rect2D value)
213 mCommands.emplace_back(CommandType::SET_SCISSOR);
214 mCommands.back().scissor.region = value;
217 void CommandBuffer::SetScissorTestEnable(bool value)
219 mCommands.emplace_back(CommandType::SET_SCISSOR_TEST);
220 mCommands.back().scissorTest.enable = value;
223 void CommandBuffer::SetViewport(Viewport value)
225 mCommands.emplace_back(CommandType::SET_VIEWPORT);
226 mCommands.back().viewport.region = value;
229 void CommandBuffer::SetViewportEnable(bool value)
231 // There is no GL equivalent
234 void CommandBuffer::SetColorMask(bool enabled)
236 mCommands.emplace_back(CommandType::SET_COLOR_MASK);
237 auto& cmd = mCommands.back().colorMask;
239 cmd.enabled = enabled;
242 void CommandBuffer::ClearStencilBuffer()
244 mCommands.emplace_back(CommandType::CLEAR_STENCIL_BUFFER);
247 void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
249 mCommands.emplace_back(CommandType::SET_STENCIL_TEST_ENABLE);
250 mCommands.back().stencilTest.enabled = stencilEnable;
253 void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
255 mCommands.emplace_back(CommandType::SET_STENCIL_WRITE_MASK);
256 mCommands.back().stencilWriteMask.mask = writeMask;
259 void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
260 Graphics::StencilOp passOp,
261 Graphics::StencilOp depthFailOp)
263 mCommands.emplace_back(CommandType::SET_STENCIL_OP);
264 auto& cmd = mCommands.back().stencilOp;
267 cmd.depthFailOp = depthFailOp;
270 void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
272 uint32_t compareMask)
274 mCommands.emplace_back(CommandType::SET_STENCIL_FUNC);
275 auto& cmd = mCommands.back().stencilFunc;
276 cmd.compareOp = compareOp;
277 cmd.compareMask = compareMask;
278 cmd.reference = reference;
281 void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
283 mCommands.emplace_back(CommandType::SET_DEPTH_COMPARE_OP);
284 mCommands.back().depth.compareOp = compareOp;
287 void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
289 mCommands.emplace_back(CommandType::SET_DEPTH_TEST_ENABLE);
290 mCommands.back().depth.testEnabled = depthTestEnable;
292 void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
294 mCommands.emplace_back(CommandType::SET_DEPTH_WRITE_ENABLE);
295 mCommands.back().depth.writeEnabled = depthWriteEnable;
297 void CommandBuffer::ClearDepthBuffer()
299 mCommands.emplace_back(CommandType::CLEAR_DEPTH_BUFFER);
302 void CommandBuffer::PresentRenderTarget(GLES::RenderTarget* renderTarget)
304 mCommands.emplace_back(CommandType::PRESENT_RENDER_TARGET);
305 mCommands.back().presentRenderTarget.targetToPresent = renderTarget;
308 [[nodiscard]] const std::vector<Command>& CommandBuffer::GetCommands() const
313 void CommandBuffer::DestroyResource()
318 bool CommandBuffer::InitializeResource()
324 void CommandBuffer::DiscardResource()
326 GetController().DiscardResource(this);
329 } // namespace Dali::Graphics::GLES