[Fix] (MG_State/ProgramState): Handle version directive in shader source.

This commit is contained in:
BZLZHH
2025-11-01 10:07:36 +08:00
parent 9b0589840b
commit 8da681c720
4 changed files with 66 additions and 0 deletions
+1
View File
@@ -56,6 +56,7 @@ set(SOURCE_FILES
MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp
MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp
MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp
@@ -1,6 +1,8 @@
#include "ShaderObject.h"
#include <MG_Util/ShaderTranspiler/Types.h>
#include <MG_Util/ShaderTranspiler/ShaderCompiler.h>
#include <MG_Util/Converters/MGToGL/ProgramEnumConverter.h>
#include <MG_Util/ShaderTranspiler/ShaderSourceProcessor.h>
#include <MG_Util/ShaderTranspiler/glslang/UniformTraverser.h>
namespace MobileGL {
@@ -16,6 +18,7 @@ namespace MobileGL {
void ShaderObject::Compile() {
using namespace MG_Util::ShaderTranspiler;
MG_Util::ShaderTranspiler::PreprocessShaderSource(m_stage, m_source);
// Compile for OpenGL here, so that we can do validation and link
// like a real OpenGL driver at linking stage
@@ -0,0 +1,45 @@
#include "ShaderSourceProcessor.h"
namespace MobileGL {
namespace MG_Util {
namespace ShaderTranspiler {
void PreprocessShaderSource(ShaderStage stage, String& source) {
ShaderProfile profile = ShaderProfile::Core;
SizeT versionPos = source.find("#version");
if (versionPos != String::npos) {
SizeT lineEnd = source.find('\n', versionPos);
String versionLine = source.substr(versionPos, lineEnd - versionPos);
if (versionLine.find("ES") != String::npos)
profile = ShaderProfile::ES;
else if (versionLine.find("compatibility") != String::npos)
profile = ShaderProfile::Compatibility;
else
profile = ShaderProfile::Core;
} else {
profile = ShaderProfile::Core;
source.insert(0, "#version 460 core\n");
return;
}
SizeT firstLineEnd = source.find('\n');
if (profile != ShaderProfile::ES) {
constexpr const char* versionDirectiveCore = "#version 460 core\n";
constexpr const char* versionDirectiveCompat = "#version 460 compatibility\n";
const char* replacement =
(profile == ShaderProfile::Compatibility) ? versionDirectiveCompat : versionDirectiveCore;
if (firstLineEnd != std::string::npos) {
source.replace(0, firstLineEnd + 1, replacement);
} else {
source = replacement;
}
}
}
} // namespace ShaderTranspiler
} // namespace MG_Util
} // namespace MobileGL
@@ -0,0 +1,17 @@
#pragma once
#include <Includes.h>
#include <MG_State/GLState/ProgramState/ShaderObject.h>
namespace MobileGL {
enum class ShaderProfile {
Core,
Compatibility,
ES,
};
namespace MG_Util {
namespace ShaderTranspiler {
void PreprocessShaderSource(ShaderStage stage, String& source);
} // namespace ShaderTranspiler
} // namespace MG_Util
} // namespace MobileGL