From 26da1e1e09574ed6cbc07fab924c3862f69fe036 Mon Sep 17 00:00:00 2001 From: VladDoc Date: Thu, 11 Apr 2024 22:36:12 +0300 Subject: [PATCH 1/2] Shaders with absent #version directive to compile on linux via prepending of said directive --- src/hardware/hw_shaders.c | 103 +++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 36cbb5db9..32336d63f 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -448,6 +448,101 @@ void HWR_LoadAllCustomShaders(void) HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i])); } +static const char version_directives[][14] = { + "#version 330\n", + "#version 150\n", + "#version 140\n", + "#version 130\n", + "#version 120\n", + "#version 110\n", +}; + +static boolean HWR_VersionDirectiveExists(const char* source) +{ + return strncmp(source, "#version", 8) == 0; +} + +static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index) +{ + const UINT32 version_len = sizeof(version_directives[version_index]) - 1; + const UINT32 source_len = strlen(source); + + char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL); + + strcpy(result, version_directives[version_index]); + strcpy(result + version_len, source); + + return result; +} + +static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index) +{ + shader[9] = version_directives[version_index][9]; + shader[10] = version_directives[version_index][10]; + shader[11] = version_directives[version_index][11]; +} + +static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag) +{ + return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag); +} + +static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id) +{ + char* vert_shader = gl_shaders[shader_index].vertex; + char* frag_shader = gl_shaders[shader_index].fragment; + + boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader); + boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader); + + if(!vert_shader_version_exists) { + CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id)); + } + + if(!frag_shader_version_exists) { + CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id)); + } + + // try to compile as is + HWR_CompileShader(shader_index); + if (gl_shaders[shader_index].compiled) + return; + + // try each version directive + for(UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i) { + CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]); + + if(!vert_shader_version_exists) { + // first time reallocation would have to be made + if(i == 0) { + void* old = (void*)gl_shaders[shader_index].vertex; + vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i); + Z_Free(old); + } else { + HWR_ReplaceVersionInplace(vert_shader, i); + } + } + + if(!frag_shader_version_exists) { + if(i == 0) { + void* old = (void*)gl_shaders[shader_index].fragment; + frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i); + Z_Free(old); + } else { + HWR_ReplaceVersionInplace(frag_shader, i); + } + } + + HWR_CompileShader(shader_index); + if (gl_shaders[shader_index].compiled) { + CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n", + version_directives[i]); + CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n"); + return; + } + } +} + void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3) { UINT16 lump; @@ -610,7 +705,13 @@ skip_field: gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment); if (!gl_shaders[shader_index].vertex) gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex); - HWR_CompileShader(shader_index); + + if(!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment)) { + HWR_TryToCompileShaderWithImplicitVersion(shader_index, i); + } else { + HWR_CompileShader(shader_index); + } + if (!gl_shaders[shader_index].compiled) CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename); } From fb437a3c72184584aa3cb33e009758e3b122ecc7 Mon Sep 17 00:00:00 2001 From: VladDoc Date: Fri, 12 Apr 2024 20:37:17 +0300 Subject: [PATCH 2/2] white space fix --- src/hardware/hw_shaders.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 32336d63f..ee1e2acdf 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -468,11 +468,10 @@ static char* HWR_PrependVersionDirective(const char* source, UINT32 version_inde const UINT32 source_len = strlen(source); char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL); - strcpy(result, version_directives[version_index]); - strcpy(result + version_len, source); + strcpy(result + version_len, source); - return result; + return result; } static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index) @@ -514,6 +513,7 @@ static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 if(!vert_shader_version_exists) { // first time reallocation would have to be made + if(i == 0) { void* old = (void*)gl_shaders[shader_index].vertex; vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);