From 89272ef946cf9293a1586ec019c75d512f55dbe7 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Fri, 25 Jun 2021 15:25:48 +0100 Subject: [PATCH] Optimized program retrieval from the cache Change-Id: I6dda5244b32a2cc5c21285673d7a125cd36caaee --- dali/internal/render/renderers/render-renderer.cpp | 58 ++++++++++++---------- dali/internal/render/shaders/program.cpp | 24 ++++----- dali/internal/render/shaders/program.h | 13 +++-- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 4a2a786..6d0f0b7 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -432,41 +432,45 @@ bool Renderer::Render(Graphics::CommandBuffer& comma // Create Program ShaderDataPtr shaderData = mRenderDataProvider->GetShader().GetShaderData(); - const std::vector& vertShader = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER); - const std::vector& fragShader = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER); - Dali::Graphics::Shader& vertexShader = mShaderCache->GetShader( - vertShader, - Graphics::PipelineStage::VERTEX_SHADER, - shaderData->GetSourceMode()); - - Dali::Graphics::Shader& fragmentShader = mShaderCache->GetShader( - fragShader, - Graphics::PipelineStage::FRAGMENT_SHADER, - shaderData->GetSourceMode()); - - std::vector shaderStates{ - Graphics::ShaderState() - .SetShader(vertexShader) - .SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER), - Graphics::ShaderState() - .SetShader(fragmentShader) - .SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)}; - - auto createInfo = Graphics::ProgramCreateInfo(); - createInfo.SetShaderState(shaderStates); - - auto graphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr); + Program* program = Program::New(*mProgramCache, shaderData, - *mGraphicsController, - std::move(graphicsProgram)); - + *mGraphicsController); if(!program) { DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast(&mRenderDataProvider->GetShader())); return false; } + // If program doesn't have Gfx program object assigned yet, prepare it. + if(!program->GetGraphicsProgramPtr()) + { + const std::vector &vertShader = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER); + const std::vector &fragShader = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER); + Dali::Graphics::Shader &vertexShader = mShaderCache->GetShader( + vertShader, + Graphics::PipelineStage::VERTEX_SHADER, + shaderData->GetSourceMode()); + + Dali::Graphics::Shader &fragmentShader = mShaderCache->GetShader( + fragShader, + Graphics::PipelineStage::FRAGMENT_SHADER, + shaderData->GetSourceMode()); + + std::vector shaderStates{ + Graphics::ShaderState() + .SetShader(vertexShader) + .SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER), + Graphics::ShaderState() + .SetShader(fragmentShader) + .SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)}; + + auto createInfo = Graphics::ProgramCreateInfo(); + createInfo.SetShaderState(shaderStates); + auto graphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr); + program->SetGraphicsProgram(std::move(graphicsProgram)); + } + // Prepare the graphics pipeline. This may either re-use an existing pipeline or create a new one. auto& pipeline = PrepareGraphicsPipeline(*program, instruction, node, blend); diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp index 3a3c8e6..56ba362 100644 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -72,37 +72,30 @@ inline uint32_t GetUniformBufferDataAlignment(uint32_t dataSize) // IMPLEMENTATION -Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr&& gfxProgram) +Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController) { - uint32_t programId{0u}; - - // Get program id and use it as hash for the cache - // in order to maintain current functionality as long as needed - gfxController.GetProgramParameter(*gfxProgram, 1, &programId); - - size_t shaderHash = programId; + size_t shaderHash = shaderData->GetHashValue(); Program* program = cache.GetProgram(shaderHash); if(nullptr == program) { // program not found so create it - program = new Program(cache, shaderData, gfxController, std::move(gfxProgram)); + program = new Program(cache, shaderData, gfxController); cache.AddProgram(shaderHash, program); } return program; } -Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller, Graphics::UniquePtr&& gfxProgram) +Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller) : mCache(cache), mProjectionMatrix(nullptr), mViewMatrix(nullptr), - mGfxProgram(std::move(gfxProgram)), + mGfxProgram(nullptr), mGfxController(controller), mProgramData(shaderData) { - BuildReflection(controller.GetProgramReflection(*mGfxProgram.get())); } Program::~Program() = default; @@ -183,6 +176,13 @@ void Program::BuildReflection(const Graphics::Reflection& graphicsReflection) } } +void Program::SetGraphicsProgram( Graphics::UniquePtr&& program ) +{ + mGfxProgram = std::move(program); + BuildReflection(mGfxController.GetProgramReflection(*mGfxProgram.get())); +} + + bool Program::GetUniform(const std::string& name, size_t hashedName, Graphics::UniformInfo& out) const { if(mReflection.empty()) diff --git a/dali/internal/render/shaders/program.h b/dali/internal/render/shaders/program.h index 05a6e70..d6cde0f 100644 --- a/dali/internal/render/shaders/program.h +++ b/dali/internal/render/shaders/program.h @@ -74,10 +74,9 @@ public: * and optionally precompiled binary. If the binary is empty the program bytecode * is copied into it after compilation and linking) * @param[in] gfxController Reference to valid graphics Controller object - * @param[in] gfxProgram Reference to valid graphics Program object * @return pointer to the program */ - static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr&& gfxProgram); + static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController); /** * Set the projection matrix that has currently been sent @@ -120,6 +119,13 @@ public: return *mGfxProgram; } + [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const + { + return mGfxProgram.get(); + } + + void SetGraphicsProgram( Graphics::UniquePtr&& program ); + /** * Retrieves uniform data. * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known @@ -145,10 +151,9 @@ private: // Implementation * Constructor, private so no direct instantiation * @param[in] cache where the programs are stored * @param[in] shaderData A smart pointer to a data structure containing the program source and binary - * @param[in] gfxProgram Graphics Program object * @param[in] gfxController Reference to Graphics Controller object */ - Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr&& gfxProgram); + Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController); public: Program() = delete; ///< default constructor, not defined -- 2.7.4