From 161884f8b397e19bc135072e3b44d9e54732dd21 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Thu, 17 Jun 2021 12:40:48 +0100 Subject: [PATCH] Standalone uniforms cache Change-Id: I7234d85c4f3e93f5c1a76a19e1bc41a2cb6447e2 GLES::Program uses internal uniform cache --- dali/internal/graphics/gles-impl/gles-context.cpp | 100 +---------- .../graphics/gles-impl/gles-graphics-program.cpp | 186 +++++++++++++++++++++ .../graphics/gles-impl/gles-graphics-program.h | 18 ++ 3 files changed, 207 insertions(+), 97 deletions(-) diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index a0843e6..2a6677d 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -509,106 +509,12 @@ void Context::ResolveUniformBuffers() void Context::ResolveStandaloneUniforms() { - auto& gl = *mImpl->mController.GetGL(); - // Find reflection for program const auto program = static_cast(mImpl->mNewPipeline->GetCreateInfo().programState->program); + const auto ptr = reinterpret_cast(mImpl->mCurrentStandaloneUBOBinding.buffer->GetCPUAllocatedAddress()) + mImpl->mCurrentStandaloneUBOBinding.offset; - const auto& reflection = program->GetReflection(); - - auto extraInfos = reflection.GetStandaloneUniformExtraInfo(); - - const auto ptr = reinterpret_cast(mImpl->mCurrentStandaloneUBOBinding.buffer->GetCPUAllocatedAddress()) + mImpl->mCurrentStandaloneUBOBinding.offset; - - for(const auto& info : extraInfos) - { - auto type = GLTypeConversion(info.type).type; - auto offset = info.offset; - switch(type) - { - case GLType::FLOAT_VEC2: - { - gl.Uniform2fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_VEC3: - { - gl.Uniform3fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_VEC4: - { - gl.Uniform4fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC2: - { - gl.Uniform2iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC3: - { - gl.Uniform3iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::INT_VEC4: - { - gl.Uniform4iv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::BOOL: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC2: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC3: - { - // not supported by DALi - break; - } - case GLType::BOOL_VEC4: - { - // not supported by DALi - break; - } - case GLType::FLOAT: - { - gl.Uniform1fv(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT2: - { - gl.UniformMatrix2fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT3: - { - gl.UniformMatrix3fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::FLOAT_MAT4: - { - gl.UniformMatrix4fv(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - break; - } - case GLType::SAMPLER_2D: - { - break; - } - case GLType::SAMPLER_CUBE: - { - break; - } - default: - { - } - } - } + // Update program uniforms + program->GetImplementation()->UpdateStandaloneUniformBlock(ptr); } void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) diff --git a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp index 64de708..5c833f5 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp @@ -28,6 +28,32 @@ namespace Dali::Graphics::GLES { +using Integration::GlAbstraction; + +/** + * Structure stores pointer to the function + * which will set the uniform of particular type + */ +struct UniformSetter +{ + union + { + void (GlAbstraction::*uniformfProc)(GLint, GLsizei, const float*); + void (GlAbstraction::*uniformiProc)(GLint, GLsizei, const int*); + void (GlAbstraction::*uniformMatrixProc)(GLint, GLsizei, GLboolean, const float*); + }; + + enum class Type + { + UNDEFINED = 0, + FLOAT, + INT, + MATRIX + }; + + Type type; +}; + struct ProgramImpl::Impl { explicit Impl(EglGraphicsController& _controller, const ProgramCreateInfo& info) @@ -51,6 +77,12 @@ struct ProgramImpl::Impl uint32_t refCount{0u}; std::unique_ptr reflection{nullptr}; + + // Uniform cache + std::vector uniformData; + + // List of standalone uniform setters + std::vector uniformSetters; }; ProgramImpl::ProgramImpl(const Graphics::ProgramCreateInfo& createInfo, Graphics::EglGraphicsController& controller) @@ -125,6 +157,20 @@ bool ProgramImpl::Create() mImpl->reflection->BuildUniformReflection(); mImpl->reflection->BuildVertexAttributeReflection(); + // populate uniform cache memory for standalone uniforms (it's not needed + // for real UBOs as real UBOs work with whole memory blocks) + auto& reflection = mImpl->reflection; + if(!reflection->GetStandaloneUniformExtraInfo().empty()) + { + UniformBlockInfo blockInfo; + mImpl->reflection->GetUniformBlock(0, blockInfo); + auto uniformCacheSize = blockInfo.size; + mImpl->uniformData.resize(uniformCacheSize); + + std::fill(mImpl->uniformData.begin(), mImpl->uniformData.end(), 0); + + BuildStandaloneUniformCache(); + } return true; } @@ -168,6 +214,146 @@ const ProgramCreateInfo& ProgramImpl::GetCreateInfo() const return mImpl->createInfo; } +void ProgramImpl::UpdateStandaloneUniformBlock(const char* ptr) +{ + const auto& reflection = GetReflection(); + + const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo(); + + auto& gl = *GetController().GetGL(); + + // Set uniforms + int index = 0; + auto cachePtr = reinterpret_cast(mImpl->uniformData.data()); + for(const auto& info : extraInfos) + { + auto& setter = mImpl->uniformSetters[index++]; + + auto offset = info.offset; + switch(setter.type) + { + case UniformSetter::Type::FLOAT: + { + if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + { + (gl.*(setter.uniformfProc))(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); + memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + } + break; + } + case UniformSetter::Type::INT: + { + if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + { + (gl.*(setter.uniformiProc))(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); + memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + } + break; + } + case UniformSetter::Type::MATRIX: + { + if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + { + (gl.*(setter.uniformMatrixProc))(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); + memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + } + break; + } + case UniformSetter::Type::UNDEFINED: + { + } + } + } +} + +void ProgramImpl::BuildStandaloneUniformCache() +{ + const auto& reflection = GetReflection(); + const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo(); + + // Prepare pointers to the uniform setter calls + mImpl->uniformSetters.resize(extraInfos.size()); + int index = 0; + for(const auto& info : extraInfos) + { + auto type = GLTypeConversion(info.type).type; + mImpl->uniformSetters[index].type = UniformSetter::Type::UNDEFINED; + switch(type) + { + case GLType::FLOAT_VEC2: + { + mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform2fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT; + break; + } + case GLType::FLOAT_VEC3: + { + mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform3fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT; + break; + } + case GLType::FLOAT_VEC4: + { + mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform4fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT; + break; + } + case GLType::INT_VEC2: + { + mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform2iv; + mImpl->uniformSetters[index].type = UniformSetter::Type::INT; + break; + } + case GLType::INT_VEC3: + { + mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform3iv; + mImpl->uniformSetters[index].type = UniformSetter::Type::INT; + break; + } + case GLType::INT_VEC4: + { + mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform4iv; + mImpl->uniformSetters[index].type = UniformSetter::Type::INT; + break; + } + case GLType::BOOL: + case GLType::BOOL_VEC2: + case GLType::BOOL_VEC3: + case GLType::BOOL_VEC4: + case GLType::FLOAT: + { + mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform1fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT; + break; + } + case GLType::FLOAT_MAT2: + { + mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix2fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX; + break; + } + case GLType::FLOAT_MAT3: + { + mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix3fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX; + break; + } + case GLType::FLOAT_MAT4: + { + mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix4fv; + mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX; + break; + } + case GLType::SAMPLER_2D: + case GLType::SAMPLER_CUBE: + default: + { + } + } + index++; + } +} + Program::~Program() { // Destroy GL resources of implementation. This should happen diff --git a/dali/internal/graphics/gles-impl/gles-graphics-program.h b/dali/internal/graphics/gles-impl/gles-graphics-program.h index 73ed75c..e657e5e 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-program.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-program.h @@ -120,6 +120,24 @@ public: */ bool GetParameter(uint32_t parameterId, void* out); + /** + * @brief Updates standalone uniforms + * + * Updates standalone uniforms (issues the GL calls) and + * updates internal uniform cache + * + * @param[in] ptr Valid pointer to the uniform block memory + */ + void UpdateStandaloneUniformBlock(const char* ptr); + + /** + * @brief Builds standalone uniform cache + * + * This function allocates cache memory and + * gathers a list of GL functions per uniform type. + */ + void BuildStandaloneUniformCache(); + private: friend class Program; -- 2.7.4