From 2fb069080481bfbdb3383f616dbc7784d0a123d7 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Mon, 9 Jun 2025 13:38:16 +0800 Subject: [PATCH] [Fix] (Diligent/PSO): Try to bind input layout locations for GLSL. --- .../Implementations/EGL/Diligent/EGL_impl.cpp | 67 ++++++++++++++- .../Implementations/EGL/Diligent/EGL_impl.h | 42 +-------- .../Implementations/GL/Program/GL_Program.cpp | 36 +++++++- MG/MG_UTIL/Program/GLSLTool.cpp | 86 +++++++++++++++++++ MG/MG_UTIL/Program/GLSLTool.h | 3 + 5 files changed, 186 insertions(+), 48 deletions(-) diff --git a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp index fb8f1067..cde0a9f9 100644 --- a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp +++ b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp @@ -87,6 +87,50 @@ namespace MG_Diligent { } } + uint64_t PipelineStateManager::CalculateStateHash( + CommonState &commonState, + VertexArrayState &vaState, + GLFramebufferInfo& fbInfo) { + uint64_t hash = 0; + + MG_Global::unordered_map capabilities = commonState.capabilities; + + hash ^= std::hash()(commonState.blendSrcRGB); + hash ^= std::hash()(commonState.blendDstRGB); + hash ^= std::hash()(commonState.blendSrcAlpha); + hash ^= std::hash()(commonState.blendDstAlpha); + hash ^= std::hash()(capabilities[GL_BLEND]); + + hash ^= std::hash()(commonState.depthFunc); + hash ^= std::hash()(commonState.depthMask); + hash ^= std::hash()(capabilities[GL_DEPTH_TEST]); + + hash ^= std::hash()(0); // TODO: Cull Face Mode + hash ^= std::hash()(capabilities[GL_CULL_FACE]); + + hash ^= std::hash()(capabilities[GL_STENCIL_TEST]); + + auto *pVAO = vaState.GetCurrentVAO(); + for (const auto &[index, attrib]: pVAO->attribs) { + if (attrib.enabled) { + hash ^= std::hash()(index); + hash ^= std::hash()(attrib.size); + hash ^= std::hash()(attrib.type); + hash ^= std::hash()(attrib.normalized); + } + } + + hash ^= std::hash()(fbInfo.ColorRTVs.size()); + for (const auto& rtv : fbInfo.ColorRTVs) { + if (rtv) { + hash ^= std::hash()(rtv->GetDesc().Format); + } + } + + hash ^= std::hash()(fbInfo.DepthStencilFormat); + + return hash; + } void PipelineStateManager::ConfigurePSO( Diligent::GraphicsPipelineStateCreateInfo &PSOCreateInfo, @@ -311,9 +355,26 @@ namespace MG_Diligent { for (GLuint shaderId : programObj.attachedShaders) { auto it = MG_State_T::programState->shaders_.find(shaderId); - if (it != MG_State_T::programState->shaders_.end() && - !it->second.markedForDeletion) { - shaderSourcesMap[it->first] = it->second.source; + if (it != MG_State_T::programState->shaders_.end() && !it->second.markedForDeletion) { + std::string shaderSource; + if (it->second.type == GL_VERTEX_SHADER) { + std::string infoLog; + auto spirv = + MG_Util::Program::CompileGLSLToSPIRV(it->second.type, + it->second.source, + infoLog); + if (spirv.empty()) { + MG_Util::Debug::LogE("Failed to compile shader %u: %s", shaderId, + infoLog.c_str()); + continue; + } + + shaderSource = MG_Util::Program::BindInputLayoutLocationsForGLSL(spirv, + programObj.attribLocations); + } else { + shaderSource = it->second.source; + } + shaderSourcesMap[it->first] = shaderSource; } } diff --git a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.h b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.h index 94d80752..4c226099 100644 --- a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.h +++ b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.h @@ -192,47 +192,7 @@ namespace MG_Diligent { uint64_t CalculateStateHash( CommonState &commonState, VertexArrayState &vaState, - GLFramebufferInfo& fbInfo) { - uint64_t hash = 0; - - MG_Global::unordered_map capabilities = commonState.capabilities; - - hash ^= std::hash()(commonState.blendSrcRGB); - hash ^= std::hash()(commonState.blendDstRGB); - hash ^= std::hash()(commonState.blendSrcAlpha); - hash ^= std::hash()(commonState.blendDstAlpha); - hash ^= std::hash()(capabilities[GL_BLEND]); - - hash ^= std::hash()(commonState.depthFunc); - hash ^= std::hash()(commonState.depthMask); - hash ^= std::hash()(capabilities[GL_DEPTH_TEST]); - - hash ^= std::hash()(0); // TODO: Cull Face Mode - hash ^= std::hash()(capabilities[GL_CULL_FACE]); - - hash ^= std::hash()(capabilities[GL_STENCIL_TEST]); - - auto *pVAO = vaState.GetCurrentVAO(); - for (const auto &[index, attrib]: pVAO->attribs) { - if (attrib.enabled) { - hash ^= std::hash()(index); - hash ^= std::hash()(attrib.size); - hash ^= std::hash()(attrib.type); - hash ^= std::hash()(attrib.normalized); - } - } - - hash ^= std::hash()(fbInfo.ColorRTVs.size()); - for (const auto& rtv : fbInfo.ColorRTVs) { - if (rtv) { - hash ^= std::hash()(rtv->GetDesc().Format); - } - } - - hash ^= std::hash()(fbInfo.DepthStencilFormat); - - return hash; - } + GLFramebufferInfo& fbInfo); void ConfigurePSO( Diligent::GraphicsPipelineStateCreateInfo &PSOCreateInfo, diff --git a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp index 5d938990..8b29b99e 100644 --- a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp +++ b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp @@ -224,6 +224,11 @@ namespace MG_GL::GL { void ShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint* length) { MG_Util::Debug::LogD("glShaderSource, shader: %u, count: %d", shader, count); + if (count > 0 && string != nullptr && string[0] != nullptr) { + MG_Util::Debug::LogD("Shader source for shader %u:\n%s", shader, string[0]); + } else { + MG_Util::Debug::LogD("Shader source for shader %u is empty or null.", shader); + } GLenum result = MG_State::UploadShaderSource(shader, count, (const GLchar **)string, length); if (result == GL_NO_ERROR) return; MG_State::SetError(result); @@ -251,13 +256,36 @@ namespace MG_GL::GL { } MG_Global::unordered_map shaderSources; - for (GLuint shaderId : programInfo.AttachedShadersID) { - auto& shaderObj = MG_State_T::programState->shaders_[shaderId]; - shaderSources[shaderId] = shaderObj.source; + for (GLuint shaderId : programObj.attachedShaders) { + auto it = MG_State_T::programState->shaders_.find(shaderId); + if (it != MG_State_T::programState->shaders_.end() && !it->second.markedForDeletion) { + std::string shaderSource; + if (it->second.type == GL_VERTEX_SHADER) { + std::string infoLog; + auto spirv = + MG_Util::Program::CompileGLSLToSPIRV(it->second.type, + it->second.source, + infoLog); + if (spirv.empty()) { + MG_Util::Debug::LogE("Failed to compile shader %u: %s", shaderId, + infoLog.c_str()); + continue; + } + + shaderSource = MG_Util::Program::BindInputLayoutLocationsForGLSL(spirv, + programObj.attribLocations); + } else { + shaderSource = it->second.source; + } + shaderSources[it->first] = shaderSource; + } } MG_Util::Program::GenerateDefaultUBOForGLSL_Multi(shaderSources, programInfo.uniformBufferNames); - + MG_Util::Debug::LogD("Shader sources after UBO generation for program %u:", program); + for (const auto& [shaderId, source] : shaderSources) { + MG_Util::Debug::LogD(" Program %u Shader %u:\n%s", program, shaderId, source.c_str()); + } // Compile attached shaders for (GLuint shaderId : programInfo.AttachedShadersID) { auto& shaderObj = MG_State_T::programState->shaders_[shaderId]; diff --git a/MG/MG_UTIL/Program/GLSLTool.cpp b/MG/MG_UTIL/Program/GLSLTool.cpp index d7784c4e..9417a6ad 100644 --- a/MG/MG_UTIL/Program/GLSLTool.cpp +++ b/MG/MG_UTIL/Program/GLSLTool.cpp @@ -5,6 +5,92 @@ #include "GLSLTool.h" namespace MG_Util::Program { + std::string BindInputLayoutLocationsForGLSL(const std::vector& spirv, + const MG_Global::unordered_map& + name_location_map) { + spvc_context context = nullptr; + spvc_parsed_ir ir = nullptr; + spvc_compiler compiler = nullptr; + spvc_resources resources = nullptr; + spvc_result result = SPVC_SUCCESS; + const char* glsl_source = nullptr; + std::string output_glsl; + + if ((result = spvc_context_create(&context)) != SPVC_SUCCESS) { + return {}; + } + + if ((result = spvc_context_parse_spirv(context, spirv.data(), spirv.size(), &ir)) != SPVC_SUCCESS) { + spvc_context_destroy(context); + return {}; + } + + if ((result = spvc_context_create_compiler( + context, + SPVC_BACKEND_GLSL, + ir, + SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, + &compiler + )) != SPVC_SUCCESS) { + spvc_context_destroy(context); + return {}; + } + + if ((result = spvc_compiler_create_shader_resources(compiler, &resources)) != SPVC_SUCCESS) { + spvc_context_destroy(context); + return {}; + } + + const spvc_reflected_resource* inputs = nullptr; + size_t num_inputs = 0; + if ((result = spvc_resources_get_resource_list_for_type( + resources, + SPVC_RESOURCE_TYPE_STAGE_INPUT, + &inputs, + &num_inputs + )) != SPVC_SUCCESS) { + spvc_context_destroy(context); + return {}; + } + + std::unordered_map name_to_id; + for (size_t i = 0; i < num_inputs; i++) { + name_to_id[inputs[i].name] = inputs[i].id; + } + + for (const auto& [name, location] : name_location_map) { + auto it = name_to_id.find(name); + if (it == name_to_id.end()) { + spvc_context_destroy(context); + return {}; + } + + spvc_compiler_set_decoration( + compiler, + it->second, + SpvDecorationLocation, + location + ); + } + + spvc_compiler_options options = nullptr; + spvc_compiler_create_compiler_options(compiler, &options); + spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 450); + spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE); + spvc_compiler_install_compiler_options(compiler, options); + + if ((result = spvc_compiler_compile(compiler, &glsl_source)) != SPVC_SUCCESS) { + spvc_context_destroy(context); + return {}; + } + + output_glsl = glsl_source; + + spvc_context_destroy(context); + + return output_glsl; + } + static std::vector buildCommentMask(const std::string &src) { enum State { NORMAL, diff --git a/MG/MG_UTIL/Program/GLSLTool.h b/MG/MG_UTIL/Program/GLSLTool.h index fd9d0313..094063a6 100644 --- a/MG/MG_UTIL/Program/GLSLTool.h +++ b/MG/MG_UTIL/Program/GLSLTool.h @@ -182,6 +182,9 @@ namespace MG_Util::Program { std::string>& glslSources); void GenerateDefaultUBOForGLSL_Multi( MG_Global::unordered_map &shaderSources, std::vector& outUniformBufferNames); + std::string BindInputLayoutLocationsForGLSL(const std::vector& spirv, + const MG_Global::unordered_map& + name_location_map); } #endif //MOBILEGL_GLSLTOOL_H