X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=automated-tests%2Fsrc%2Fdali-toolkit%2Fdali-toolkit-test-utils%2Ftest-graphics-controller.cpp;h=e398236f97c6dedbb37ed08db23dce26eebcc895;hp=41d13c9869e8095a99332df52c2fa7f36830c086;hb=dc96b027c0d06fae091bde3f877b32a379ca2894;hpb=f1150c8895518f78f8c2b9c4cb1464ffaffdf16e diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp index 41d13c9..e398236 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp @@ -18,8 +18,12 @@ #include "test-graphics-buffer.h" #include "test-graphics-command-buffer.h" +#include "test-graphics-framebuffer.h" #include "test-graphics-reflection.h" +#include "test-graphics-render-pass.h" +#include "test-graphics-render-target.h" #include "test-graphics-sampler.h" +#include "test-graphics-shader.h" #include "test-graphics-texture.h" #include @@ -29,30 +33,6 @@ namespace Dali { -template -T* Uncast(const Graphics::CommandBuffer* object) -{ - return const_cast(static_cast(object)); -} - -template -T* Uncast(const Graphics::Texture* object) -{ - return const_cast(static_cast(object)); -} - -template -T* Uncast(const Graphics::Sampler* object) -{ - return const_cast(static_cast(object)); -} - -template -T* Uncast(const Graphics::Buffer* object) -{ - return const_cast(static_cast(object)); -} - std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo) { return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size; @@ -166,68 +146,34 @@ std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& cre return o; } -class TestGraphicsMemory : public Graphics::Memory +std::ostream& operator<<(std::ostream& o, const Graphics::ColorAttachment& colorAttachment) { -public: - TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize) - : mCallStack(callStack), - mBuffer(buffer), - mMappedOffset(mappedOffset), - mMappedSize(mappedSize) - { - } - - void* LockRegion(uint32_t offset, uint32_t size) override - { - std::ostringstream o; - o << offset << ", " << size; - mCallStack.PushCall("Memory::LockRegion", o.str()); - - if(offset > mMappedOffset + mMappedSize || - size + offset > mMappedOffset + mMappedSize) - { - fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds"); - mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing - } - mLockedOffset = offset; - mLockedSize = size; - return &mBuffer.memory[mMappedOffset + offset]; - } + o << "attachmentId:" << colorAttachment.attachmentId + << " layerId:" << colorAttachment.layerId + << " levelId:" << colorAttachment.levelId + << " texture:" << colorAttachment.texture; + return o; +} - void Unlock(bool flush) override - { - mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush")); - if(flush) - { - Flush(); - } - } +std::ostream& operator<<(std::ostream& o, const Graphics::DepthStencilAttachment& depthStencilAttachment) +{ + o << "depthTexture:" << depthStencilAttachment.depthTexture + << "depthLevel:" << depthStencilAttachment.depthLevel + << "stencilTexture:" << depthStencilAttachment.stencilTexture + << "stencilLevel:" << depthStencilAttachment.stencilLevel; + return o; +} - void Flush() override +std::ostream& operator<<(std::ostream& o, const Graphics::FramebufferCreateInfo& createInfo) +{ + o << "colorAttachments:"; + for(auto i = 0u; i < createInfo.colorAttachments.size(); ++i) { - mCallStack.PushCall("Memory::Flush", ""); - mBuffer.Bind(); - mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize); - mBuffer.Unbind(); + o << "[" << i << "]=" << createInfo.colorAttachments[i] << " "; } - - TraceCallStack& mCallStack; - TestGraphicsBuffer& mBuffer; - uint32_t mMappedOffset; - uint32_t mMappedSize; - uint32_t mLockedOffset; - uint32_t mLockedSize; -}; - -TestGraphicsController::TestGraphicsController() -: mCallStack(true, "TestGraphicsController."), - mCommandBufferCallStack(true, "TestCommandBuffer.") -{ - mCallStack.Enable(true); - mCommandBufferCallStack.Enable(true); - auto& trace = mGl.GetTextureTrace(); - trace.Enable(true); - trace.EnableLogging(true); + o << "depthStencilAttachment:" << createInfo.depthStencilAttachment; + o << "size: " << createInfo.size; + return o; } int GetNumComponents(Graphics::VertexInputFormat vertexFormat) @@ -438,134 +384,405 @@ GLenum GetBlendOp(Graphics::BlendOp blendOp) return op; } +class TestGraphicsMemory : public Graphics::Memory +{ +public: + TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize) + : mCallStack(callStack), + mBuffer(buffer), + mMappedOffset(mappedOffset), + mMappedSize(mappedSize), + mLockedOffset(0u), + mLockedSize(0u) + { + } + + void* LockRegion(uint32_t offset, uint32_t size) override + { + std::ostringstream o; + o << offset << ", " << size; + mCallStack.PushCall("Memory::LockRegion", o.str()); + + if(offset > mMappedOffset + mMappedSize || + size + offset > mMappedOffset + mMappedSize) + { + fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds"); + mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing + } + mLockedOffset = offset; + mLockedSize = size; + return &mBuffer.memory[mMappedOffset + offset]; + } + + void Unlock(bool flush) override + { + mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush")); + if(flush) + { + Flush(); + } + } + + void Flush() override + { + mCallStack.PushCall("Memory::Flush", ""); + mBuffer.Bind(); + mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize); + mBuffer.Unbind(); + } + + TraceCallStack& mCallStack; + TestGraphicsBuffer& mBuffer; + uint32_t mMappedOffset; + uint32_t mMappedSize; + uint32_t mLockedOffset; + uint32_t mLockedSize; +}; + +TestGraphicsController::TestGraphicsController() +: mCallStack(true, "TestGraphicsController."), + mCommandBufferCallStack(true, "TestCommandBuffer."), + mFrameBufferCallStack(true, "TestFrameBuffer.") +{ + mCallStack.Enable(true); + mCommandBufferCallStack.Enable(true); + auto& trace = mGl.GetTextureTrace(); + trace.Enable(true); + trace.EnableLogging(true); +} + void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) { TraceCallStack::NamedParams namedParams; namedParams["submitInfo"] << "cmdBuffer[" << submitInfo.cmdBuffer.size() << "], flags:" << std::hex << submitInfo.flags; - mCallStack.PushCall("Controller::SubmitCommandBuffers", "", namedParams); + mCallStack.PushCall("SubmitCommandBuffers", "", namedParams); + + mSubmitStack.emplace_back(submitInfo); for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer) { auto commandBuffer = Uncast(graphicsCommandBuffer); - for(auto& binding : commandBuffer->mTextureBindings) - { - if(binding.texture) - { - auto texture = Uncast(binding.texture); + ProcessCommandBuffer(*commandBuffer); + } +} - texture->Bind(binding.binding); +void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& commandBuffer) +{ + bool scissorEnabled = false; + TestGraphicsFramebuffer* currentFramebuffer{nullptr}; + TestGraphicsPipeline* currentPipeline{nullptr}; - if(binding.sampler) + for(auto& cmd : commandBuffer.GetCommands()) + { + // process command + switch(cmd.type) + { + case CommandType::FLUSH: + { + // Nothing to do here + break; + } + case CommandType::BIND_TEXTURES: + { + for(auto& binding : cmd.data.bindTextures.textureBindings) { - auto sampler = Uncast(binding.sampler); - if(sampler) + if(binding.texture) { - sampler->Apply(texture->GetTarget()); + auto texture = Uncast(binding.texture); + texture->Bind(binding.binding); + + if(binding.sampler) + { + auto sampler = Uncast(binding.sampler); + if(sampler) + { + sampler->Apply(texture->GetTarget()); + } + } + + texture->Prepare(); // Ensure native texture is ready } } - - texture->Prepare(); // Ensure native texture is ready + break; } - } - - // IndexBuffer binding, - auto& indexBufferBinding = commandBuffer->mIndexBufferBinding; - if(indexBufferBinding.buffer) - { - auto buffer = Uncast(indexBufferBinding.buffer); - buffer->Bind(); - } - - // VertexBuffer binding, - for(auto graphicsBuffer : commandBuffer->mVertexBufferBindings.buffers) - { - auto vertexBuffer = Uncast(graphicsBuffer); - vertexBuffer->Bind(); - } - - // Pipeline attribute setup - auto& vi = commandBuffer->mPipeline->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(attributeOffset)); - } + case CommandType::BIND_VERTEX_BUFFERS: + { + for(auto& binding : cmd.data.bindVertexBuffers.vertexBufferBindings) + { + auto graphicsBuffer = binding.buffer; + auto vertexBuffer = Uncast(graphicsBuffer); + vertexBuffer->Bind(); + } + break; + } + case CommandType::BIND_INDEX_BUFFER: + { + auto& indexBufferBinding = cmd.data.bindIndexBuffer; + if(indexBufferBinding.buffer) + { + auto buffer = Uncast(indexBufferBinding.buffer); + buffer->Bind(); + } + break; + } + case CommandType::BIND_UNIFORM_BUFFER: + { + auto& bindings = cmd.data.bindUniformBuffers; + auto buffer = bindings.standaloneUniformsBufferBinding; - // Cull face setup - auto& rasterizationState = commandBuffer->mPipeline->rasterizationState; - if(rasterizationState.cullMode == Graphics::CullMode::NONE) - { - mGl.Disable(GL_CULL_FACE); - } - else - { - mGl.Enable(GL_CULL_FACE); - mGl.CullFace(GetCullFace(rasterizationState.cullMode)); - } + // based on reflection, issue gl calls + buffer.buffer->BindAsUniformBuffer(static_cast(currentPipeline->programState.program)); + break; + } + case CommandType::BIND_SAMPLERS: + { + break; + } + case CommandType::BIND_PIPELINE: + { + currentPipeline = Uncast(cmd.data.bindPipeline.pipeline); - mGl.FrontFace(GetFrontFace(rasterizationState.frontFace)); - // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default), - // so it isn't present in the API (and won't have any tests!) + // Bind framebuffer if different. @todo Move to RenderPass + auto framebuffer = currentPipeline->framebufferState.framebuffer; + if(framebuffer && framebuffer != currentFramebuffer) + { + auto graphicsFramebuffer = Uncast(framebuffer); + graphicsFramebuffer->Bind(); + } + else + { + if(currentFramebuffer) + currentFramebuffer->Bind(); + else + mGl.BindFramebuffer(GL_FRAMEBUFFER, 0); + } + BindPipeline(currentPipeline); + break; + } + case CommandType::DRAW: + { + mGl.DrawArrays(GetTopology(currentPipeline->inputAssemblyState.topology), + 0, + cmd.data.draw.draw.vertexCount); + break; + } + case CommandType::DRAW_INDEXED: + { + mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology), + static_cast(cmd.data.draw.drawIndexed.indexCount), + GL_UNSIGNED_SHORT, + reinterpret_cast(cmd.data.draw.drawIndexed.firstIndex)); + break; + } + case CommandType::DRAW_INDEXED_INDIRECT: + { + mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology), + static_cast(cmd.data.draw.drawIndexed.indexCount), + GL_UNSIGNED_SHORT, + reinterpret_cast(cmd.data.draw.drawIndexed.firstIndex)); + break; + } + case CommandType::SET_SCISSOR: + { + if(scissorEnabled) + { + auto& rect = cmd.data.scissor.region; + mGl.Scissor(rect.x, rect.y, rect.width, rect.height); + } + break; + } + case CommandType::SET_SCISSOR_TEST: + { + if(cmd.data.scissorTest.enable) + { + mGl.Enable(GL_SCISSOR_TEST); + scissorEnabled = true; + } + else + { + mGl.Disable(GL_SCISSOR_TEST); + scissorEnabled = false; + } + break; + } + case CommandType::SET_VIEWPORT_TEST: + { + break; + } + case CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here? + { + auto& rect = cmd.data.viewport.region; + mGl.Viewport(rect.x, rect.y, rect.width, rect.height); + break; + } + case CommandType::EXECUTE_COMMAND_BUFFERS: + { + // Process secondary command buffers + for(auto& buf : cmd.data.executeCommandBuffers.buffers) + { + ProcessCommandBuffer(*static_cast(buf)); + } + break; + } + case CommandType::BEGIN_RENDER_PASS: + { + auto renderTarget = Uncast(cmd.data.beginRenderPass.renderTarget); - // Blending setup - auto& colorBlendState = commandBuffer->mPipeline->colorBlendState; - if(colorBlendState.blendEnable) - { - mGl.Enable(GL_BLEND); + if(renderTarget) + { + auto fb = renderTarget->mCreateInfo.framebuffer; + if(fb) + { + if(currentFramebuffer != fb) + { + currentFramebuffer = Uncast(fb); + currentFramebuffer->Bind(); + } + } + else + { + mGl.BindFramebuffer(GL_FRAMEBUFFER, 0); + } + } + else + { + mGl.BindFramebuffer(GL_FRAMEBUFFER, 0); + } - 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)); + auto& clearValues = cmd.data.beginRenderPass.clearValues; + if(clearValues.size() > 0) + { + const auto renderPass = static_cast(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) + { + mask |= GL_DEPTH_BUFFER_BIT; + } + if(depthStencil.stencilLoadOp == Graphics::AttachmentLoadOp::CLEAR) + { + 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 && + 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; } - else + case CommandType::END_RENDER_PASS: { - mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp)); + break; } - mGl.BlendColor(colorBlendState.blendConstants[0], - colorBlendState.blendConstants[1], - colorBlendState.blendConstants[2], - colorBlendState.blendConstants[3]); - } - else - { - mGl.Disable(GL_BLEND); } + } +} - // draw call - auto topology = commandBuffer->mPipeline->inputAssemblyState.topology; +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(attributeOffset)); + } - if(commandBuffer->drawCommand.drawType == TestGraphicsCommandBuffer::Draw::DrawType::Indexed) + // 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.DrawElements(GetTopology(topology), - static_cast(commandBuffer->drawCommand.u.indexedDraw.indexCount), - GL_UNSIGNED_SHORT, - reinterpret_cast(commandBuffer->drawCommand.u.indexedDraw.firstIndex)); + mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp)); } else { - mGl.DrawArrays(GetTopology(topology), 0, commandBuffer->drawCommand.u.unindexedDraw.vertexCount); - } - - // attribute clear - for(auto& attribute : vi.attributes) - { - mGl.DisableVertexAttribArray(attribute.location); + mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp)); } + mGl.BlendColor(colorBlendState.blendConstants[0], + colorBlendState.blendConstants[1], + colorBlendState.blendConstants[2], + colorBlendState.blendConstants[3]); } + else + { + mGl.Disable(GL_BLEND); + } + + auto* program = static_cast(pipeline->programState.program); + mGl.UseProgram(program->mImpl->mId); } /** @@ -576,7 +793,7 @@ void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderT { TraceCallStack::NamedParams namedParams; namedParams["renderTarget"] << std::hex << renderTarget; - mCallStack.PushCall("Controller::PresentRenderTarget", "", namedParams); + mCallStack.PushCall("PresentRenderTarget", "", namedParams); } /** @@ -584,7 +801,7 @@ void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderT */ void TestGraphicsController::WaitIdle() { - mCallStack.PushCall("Controller::WaitIdle", ""); + mCallStack.PushCall("WaitIdle", ""); } /** @@ -592,7 +809,7 @@ void TestGraphicsController::WaitIdle() */ void TestGraphicsController::Pause() { - mCallStack.PushCall("Controller::Pause", ""); + mCallStack.PushCall("Pause", ""); } /** @@ -600,7 +817,17 @@ void TestGraphicsController::Pause() */ void TestGraphicsController::Resume() { - mCallStack.PushCall("Controller::Resume", ""); + mCallStack.PushCall("Resume", ""); +} + +void TestGraphicsController::Shutdown() +{ + mCallStack.PushCall("Shutdown", ""); +} + +void TestGraphicsController::Destroy() +{ + mCallStack.PushCall("Destroy", ""); } void TestGraphicsController::UpdateTextures(const std::vector& updateInfoList, @@ -610,7 +837,7 @@ void TestGraphicsController::UpdateTextures(const std::vector TestGraphicsController::CreateBuffer(const { std::ostringstream oss; oss << "bufferCreateInfo:" << createInfo; - mCallStack.PushCall("Controller::CreateBuffer", oss.str()); + mCallStack.PushCall("CreateBuffer", oss.str()); return Graphics::MakeUnique(mCallStack, mGl, createInfo.size, createInfo.usage); } @@ -674,61 +901,103 @@ Graphics::UniquePtr TestGraphicsController::CreateComma { std::ostringstream oss; oss << "commandBufferCreateInfo:" << commandBufferCreateInfo; - mCallStack.PushCall("Controller::CreateCommandBuffer", oss.str()); + mCallStack.PushCall("CreateCommandBuffer", oss.str()); return Graphics::MakeUnique(mCommandBufferCallStack, mGl); } Graphics::UniquePtr TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr&& oldRenderPass) { - mCallStack.PushCall("Controller::CreateRenderPass", ""); - return nullptr; + mCallStack.PushCall("CreateRenderPass", ""); + return Graphics::MakeUnique(mGl, renderPassCreateInfo); } Graphics::UniquePtr TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr&& oldTexture) { TraceCallStack::NamedParams namedParams; namedParams["textureCreateInfo"] << textureCreateInfo; - mCallStack.PushCall("Controller::CreateTexture", namedParams.str(), namedParams); + mCallStack.PushCall("CreateTexture", namedParams.str(), namedParams); return Graphics::MakeUnique(mGl, textureCreateInfo); } -Graphics::UniquePtr TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr&& oldFramebuffer) +Graphics::UniquePtr TestGraphicsController::CreateFramebuffer( + const Graphics::FramebufferCreateInfo& createInfo, + Graphics::UniquePtr&& oldFramebuffer) { - mCallStack.PushCall("Controller::CreateFramebuffer", ""); - return nullptr; + TraceCallStack::NamedParams namedParams; + namedParams["framebufferCreateInfo"] << createInfo; + mCallStack.PushCall("Controller::CreateFramebuffer", namedParams.str(), namedParams); + + return Graphics::MakeUnique(mFrameBufferCallStack, mGl, createInfo); } Graphics::UniquePtr TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr&& oldPipeline) { - mCallStack.PushCall("Controller::CreatePipeline", ""); + mCallStack.PushCall("CreatePipeline", ""); return std::make_unique(mGl, pipelineCreateInfo); } +Graphics::UniquePtr TestGraphicsController::CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr&& oldProgram) +{ + mCallStack.PushCall("CreateProgram", ""); + + for(auto cacheEntry : mProgramCache) + { + bool found = true; + for(auto& shader : *(programCreateInfo.shaderState)) + { + auto graphicsShader = Uncast(shader.shader); + std::vector source; + source.resize(graphicsShader->mCreateInfo.sourceSize); + memcpy(&source[0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize); + + if(!std::equal(source.begin(), source.end(), cacheEntry.shaders[shader.pipelineStage].begin())) + { + found = false; + break; + } + } + if(found) + { + return Graphics::MakeUnique(cacheEntry.programImpl); + } + } + + mProgramCache.emplace_back(); + mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms); + for(auto& shader : *(programCreateInfo.shaderState)) + { + auto graphicsShader = Uncast(shader.shader); + mProgramCache.back().shaders[shader.pipelineStage].resize(graphicsShader->mCreateInfo.sourceSize); + memcpy(&mProgramCache.back().shaders[shader.pipelineStage][0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize); + } + return Graphics::MakeUnique(mProgramCache.back().programImpl); +} + Graphics::UniquePtr TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) { - mCallStack.PushCall("Controller::CreateShader", ""); - return nullptr; + mCallStack.PushCall("CreateShader", ""); + return Graphics::MakeUnique(mGl, shaderCreateInfo); } Graphics::UniquePtr TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr&& oldSampler) { TraceCallStack::NamedParams namedParams; namedParams["samplerCreateInfo"] << samplerCreateInfo; - mCallStack.PushCall("Controller::CreateSampler", namedParams.str(), namedParams); + mCallStack.PushCall("CreateSampler", namedParams.str(), namedParams); return Graphics::MakeUnique(mGl, samplerCreateInfo); } Graphics::UniquePtr TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr&& oldRenderTarget) { - mCallStack.PushCall("Controller::CreateRenderTarget", ""); - return nullptr; + mCallStack.PushCall("CreateRenderTarget", ""); + return Graphics::MakeUnique(mGl, renderTargetCreateInfo); } Graphics::UniquePtr TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo) { - mCallStack.PushCall("Controller::MapBufferRange", ""); + mCallStack.PushCall("MapBufferRange", ""); auto buffer = static_cast(mapInfo.buffer); buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity @@ -738,47 +1007,53 @@ Graphics::UniquePtr TestGraphicsController::MapBufferRange(con Graphics::UniquePtr TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo) { - mCallStack.PushCall("Controller::MapTextureRange", ""); + mCallStack.PushCall("MapTextureRange", ""); return nullptr; } void TestGraphicsController::UnmapMemory(Graphics::UniquePtr memory) { - mCallStack.PushCall("Controller::UnmapMemory", ""); + mCallStack.PushCall("UnmapMemory", ""); } Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const { - mCallStack.PushCall("Controller::GetTextureMemoryRequirements", ""); + mCallStack.PushCall("GetTextureMemoryRequirements", ""); return Graphics::MemoryRequirements{}; } Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const { - mCallStack.PushCall("Controller::GetBufferMemoryRequirements", ""); + mCallStack.PushCall("GetBufferMemoryRequirements", ""); return Graphics::MemoryRequirements{}; } const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture) { static Graphics::TextureProperties textureProperties{}; - mCallStack.PushCall("Controller::GetTextureProperties", ""); + mCallStack.PushCall("GetTextureProperties", ""); return textureProperties; } -const Graphics::Reflection& TestGraphicsController::GetPipelineReflection(const Graphics::Pipeline& pipeline) +const Graphics::Reflection& TestGraphicsController::GetProgramReflection(const Graphics::Program& program) { - static TestGraphicsReflection reflection(mGl); - mCallStack.PushCall("Controller::GetPipelineReflection", ""); + mCallStack.PushCall("GetProgramReflection", ""); - return reflection; + return static_cast(&program)->GetReflection(); } bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const { - mCallStack.PushCall("Controller::PipelineEquals", ""); + mCallStack.PushCall("PipelineEquals", ""); return false; } +bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) +{ + mCallStack.PushCall("GetProgramParameter", ""); + auto graphicsProgram = Uncast(&program); + return graphicsProgram->GetParameter(parameterId, outData); +} + } // namespace Dali