diff --git a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp index cde0a9f9..cdcdaa82 100644 --- a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp +++ b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp @@ -371,6 +371,7 @@ namespace MG_Diligent { shaderSource = MG_Util::Program::BindInputLayoutLocationsForGLSL(spirv, programObj.attribLocations); + MG_Util::Program::RenameGLSLBuiltinsForVulkan(shaderSource); } else { shaderSource = it->second.source; } diff --git a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp index 8b29b99e..6aab7dbf 100644 --- a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp +++ b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp @@ -277,6 +277,7 @@ namespace MG_GL::GL { } else { shaderSource = it->second.source; } + MG_Util::Program::RenameGLSLBuiltinsForVulkan(shaderSource); shaderSources[it->first] = shaderSource; } } diff --git a/MG/MG_GL/State/Program/ProgramState.cpp b/MG/MG_GL/State/Program/ProgramState.cpp index dc45098f..87ad9be9 100644 --- a/MG/MG_GL/State/Program/ProgramState.cpp +++ b/MG/MG_GL/State/Program/ProgramState.cpp @@ -176,9 +176,25 @@ GLint ProgramState::QueryProgramAttributeLocation(GLuint program, const GLchar* GLint loc = it->second; MG_Util::Debug::LogD("MG_State: Program: QueryProgramAttributeLocation success: %s -> %d", name, loc); return loc; + } else { + MG_Util::Debug::LogW("MG_State: Program: QueryProgramAttributeLocation warning: name '%s' not found, generating new one...", name); + // Find the next available location + GLint loc = (GLint)prog.attribLocations.size(); + bool locInUse; + do { + locInUse = false; + for (const auto& pair : prog.attribLocations) { + if (pair.second == loc) { + locInUse = true; + loc++; + break; + } + } + } while (locInUse); + prog.attribLocations[name] = loc; + MG_Util::Debug::LogD("MG_State: Program: QueryProgramAttributeLocation success: %s -> %d", name, loc); + return prog.attribLocations[name]; } - MG_Util::Debug::LogW("MG_State: Program: QueryProgramAttributeLocation warning: name '%s' not found", name); - return -1; } GLenum ProgramState::QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params) { diff --git a/MG/MG_UTIL/Program/GLSLTool.cpp b/MG/MG_UTIL/Program/GLSLTool.cpp index 9417a6ad..f63bcd98 100644 --- a/MG/MG_UTIL/Program/GLSLTool.cpp +++ b/MG/MG_UTIL/Program/GLSLTool.cpp @@ -5,8 +5,19 @@ #include "GLSLTool.h" namespace MG_Util::Program { - std::string BindInputLayoutLocationsForGLSL(const std::vector& spirv, - const MG_Global::unordered_map& + void RenameGLSLBuiltinsForVulkan(std::string &src) { + static const std::vector> rules = { + { std::regex(R"(\bgl_VertexID\b)"), "gl_VertexIndex" }, + { std::regex(R"(\bgl_InstanceID\b)"), "gl_InstanceIndex" } + }; + + for (auto &rule : rules) { + src = std::regex_replace(src, rule.first, rule.second); + } + } + + std::string BindInputLayoutLocationsForGLSL(std::vector& spirv, + MG_Global::unordered_map& name_location_map) { spvc_context context = nullptr; spvc_parsed_ir ir = nullptr; @@ -17,11 +28,13 @@ namespace MG_Util::Program { std::string output_glsl; if ((result = spvc_context_create(&context)) != SPVC_SUCCESS) { + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to create context."); return {}; } if ((result = spvc_context_parse_spirv(context, spirv.data(), spirv.size(), &ir)) != SPVC_SUCCESS) { spvc_context_destroy(context); + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to parse SPIR-V."); return {}; } @@ -33,11 +46,13 @@ namespace MG_Util::Program { &compiler )) != SPVC_SUCCESS) { spvc_context_destroy(context); + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to create compiler."); return {}; } if ((result = spvc_compiler_create_shader_resources(compiler, &resources)) != SPVC_SUCCESS) { spvc_context_destroy(context); + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to create shader resources."); return {}; } @@ -50,6 +65,7 @@ namespace MG_Util::Program { &num_inputs )) != SPVC_SUCCESS) { spvc_context_destroy(context); + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to get stage inputs."); return {}; } @@ -61,8 +77,8 @@ namespace MG_Util::Program { 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 {}; + MG_Util::Debug::LogW("[SPIRV-Cross] Input name not found in shader: %s", name.c_str()); + continue; } spvc_compiler_set_decoration( @@ -81,6 +97,8 @@ namespace MG_Util::Program { if ((result = spvc_compiler_compile(compiler, &glsl_source)) != SPVC_SUCCESS) { spvc_context_destroy(context); + MG_Util::Debug::LogE("[SPIRV-Cross] Failed to compile to GLSL: %s", + spvc_context_get_last_error_string(context)); return {}; } diff --git a/MG/MG_UTIL/Program/GLSLTool.h b/MG/MG_UTIL/Program/GLSLTool.h index 094063a6..f135f534 100644 --- a/MG/MG_UTIL/Program/GLSLTool.h +++ b/MG/MG_UTIL/Program/GLSLTool.h @@ -182,9 +182,10 @@ 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& + std::string BindInputLayoutLocationsForGLSL(std::vector& spirv, + MG_Global::unordered_map& name_location_map); + void RenameGLSLBuiltinsForVulkan(std::string &src); } #endif //MOBILEGL_GLSLTOOL_H