From 2be81f20223b75ad2509c50b10973e6ff4d7d27a Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Fri, 5 Mar 2021 16:50:05 +0000 Subject: [PATCH] UBO support on the Core side using CPU-based Buffer memory Change-Id: I376b6f831d28342e1ecc5313eff6f56aa9f92ef3 --- dali/devel-api/common/hash.cpp | 18 +++++++ dali/devel-api/common/hash.h | 8 +++ dali/graphics-api/graphics-buffer-create-info.h | 16 +++++- dali/graphics-api/graphics-command-buffer.h | 2 +- dali/graphics-api/graphics-types.h | 22 ++++++++ dali/internal/render/renderers/render-renderer.cpp | 61 ++++++++++++++++------ dali/internal/render/renderers/render-renderer.h | 2 + .../render/renderers/uniform-buffer-manager.cpp | 10 ++-- dali/internal/render/shaders/program.cpp | 36 +------------ dali/internal/update/common/uniform-map.h | 2 +- 10 files changed, 118 insertions(+), 59 deletions(-) diff --git a/dali/devel-api/common/hash.cpp b/dali/devel-api/common/hash.cpp index cc2740f..d510013 100644 --- a/dali/devel-api/common/hash.cpp +++ b/dali/devel-api/common/hash.cpp @@ -34,6 +34,15 @@ inline void HashString(const char* string, std::size_t& hash) } } +inline void HashString(const char* string, std::size_t& hash, char terminator) +{ + char c; + while((c = *string++) && c != terminator) + { + hash = hash * 33 + c; + } +} + } // unnamed namespace std::size_t CalculateHash(const std::string& toHash) @@ -45,6 +54,15 @@ std::size_t CalculateHash(const std::string& toHash) return hash; } +std::size_t CalculateHash(const std::string& toHash, char terminator) +{ + std::size_t hash(INITIAL_HASH_VALUE); + + HashString(toHash.c_str(), hash, terminator); + + return hash; +} + std::size_t CalculateHash(const std::string& string1, const std::string& string2) { std::size_t hash(INITIAL_HASH_VALUE); diff --git a/dali/devel-api/common/hash.h b/dali/devel-api/common/hash.h index 94ccad7..4665102 100644 --- a/dali/devel-api/common/hash.h +++ b/dali/devel-api/common/hash.h @@ -47,6 +47,14 @@ DALI_CORE_API std::size_t CalculateHash(const std::string& toHash); */ DALI_CORE_API std::size_t CalculateHash(const std::string& string1, const std::string& string2); +/** + * @brief Create a hash code for a string + * @param toHash string to hash + * @param terminator character terminating the hashing + * @return hash code + */ +DALI_CORE_API std::size_t CalculateHash(const std::string& toHash, char terminator); + } // namespace Dali #endif // DALI_HASH diff --git a/dali/graphics-api/graphics-buffer-create-info.h b/dali/graphics-api/graphics-buffer-create-info.h index c93bd4b..dcdc802 100644 --- a/dali/graphics-api/graphics-buffer-create-info.h +++ b/dali/graphics-api/graphics-buffer-create-info.h @@ -81,6 +81,20 @@ struct BufferCreateInfo } /** + * @brief Sets properties flags + * + * Properties flag bits can alter behaviour of the implementation + * + * @param[in] value Flags + * @return reference to this structure + */ + auto& SetBufferPropertiesFlags( BufferPropertiesFlags value ) + { + propertiesFlags = value; + return *this; + } + + /** * @brief Sets allocation callbacks which will be used when object is created * and destroyed. * @@ -97,7 +111,7 @@ struct BufferCreateInfo ExtensionCreateInfo* nextExtension{nullptr}; BufferUsageFlags usage{}; uint32_t size{0u}; - + BufferPropertiesFlags propertiesFlags{}; const AllocationCallbacks* allocationCallbacks{nullptr}; }; diff --git a/dali/graphics-api/graphics-command-buffer.h b/dali/graphics-api/graphics-command-buffer.h index 5d48685..c2613b1 100644 --- a/dali/graphics-api/graphics-command-buffer.h +++ b/dali/graphics-api/graphics-command-buffer.h @@ -263,7 +263,7 @@ public: * It is useful if the command buffer has to be re-recorded frequently, for example, * every frame. */ - virtual void Reset(CommandBuffer& commandBuffer) = 0; + virtual void Reset() = 0; /** * @brief Changes scissor rect diff --git a/dali/graphics-api/graphics-types.h b/dali/graphics-api/graphics-types.h index d690478..5cf6a4a 100644 --- a/dali/graphics-api/graphics-types.h +++ b/dali/graphics-api/graphics-types.h @@ -872,6 +872,28 @@ inline BufferUsageFlags operator|(BufferUsageFlags flags, BufferUsage usage) } /** + * @brief Buffer property bits + * + * Use these bits to set BufferPropertiesFlags. + */ +enum class BufferPropertiesFlagBit : uint32_t +{ + CPU_ALLOCATED = 1 << 0, ///< Buffer is allocated on the CPU side + TRANSIENT_MEMORY = 1 << 1, ///< Buffer memory will be short-lived +}; + +/** + * @brief BufferPropetiesFlags alters behaviour of implementation + */ +using BufferPropertiesFlags = uint32_t; + +inline BufferPropertiesFlags operator|(BufferPropertiesFlags flags, BufferPropertiesFlagBit usage) +{ + flags |= static_cast(usage); + return flags; +} + +/** * @brief The structure describes memory requirements of GPU resource (texture, buffer) */ struct MemoryRequirements diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 3bba444..1824256 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -752,11 +752,19 @@ void Renderer::Render(Context& conte { return; } + if(!mGraphicsCommandBuffer) + { + mGraphicsCommandBuffer = mGraphicsController->CreateCommandBuffer( + Graphics::CommandBufferCreateInfo() + .SetLevel(Graphics::CommandBufferLevel::SECONDARY), + nullptr); + } + else + { + mGraphicsCommandBuffer->Reset(); + } - Graphics::UniquePtr commandBuffer = mGraphicsController->CreateCommandBuffer( - Graphics::CommandBufferCreateInfo() - .SetLevel(Graphics::CommandBufferLevel::SECONDARY), - nullptr); + auto& commandBuffer = mGraphicsCommandBuffer; //Set blending mode if(!mDrawCommands.empty()) @@ -953,7 +961,7 @@ void Renderer::Render(Context& conte template bool Renderer::WriteDefaultUniform(const Graphics::UniformInfo* uniformInfo, Render::UniformBuffer& ubo, const std::vector& bindings, const T& data) { - if(uniformInfo) + if(uniformInfo && !uniformInfo->name.empty()) { WriteUniform(ubo, bindings, *uniformInfo, data); return true; @@ -1014,27 +1022,39 @@ void Renderer::FillUniformBuffers(Program& switch((*iter).propertyValue->GetType()) { - case Property::Type::FLOAT: - case Property::Type::INTEGER: case Property::Type::BOOLEAN: { + ubo.Write(&(*iter).propertyValue->GetBoolean(updateBufferIndex), + sizeof(bool), + dst + static_cast(sizeof(bool)) * arrayIndex); + break; + } + case Property::Type::INTEGER: + { + ubo.Write(&(*iter).propertyValue->GetInteger(updateBufferIndex), + sizeof(int32_t), + dst + static_cast(sizeof(int32_t)) * arrayIndex); + break; + } + case Property::Type::FLOAT: + { ubo.Write(&(*iter).propertyValue->GetFloat(updateBufferIndex), sizeof(float), - dst + static_cast(sizeof(Vector4)) * arrayIndex); + dst + static_cast(sizeof(float)) * arrayIndex); break; } case Property::Type::VECTOR2: { ubo.Write(&(*iter).propertyValue->GetVector2(updateBufferIndex), sizeof(Vector2), - dst + static_cast(sizeof(Vector4)) * arrayIndex); + dst + static_cast(sizeof(Vector2)) * arrayIndex); break; } case Property::Type::VECTOR3: { ubo.Write(&(*iter).propertyValue->GetVector3(updateBufferIndex), sizeof(Vector3), - dst + static_cast(sizeof(Vector4)) * arrayIndex); + dst + static_cast(sizeof(Vector3)) * arrayIndex); break; } case Property::Type::VECTOR4: @@ -1053,13 +1073,20 @@ void Renderer::FillUniformBuffers(Program& } case Property::Type::MATRIX3: { - const auto& matrix = &(*iter).propertyValue->GetMatrix3(updateBufferIndex); - for(int i = 0; i < 3; ++i) - { - ubo.Write(&matrix->AsFloat()[i * 3], - sizeof(float) * 3, - dst + (i * static_cast(sizeof(Vector4)))); - } + // todo: handle data padding properly + // Vulkan: + // + //const auto& matrix = &(*iter).propertyValue->GetMatrix3(updateBufferIndex); + //for(int i = 0; i < 3; ++i) + //{ + //ubo.Write(&matrix->AsFloat()[i * 3], + // sizeof(float) * 3, + // dst + (i * static_cast(sizeof(Vector4)))); + //} + // GL: + ubo.Write(&(*iter).propertyValue->GetMatrix3(updateBufferIndex), + sizeof(Matrix3), + dst + static_cast(sizeof(Matrix3)) * arrayIndex); break; } default: diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 26b7a9e..0df272e 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -491,6 +491,8 @@ private: Context* mContext; Render::Geometry* mGeometry; + Graphics::UniquePtr mGraphicsCommandBuffer{}; + ProgramCache* mProgramCache{}; Render::ShaderCache* mShaderCache{}; diff --git a/dali/internal/render/renderers/uniform-buffer-manager.cpp b/dali/internal/render/renderers/uniform-buffer-manager.cpp index 5b6a1ec..2f34327 100644 --- a/dali/internal/render/renderers/uniform-buffer-manager.cpp +++ b/dali/internal/render/renderers/uniform-buffer-manager.cpp @@ -70,10 +70,12 @@ void UniformBuffer::Reserve(uint32_t size) mSize = size; - Graphics::BufferCreateInfo createInfo; - createInfo.SetSize(mSize); - createInfo.SetUsage(mUsageFlags); - mBuffer = std::move(mController->CreateBuffer(createInfo, std::move(mBuffer))); + auto createInfo = Graphics::BufferCreateInfo() + .SetSize(mSize) + .SetBufferPropertiesFlags( 0 | Graphics::BufferPropertiesFlagBit::CPU_ALLOCATED ) + .SetUsage(mUsageFlags); + + mBuffer = mController->CreateBuffer(createInfo, std::move(mBuffer)); mMapBufferInfo.buffer = mBuffer.get(); mMapBufferInfo.usage = 0 | Graphics::MemoryUsageFlagBits::WRITE; diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp index d62e421..f8aa3a8 100644 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -38,40 +38,6 @@ #include #include -namespace -{ -void LogWithLineNumbers(const char* source) -{ - uint32_t lineNumber = 0u; - const char* prev = source; - const char* ptr = prev; - - while(true) - { - if(lineNumber > 200u) - { - break; - } - // seek the next end of line or end of text - while(*ptr != '\n' && *ptr != '\0') - { - ++ptr; - } - - std::string line(prev, ptr - prev); - Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, "%4d %s\n", lineNumber, line.c_str()); - - if(*ptr == '\0') - { - break; - } - prev = ++ptr; - ++lineNumber; - } -} - -} //namespace - namespace Dali { namespace Internal @@ -786,7 +752,7 @@ bool Program::GetUniform(const std::string& name, size_t hashedName, Graphics::U return false; } - hashedName = !hashedName ? CalculateHash(name) : hashedName; + hashedName = !hashedName ? CalculateHash(name, '[') : hashedName; for(const ReflectionUniformInfo& item : mReflection) { diff --git a/dali/internal/update/common/uniform-map.h b/dali/internal/update/common/uniform-map.h index d20782e..fbfb9f6 100644 --- a/dali/internal/update/common/uniform-map.h +++ b/dali/internal/update/common/uniform-map.h @@ -61,7 +61,7 @@ public: auto pos0 = theUniformName.GetStringView().rfind("[", pos); arrayIndex = atoi(theUniformName.GetCString() + pos0 + 1); // Calculate hash from name without array index - uniformNameHashNoArray = Dali::CalculateHash(theUniformName.GetStringView().substr(0, pos0).data()); + uniformNameHashNoArray = Dali::CalculateHash(theUniformName.GetStringView().substr(0, pos0).data(), '['); } uniformName = theUniformName; uniformNameHash = Dali::CalculateHash(theUniformName.GetCString()); -- 2.7.4