From 81d18d371252d46e77ac38f52b1429a7efbf55fe Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Tue, 25 Jun 2024 12:29:06 +0100 Subject: [PATCH] GLES reflection supports array element stride for UBO members. Change-Id: Ic703df5c5909d7b56de3d5870fb18b3b2adda3f4 --- .../test-graphics-controller.h | 76 ++++++++++++++++++++++ .../test-graphics-reflection.cpp | 15 +++-- .../test-graphics-reflection.h | 3 +- .../gles-impl/gles-graphics-reflection.cpp | 39 +++++++++-- 4 files changed, 119 insertions(+), 14 deletions(-) diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h index 6066f67..e21c304 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h @@ -442,9 +442,85 @@ public: // Test Functions mCustomUniforms = customUniforms; } + constexpr std::pair 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() diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp index 22d09e1..2d507f7 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp @@ -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; diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.h index b598435..3521ed0 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-reflection.h @@ -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 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 diff --git a/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp b/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp index 27e2b3b..5766dc7 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp @@ -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; -- 2.7.4