UBO support on the Core side using CPU-based Buffer memory 11/254411/11
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 5 Mar 2021 16:50:05 +0000 (16:50 +0000)
committerDavid Steele <david.steele@samsung.com>
Mon, 8 Mar 2021 16:31:02 +0000 (16:31 +0000)
Change-Id: I376b6f831d28342e1ecc5313eff6f56aa9f92ef3

dali/devel-api/common/hash.cpp
dali/devel-api/common/hash.h
dali/graphics-api/graphics-buffer-create-info.h
dali/graphics-api/graphics-command-buffer.h
dali/graphics-api/graphics-types.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/renderers/uniform-buffer-manager.cpp
dali/internal/render/shaders/program.cpp
dali/internal/update/common/uniform-map.h

index cc2740f..d510013 100644 (file)
@@ -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);
index 94ccad7..4665102 100644 (file)
@@ -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
index c93bd4b..dcdc802 100644 (file)
@@ -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};
 };
 
index 5d48685..c2613b1 100644 (file)
@@ -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
index d690478..5cf6a4a 100644 (file)
@@ -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<uint32_t>(usage);
+  return flags;
+}
+
+/**
  * @brief The structure describes memory requirements of GPU resource (texture, buffer)
  */
 struct MemoryRequirements
index 3bba444..1824256 100644 (file)
@@ -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<Graphics::CommandBuffer> 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<class T>
 bool Renderer::WriteDefaultUniform(const Graphics::UniformInfo* uniformInfo, Render::UniformBuffer& ubo, const std::vector<Graphics::UniformBufferBinding>& 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<uint32_t>(sizeof(bool)) * arrayIndex);
+            break;
+          }
+          case Property::Type::INTEGER:
+          {
+            ubo.Write(&(*iter).propertyValue->GetInteger(updateBufferIndex),
+                      sizeof(int32_t),
+                      dst + static_cast<int32_t>(sizeof(int32_t)) * arrayIndex);
+            break;
+          }
+          case Property::Type::FLOAT:
+          {
             ubo.Write(&(*iter).propertyValue->GetFloat(updateBufferIndex),
                       sizeof(float),
-                      dst + static_cast<uint32_t>(sizeof(Vector4)) * arrayIndex);
+                      dst + static_cast<uint32_t>(sizeof(float)) * arrayIndex);
             break;
           }
           case Property::Type::VECTOR2:
           {
             ubo.Write(&(*iter).propertyValue->GetVector2(updateBufferIndex),
                       sizeof(Vector2),
-                      dst + static_cast<uint32_t>(sizeof(Vector4)) * arrayIndex);
+                      dst + static_cast<uint32_t>(sizeof(Vector2)) * arrayIndex);
             break;
           }
           case Property::Type::VECTOR3:
           {
             ubo.Write(&(*iter).propertyValue->GetVector3(updateBufferIndex),
                       sizeof(Vector3),
-                      dst + static_cast<uint32_t>(sizeof(Vector4)) * arrayIndex);
+                      dst + static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(sizeof(Vector4))));
+            //}
+            // GL:
+            ubo.Write(&(*iter).propertyValue->GetMatrix3(updateBufferIndex),
+                      sizeof(Matrix3),
+                      dst + static_cast<uint32_t>(sizeof(Matrix3)) * arrayIndex);
             break;
           }
           default:
index 26b7a9e..0df272e 100644 (file)
@@ -491,6 +491,8 @@ private:
   Context*          mContext;
   Render::Geometry* mGeometry;
 
+  Graphics::UniquePtr<Graphics::CommandBuffer> mGraphicsCommandBuffer{};
+
   ProgramCache*        mProgramCache{};
   Render::ShaderCache* mShaderCache{};
 
index 5b6a1ec..2f34327 100644 (file)
@@ -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;
index d62e421..f8aa3a8 100644 (file)
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/dali-vector.h>
 
-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)
   {
index d20782e..fbfb9f6 100644 (file)
@@ -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());