diff --git a/gapis/api/gles/compat.go b/gapis/api/gles/compat.go index ee99859b71..c67f15fc41 100644 --- a/gapis/api/gles/compat.go +++ b/gapis/api/gles/compat.go @@ -415,6 +415,7 @@ func compat(ctx context.Context, device *device.Instance, onError onCompatError) ShaderType: st, Relaxed: true, // find_issues will still report bad GLSL. StripOptimizations: true, + TargetGLSLVersion: version.MaxGLSL().AsInt(), } // Trim any prefix whitespace / newlines. diff --git a/gapis/api/gles/find_issues.go b/gapis/api/gles/find_issues.go index 7929d0c169..738c9d6e14 100644 --- a/gapis/api/gles/find_issues.go +++ b/gapis/api/gles/find_issues.go @@ -170,6 +170,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o ShaderType: st, CheckAfterChanges: true, Disassemble: true, + TargetGLSLVersion: 430, } if _, err := shadertools.ConvertGlsl(shader.Source, &opts); err != nil { diff --git a/gapis/api/gles/version.go b/gapis/api/gles/version.go index a74af668e0..f1628c34c6 100644 --- a/gapis/api/gles/version.go +++ b/gapis/api/gles/version.go @@ -51,44 +51,46 @@ func (v Version) AtLeastGL(major, minor int) bool { return !v.IsES && v.AtLeast(major, minor) } -var versionRe = regexp.MustCompile(`^(OpenGL ES.*? )?(\d+)\.(\d+).*`) - -// ParseVersion parses the GL version major, minor and flavour from the output of glGetString(GL_VERSION). -func ParseVersion(str string) (*Version, error) { - if match := versionRe.FindStringSubmatch(str); match != nil { - isES := len(match[1]) > 0 // Desktop GL doesn't have a flavour prefix. - major, _ := strconv.Atoi(match[2]) - minor, _ := strconv.Atoi(match[3]) - return &Version{IsES: isES, Major: major, Minor: minor}, nil - } - return nil, fmt.Errorf("Unknown GL_VERSION format: %s", str) -} - -// GLSLVersion returns the highest supported GLSL version for the given GL version. -func GLSLVersion(glVersion string) (Version, error) { - v, err := ParseVersion(glVersion) - if err != nil { - return Version{}, err - } +// MaxGLSL returns the highest supported GLSL version for the given GL version. +func (v Version) MaxGLSL() Version { major, minor, isES := v.Major, v.Minor, v.IsES switch { case major == 2 && isES: - return Version{Major: 1, Minor: 0}, nil + return Version{Major: 1, Minor: 0} case major == 3 && isES: - return Version{Major: 3, Minor: 0}, nil + return Version{Major: 3, Minor: 0} case major == 2 && minor == 0 && !isES: - return Version{Major: 1, Minor: 1}, nil + return Version{Major: 1, Minor: 1} case major == 2 && minor == 1 && !isES: - return Version{Major: 1, Minor: 2}, nil + return Version{Major: 1, Minor: 2} case major == 3 && minor == 0 && !isES: - return Version{Major: 1, Minor: 3}, nil + return Version{Major: 1, Minor: 3} case major == 3 && minor == 1 && !isES: - return Version{Major: 1, Minor: 4}, nil + return Version{Major: 1, Minor: 4} case major == 3 && minor == 2 && !isES: - return Version{Major: 1, Minor: 5}, nil + return Version{Major: 1, Minor: 5} default: - return Version{Major: major, Minor: minor}, nil + return Version{Major: major, Minor: minor} } } + +// AsInt returns the version in the form Mmm, where M is the major version and +// m is the minor version. +func (v Version) AsInt() int { + return v.Major*100 + v.Minor*10 +} + +var versionRe = regexp.MustCompile(`^(OpenGL ES.*? )?(\d+)\.(\d+).*`) + +// ParseVersion parses the GL version major, minor and flavour from the output of glGetString(GL_VERSION). +func ParseVersion(str string) (*Version, error) { + if match := versionRe.FindStringSubmatch(str); match != nil { + isES := len(match[1]) > 0 // Desktop GL doesn't have a flavour prefix. + major, _ := strconv.Atoi(match[2]) + minor, _ := strconv.Atoi(match[3]) + return &Version{IsES: isES, Major: major, Minor: minor}, nil + } + return nil, fmt.Errorf("Unknown GL_VERSION format: %s", str) +} diff --git a/gapis/shadertools/cc/libmanager.cpp b/gapis/shadertools/cc/libmanager.cpp index e43b644f0e..9ab3e0e977 100644 --- a/gapis/shadertools/cc/libmanager.cpp +++ b/gapis/shadertools/cc/libmanager.cpp @@ -292,7 +292,8 @@ code_with_debug_info_t* convertGlsl(const char* input, size_t length, const conv strcpy(result->disassembly_string, tmp.c_str()); } - std::string source = spirv2glsl(std::move(spirv_new), options->strip_optimizations); + std::string source = spirv2glsl(std::move(spirv_new), + options->target_glsl_version, options->strip_optimizations); result->source_code = new char[source.length() + 1]; strcpy(result->source_code, source.c_str()); diff --git a/gapis/shadertools/cc/libmanager.h b/gapis/shadertools/cc/libmanager.h index 159f49bc12..810b10d437 100644 --- a/gapis/shadertools/cc/libmanager.h +++ b/gapis/shadertools/cc/libmanager.h @@ -76,6 +76,7 @@ typedef struct convert_options_t { bool disassemble; bool relaxed; bool strip_optimizations; + int target_glsl_version; } convert_options_t; typedef struct compile_options_t { diff --git a/gapis/shadertools/cc/spirv2glsl.cpp b/gapis/shadertools/cc/spirv2glsl.cpp index 05c4e3a6a0..e7bccbcc99 100644 --- a/gapis/shadertools/cc/spirv2glsl.cpp +++ b/gapis/shadertools/cc/spirv2glsl.cpp @@ -21,10 +21,10 @@ // so it is important we never include both at the same time. #include "third_party/SPIRV-Cross/spirv_glsl.hpp" -std::string spirv2glsl(std::vector spirv, bool strip_optimizations) { +std::string spirv2glsl(std::vector spirv, int glsl_version, bool strip_optimizations) { spirv_cross::CompilerGLSL glsl(std::move(spirv)); spirv_cross::CompilerGLSL::Options cross_options; - cross_options.version = 330; + cross_options.version = glsl_version == 0 ? 330 : glsl_version; cross_options.es = false; cross_options.force_temporary = false; cross_options.vertex.fixup_clipspace = false; diff --git a/gapis/shadertools/cc/spirv2glsl.h b/gapis/shadertools/cc/spirv2glsl.h index 8832c0799a..9d3c56a1f7 100644 --- a/gapis/shadertools/cc/spirv2glsl.h +++ b/gapis/shadertools/cc/spirv2glsl.h @@ -17,4 +17,4 @@ #include #include -std::string spirv2glsl(std::vector spirv, bool strip_optimizations); +std::string spirv2glsl(std::vector spirv, int glsl_version, bool strip_optimizations); diff --git a/gapis/shadertools/shadertools.go b/gapis/shadertools/shadertools.go index bf46531dcd..a8f09a8761 100644 --- a/gapis/shadertools/shadertools.go +++ b/gapis/shadertools/shadertools.go @@ -117,6 +117,8 @@ func (t ShaderType) String() string { type ConvertOptions struct { // The type of shader. ShaderType ShaderType + // The target GLSL version (default 330). + TargetGLSLVersion int // Shader source preamble. Preamble string // Whether to add prefix to all non-builtin symbols. @@ -175,6 +177,7 @@ func ConvertGlsl(source string, o *ConvertOptions) (CodeWithDebugInfo, error) { disassemble: C.bool(o.Disassemble), relaxed: C.bool(o.Relaxed), strip_optimizations: C.bool(o.StripOptimizations), + target_glsl_version: C.int(o.TargetGLSLVersion), } result := C.convertGlsl(cstr(source), C.size_t(len(source)), &opts) defer C.deleteGlslCodeWithDebug(result) diff --git a/gapis/shadertools/shadertools_test.go b/gapis/shadertools/shadertools_test.go index b08d6bbb25..92efb56da7 100644 --- a/gapis/shadertools/shadertools_test.go +++ b/gapis/shadertools/shadertools_test.go @@ -59,6 +59,7 @@ void main() ShaderType: shadertools.TypeFragment, CheckAfterChanges: true, StripOptimizations: true, + TargetGLSLVersion: 330, }, `#version 310 es layout(early_fragment_tests) in;