From: Richard Huang Date: Mon, 11 Apr 2022 15:35:53 +0000 (+0100) Subject: Sort samplers in vertex shader first and then fragment shader X-Git-Tag: dali_2.1.18~2^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=cce86445ae0848ad7466064fcce71411c1feae2e Sort samplers in vertex shader first and then fragment shader Change-Id: Ic46d65f219d5b0784ba969650fccc02de926639f --- diff --git a/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp b/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp index 05a803d..05776c2 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp @@ -33,6 +33,35 @@ namespace { +struct StringSize +{ + const char* const mString; + const uint32_t mLength; + + template + constexpr StringSize(const char (&string)[kLength]) + : mString(string), + mLength(kLength - 1) // remove terminating null; N.B. there should be no other null. + { + } + + operator const char*() const + { + return mString; + } +}; + +bool operator==(const StringSize& lhs, const char* rhs) +{ + return strncmp(lhs.mString, rhs, lhs.mLength) == 0; +} + +const char* const DELIMITERS = " \t\n"; +constexpr StringSize UNIFORM{"uniform"}; +constexpr StringSize SAMPLER_PREFIX{"sampler"}; +constexpr StringSize SAMPLER_TYPES[] = {"2D", "Cube", "ExternalOES"}; +constexpr auto END_SAMPLER_TYPES = SAMPLER_TYPES + std::extent::value; + Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeTypeFormat(GLenum type) { switch(type) @@ -94,34 +123,68 @@ bool SortUniformExtraInfoByLocation(Dali::Graphics::GLES::Reflection::UniformExt return a.location < b.location; } -struct StringSize +std::string GetShaderSource(Dali::Graphics::ShaderState shaderState) { - const char* const mString; - const uint32_t mLength; + std::vector data; + auto* shader = static_cast(shaderState.shader); + auto& shaderCreateInfo = shader->GetCreateInfo(); + data.resize(shaderCreateInfo.sourceSize + 1); + std::memcpy(&data[0], shaderCreateInfo.sourceData, shaderCreateInfo.sourceSize); + data[shaderCreateInfo.sourceSize] = 0; - template - constexpr StringSize(const char (&string)[kLength]) - : mString(string), - mLength(kLength - 1) // remove terminating null; N.B. there should be no other null. - { - } + return std::string(reinterpret_cast(&data[0])); +} - operator const char*() const +void ParseShaderSamplers(std::string shaderSource, std::vector& uniformOpaques, int& samplerPosition, std::vector& samplerPositions) +{ + if(!shaderSource.empty()) { - return mString; - } -}; + char* shaderStr = strdup(shaderSource.c_str()); + char* uniform = strstr(shaderStr, UNIFORM); -bool operator==(const StringSize& lhs, const char* rhs) -{ - return strncmp(lhs.mString, rhs, lhs.mLength) == 0; -} + while(uniform) + { + char* outerToken = strtok_r(uniform + UNIFORM.mLength, ";", &uniform); -const char* const DELIMITERS = " \t\n"; -constexpr StringSize UNIFORM{"uniform"}; -constexpr StringSize SAMPLER_PREFIX{"sampler"}; -constexpr StringSize SAMPLER_TYPES[] = {"2D", "Cube", "ExternalOES"}; -constexpr auto END_SAMPLER_TYPES = SAMPLER_TYPES + std::extent::value; + char* nextPtr = nullptr; + char* token = strtok_r(outerToken, DELIMITERS, &nextPtr); + while(token) + { + if(SAMPLER_PREFIX == token) + { + token += SAMPLER_PREFIX.mLength; + if(std::find(SAMPLER_TYPES, END_SAMPLER_TYPES, token) != END_SAMPLER_TYPES) + { + bool found(false); + token = strtok_r(nullptr, DELIMITERS, &nextPtr); + + for(uint32_t i = 0; i < static_cast(uniformOpaques.size()); ++i) + { + if(samplerPositions[i] == -1 && + strncmp(token, uniformOpaques[i].name.c_str(), uniformOpaques[i].name.size()) == 0) + { + samplerPositions[i] = uniformOpaques[i].offset = samplerPosition++; + found = true; + break; + } + } + + if(!found) + { + DALI_LOG_ERROR("Sampler uniform %s declared but not used in the shader\n", token); + } + break; + } + } + + token = strtok_r(nullptr, DELIMITERS, &nextPtr); + } + + uniform = strstr(uniform, UNIFORM); + } + free(shaderStr); + } +} } // anonymous namespace @@ -591,71 +654,27 @@ void Reflection::SortOpaques() auto& programCreateInfo = mProgram.GetCreateInfo(); std::vector data; + std::string vertShader; std::string fragShader; for(auto& shaderState : *programCreateInfo.shaderState) { - if(shaderState.pipelineStage == PipelineStage::FRAGMENT_SHADER) + if(shaderState.pipelineStage == PipelineStage::VERTEX_SHADER) { - auto* shader = static_cast(shaderState.shader); - auto& shaderCreateInfo = shader->GetCreateInfo(); - data.resize(shaderCreateInfo.sourceSize + 1); - std::memcpy(&data[0], shaderCreateInfo.sourceData, shaderCreateInfo.sourceSize); - data[shaderCreateInfo.sourceSize] = 0; - fragShader = std::string(reinterpret_cast(&data[0])); - break; + vertShader = GetShaderSource(shaderState); } - } - - if(!fragShader.empty()) - { - char* shaderStr = strdup(fragShader.c_str()); - char* uniform = strstr(shaderStr, UNIFORM); - int samplerPosition = 0; - std::vector samplerPositions(mUniformOpaques.size(), -1); - - while(uniform) + else if(shaderState.pipelineStage == PipelineStage::FRAGMENT_SHADER) { - char* outerToken = strtok_r(uniform + UNIFORM.mLength, ";", &uniform); - - char* nextPtr = nullptr; - char* token = strtok_r(outerToken, DELIMITERS, &nextPtr); - while(token) - { - if(SAMPLER_PREFIX == token) - { - token += SAMPLER_PREFIX.mLength; - if(std::find(SAMPLER_TYPES, END_SAMPLER_TYPES, token) != END_SAMPLER_TYPES) - { - bool found(false); - token = strtok_r(nullptr, DELIMITERS, &nextPtr); - - for(uint32_t i = 0; i < static_cast(mUniformOpaques.size()); ++i) - { - if(samplerPositions[i] == -1 && - strncmp(token, mUniformOpaques[i].name.c_str(), mUniformOpaques[i].name.size()) == 0) - { - samplerPositions[i] = mUniformOpaques[i].offset = samplerPosition++; - found = true; - break; - } - } + fragShader = GetShaderSource(shaderState); + } + } - if(!found) - { - DALI_LOG_ERROR("Sampler uniform %s declared but not used in the shader\n", token); - } - break; - } - } + int samplerPosition = 0; + std::vector samplerPositions(mUniformOpaques.size(), -1); - token = strtok_r(nullptr, DELIMITERS, &nextPtr); - } + ParseShaderSamplers(vertShader, mUniformOpaques, samplerPosition, samplerPositions); + ParseShaderSamplers(fragShader, mUniformOpaques, samplerPosition, samplerPositions); - uniform = strstr(uniform, UNIFORM); - } - free(shaderStr); - } std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), [](const UniformInfo& a, const UniformInfo& b) { return a.offset < b.offset; }); }