+
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
+ {
+ // Process secondary command buffers
+ for(auto& buf : cmd.data.executeCommandBuffers.buffers)
+ {
+ ProcessCommandBuffer(*Uncast<TestGraphicsCommandBuffer>(buf));
+ }
+ break;
+ }
+ case CommandType::BEGIN_RENDER_PASS:
+ {
+ auto renderTarget = Uncast<TestGraphicsRenderTarget>(cmd.data.beginRenderPass.renderTarget);
+
+ if(renderTarget)
+ {
+ auto fb = renderTarget->mCreateInfo.framebuffer;
+ if(fb)
+ {
+ if(currentFramebuffer != fb)
+ {
+ currentFramebuffer = Uncast<TestGraphicsFramebuffer>(fb);
+ currentFramebuffer->Bind();
+ }
+ }
+ else
+ {
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+ }
+ else
+ {
+ mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ auto& clearValues = cmd.data.beginRenderPass.clearValues;
+ if(clearValues.size() > 0)
+ {
+ const auto renderPass = static_cast<TestGraphicsRenderPass*>(cmd.data.beginRenderPass.renderPass);
+ if(renderPass)
+ {
+ const auto& color0 = renderPass->attachments[0];
+ GLuint mask = 0;
+ if(color0.loadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ mask |= GL_COLOR_BUFFER_BIT;
+
+ // Set clear color (todo: cache it!)
+ // Something goes wrong here if Alpha mask is GL_TRUE
+ mGl.ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ mGl.ClearColor(clearValues[0].color.r,
+ clearValues[0].color.g,
+ clearValues[0].color.b,
+ clearValues[0].color.a);
+ }
+
+ // check for depth stencil
+ if(renderPass->attachments.size() > 1)
+ {
+ const auto& depthStencil = renderPass->attachments.back();
+ if(depthStencil.loadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ mGl.DepthMask(true);
+ uint32_t depthClearColor = 0u;
+ if(clearValues.size() == renderPass->attachments.size())
+ {
+ depthClearColor = clearValues.back().depthStencil.depth;
+ }
+ mGl.ClearDepthf(depthClearColor);
+ mask |= GL_DEPTH_BUFFER_BIT;
+ }
+ if(depthStencil.stencilLoadOp == Graphics::AttachmentLoadOp::CLEAR)
+ {
+ uint32_t stencilClearColor = 0u;
+ if(clearValues.size() == renderPass->attachments.size())
+ {
+ stencilClearColor = clearValues.back().depthStencil.stencil;
+ }
+ mGl.ClearStencil(stencilClearColor);
+ mGl.StencilMask(0xFF); // Clear all the bitplanes (assume 8)
+ mask |= GL_STENCIL_BUFFER_BIT;
+ }
+ }
+
+ if(mask != 0)
+ {
+ // Test scissor area and RT size
+ const auto& area = cmd.data.beginRenderPass.renderArea;
+ if(area.x == 0 &&
+ area.y == 0 &&
+ renderTarget &&
+ area.width == renderTarget->mCreateInfo.extent.width &&
+ area.height == renderTarget->mCreateInfo.extent.height)
+ {
+ mGl.Disable(GL_SCISSOR_TEST);
+ mGl.Clear(mask);
+ }
+ else
+ {
+ mGl.Enable(GL_SCISSOR_TEST);
+ mGl.Scissor(cmd.data.beginRenderPass.renderArea.x, cmd.data.beginRenderPass.renderArea.y, cmd.data.beginRenderPass.renderArea.width, cmd.data.beginRenderPass.renderArea.height);
+ mGl.Clear(mask);
+ mGl.Disable(GL_SCISSOR_TEST);
+ }
+ }
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG(0 && "BeginRenderPass has no render pass");
+ }
+ }
+ break;
+ }
+ case CommandType::END_RENDER_PASS:
+ {
+ if(cmd.data.endRenderPass.syncObject != nullptr)
+ {
+ auto syncObject = Uncast<TestGraphicsSyncObject>(cmd.data.endRenderPass.syncObject);
+ syncObject->InitializeResource(); // create the sync object.
+ }
+ break;
+ }
+ }
+ }
+}
+
+void TestGraphicsController::BindPipeline(TestGraphicsPipeline* pipeline)
+{
+ auto& vi = pipeline->vertexInputState;
+ for(auto& attribute : vi.attributes)
+ {
+ mGl.EnableVertexAttribArray(attribute.location);
+ uint32_t attributeOffset = attribute.offset;
+ GLsizei stride = vi.bufferBindings[attribute.binding].stride;
+
+ mGl.VertexAttribPointer(attribute.location,
+ GetNumComponents(attribute.format),
+ GetGlType(attribute.format),
+ GL_FALSE, // Not normalized
+ stride,
+ reinterpret_cast<void*>(attributeOffset));
+ }
+
+ // Cull face setup
+ auto& rasterizationState = pipeline->rasterizationState;
+ if(rasterizationState.cullMode == Graphics::CullMode::NONE)
+ {
+ mGl.Disable(GL_CULL_FACE);
+ }
+ else
+ {
+ mGl.Enable(GL_CULL_FACE);
+ mGl.CullFace(GetCullFace(rasterizationState.cullMode));
+ }
+
+ mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
+
+ // Blending setup
+ auto& colorBlendState = pipeline->colorBlendState;
+ if(colorBlendState.blendEnable)
+ {
+ mGl.Enable(GL_BLEND);
+
+ mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
+ GetBlendFactor(colorBlendState.dstColorBlendFactor),
+ GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
+ GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
+ if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+ {
+ mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
+ }
+ else
+ {
+ mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));