GLES reflection supports array element stride for UBO members. 04/313404/4
authorAdam Bialogonski <adam.b@samsung.com>
Tue, 25 Jun 2024 11:29:06 +0000 (12:29 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 28 Jun 2024 09:36:16 +0000 (10:36 +0100)
Change-Id: Ic703df5c5909d7b56de3d5870fb18b3b2adda3f4

automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.h
dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp

index 6066f67..e21c304 100644 (file)
@@ -442,9 +442,85 @@ public: // Test Functions
     mCustomUniforms = customUniforms;
   }
 
+  constexpr std::pair<uint32_t, uint32_t> GetUniformBufferArrayStrideAndTypeSize(TestGraphicsReflection::TestUniformInfo& uniformInfo, uint32_t requestedStride)
+  {
+    uint32_t dataTypeSize  = 0;
+    uint32_t elementStride = 0;
+    switch(uniformInfo.type)
+    {
+      case Property::FLOAT:
+      case Property::INTEGER:
+      case Property::BOOLEAN:
+      {
+        dataTypeSize = sizeof(float);
+        break;
+      }
+      case Property::MATRIX:
+      {
+        dataTypeSize = sizeof(float) * 16;
+        break;
+      }
+      case Property::MATRIX3:
+      {
+        dataTypeSize = sizeof(float) * 9;
+        break;
+      }
+      case Property::VECTOR2:
+      {
+        dataTypeSize = sizeof(float) * 2;
+        break;
+      }
+      case Property::VECTOR3:
+      {
+        dataTypeSize = sizeof(float) * 3;
+        break;
+      }
+      case Property::VECTOR4:
+      {
+        dataTypeSize = sizeof(float) * 4;
+        break;
+      }
+      default:
+      {
+      }
+    }
+    if(uniformInfo.elementStride)
+    {
+      bool roundUp  = (dataTypeSize % uniformInfo.elementStride);
+      elementStride = (dataTypeSize / uniformInfo.elementStride) * uniformInfo.elementStride + (roundUp ? uniformInfo.elementStride : 0);
+    }
+    return std::make_pair(dataTypeSize, elementStride);
+  }
+
+  void AddMemberToUniformBlock(TestGraphicsReflection::TestUniformBlockInfo& blockInfo,
+                               std::string                                   name,
+                               Property::Type                                type,
+                               uint32_t                                      elementCount,
+                               uint32_t                                      elementStrideInBytes)
+  {
+    TestGraphicsReflection::TestUniformInfo info;
+    info.name          = std::move(name);
+    info.type          = type;
+    info.uniformClass  = Graphics::UniformClass::UNIFORM;
+    info.numElements   = elementCount;
+    info.locations     = {0};
+    info.bufferIndex   = 0;                    // this will update when AddCustomUniformBlock called
+
+    auto retval= GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes);
+    info.elementStride = std::max(retval.first, retval.second);
+    info.offsets       = {blockInfo.size};
+    blockInfo.size += (elementCount == 0 ? 1 : elementCount) * std::max(retval.first, retval.second);
+    blockInfo.members.emplace_back(info);
+  }
+
   void AddCustomUniformBlock(const TestGraphicsReflection::TestUniformBlockInfo& blockInfo)
   {
     mCustomUniformBlocks.push_back(blockInfo);
+    auto& info = mCustomUniformBlocks.back();
+    for(auto& member : info.members)
+    {
+      member.bufferIndex = mCustomUniformBlocks.size();
+    }
   }
 
   void ClearSubmitStack()
index 22d09e1..2d507f7 100644 (file)
@@ -325,13 +325,14 @@ bool TestGraphicsReflection::GetUniformBlock(uint32_t index, Dali::Graphics::Uni
   out.size = block.size;
   for(auto i = 0u; i < out.members.size(); ++i)
   {
-    const auto& memberUniform   = block.members[i];
-    out.members[i].name         = memberUniform.name;
-    out.members[i].binding      = block.binding;
-    out.members[i].uniformClass = Graphics::UniformClass::UNIFORM;
-    out.members[i].offset       = memberUniform.offsets[0];
-    out.members[i].location     = memberUniform.locations[0];
-    out.members[i].elementCount = memberUniform.numElements;
+    const auto& memberUniform    = block.members[i];
+    out.members[i].name          = memberUniform.name;
+    out.members[i].binding       = block.binding;
+    out.members[i].uniformClass  = Graphics::UniformClass::UNIFORM;
+    out.members[i].offset        = memberUniform.offsets[0];
+    out.members[i].location      = memberUniform.locations[0];
+    out.members[i].elementCount  = memberUniform.numElements;
+    out.members[i].elementStride = memberUniform.elementStride;
   }
 
   return true;
index b598435..3521ed0 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_GRAPHICS_REFLECTION_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -60,6 +60,7 @@ public: // Test methods
     std::vector<uint32_t>  locations{};
     uint32_t               numElements{0u}; // 0 elements means this isn't an array; 1 element means this is an array of size 1
     Property::Type         type;
+    uint32_t               elementStride{0u}; // array element stride, 0 - tightly packed
   };
 
   struct TestUniformBlockInfo
index 27e2b3b..5766dc7 100644 (file)
@@ -399,6 +399,32 @@ void Reflection::BuildUniformBlockReflection()
     blockIndex++;
   }
 
+  // Calculate array element stride for uniform blocks (not needed for standalone block)
+  if(mUniformBlocks.size() > 1)
+  {
+    for(auto i = 1u; i < mUniformBlocks.size(); ++i)
+    {
+      auto& block = mUniformBlocks[i];
+
+      // check last member
+      auto& lastMember = block.members.back();
+      if(lastMember.elementCount > 0)
+      {
+        lastMember.elementStride = (block.size - lastMember.offset) / lastMember.elementCount;
+      }
+
+      // update other arrays in this block
+      for(auto memberIndex = 0u; memberIndex < block.members.size() - 1; ++memberIndex)
+      {
+        auto& member = block.members[memberIndex];
+        if(member.elementCount > 0)
+        {
+          member.elementStride = (block.members[memberIndex+1].offset - member.offset) / member.elementCount;
+        }
+      }
+    }
+  }
+
   // count uniform size
   auto& defaultUniformBlock = mUniformBlocks[0]; // Standalone block
   defaultUniformBlock.size  = 0;
@@ -507,12 +533,13 @@ bool Reflection::GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInf
   for(auto i = 0u; i < out.members.size(); ++i)
   {
     const auto& memberUniform   = block.members[i];
-    out.members[i].name         = memberUniform.name;
-    out.members[i].binding      = block.binding;
-    out.members[i].uniformClass = Graphics::UniformClass::UNIFORM;
-    out.members[i].offset       = memberUniform.offset;
-    out.members[i].location     = memberUniform.location;
-    out.members[i].elementCount = memberUniform.elementCount;
+    out.members[i].name          = memberUniform.name;
+    out.members[i].binding       = block.binding;
+    out.members[i].uniformClass  = Graphics::UniformClass::UNIFORM;
+    out.members[i].offset        = memberUniform.offset;
+    out.members[i].location      = memberUniform.location;
+    out.members[i].elementCount  = memberUniform.elementCount;
+    out.members[i].elementStride = memberUniform.elementStride;
   }
 
   return true;