From fee7fed1d0921fc1ed97af918cdf6926a2e6a348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 8 Jan 2025 09:53:46 -0300 Subject: [PATCH] add in/out varyings to materials in gldefs --- .../postprocessing/hw_useruniforms.h | 7 +++ .../rendering/vulkan/shaders/vk_shader.cpp | 26 ++++++-- .../rendering/vulkan/shaders/vk_shader.h | 4 +- src/common/textures/textures.h | 1 + src/r_data/gldefs.cpp | 62 +++++++++++++++++++ 5 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/common/rendering/hwrenderer/postprocessing/hw_useruniforms.h b/src/common/rendering/hwrenderer/postprocessing/hw_useruniforms.h index 968383de2..9e307a0e2 100644 --- a/src/common/rendering/hwrenderer/postprocessing/hw_useruniforms.h +++ b/src/common/rendering/hwrenderer/postprocessing/hw_useruniforms.h @@ -42,6 +42,13 @@ struct UniformFieldDesc std::size_t Offset; }; +struct VaryingFieldDesc +{ + FString Name; + FString Property; + UniformType Type; +}; + struct UniformField { UniformType Type = UniformType::Undefined; diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 9e8b2621f..c16390c9d 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -163,9 +163,9 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key) const FString& name = ExtractFileBase(desc.shader.GetChars()); FString defines = defaultshaders[desc.shaderType].Defines + desc.defines; - program.vert = LoadVertShader(name, mainvp, desc.vertshader.IsEmpty() ? vert_nocustom : desc.vertshader.GetChars(), defines.GetChars(), key, &desc.Uniforms); + program.vert = LoadVertShader(name, mainvp, desc.vertshader.IsEmpty() ? vert_nocustom : desc.vertshader.GetChars(), defines.GetChars(), key, &desc); if (!key.NoFragmentShader) - program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump_shared, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key, &desc.Uniforms); + program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump_shared, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key, &desc); desc.Uniforms.WriteUniforms(program.Uniforms); } @@ -201,7 +201,7 @@ static void addPushConstants(FString &layoutBlock, const UserUniforms *uniforms) } -std::unique_ptr VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserUniforms *uniforms) +std::unique_ptr VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader) { FString definesBlock; definesBlock << defines; @@ -222,10 +222,17 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername definesBlock << "#define USE_LEVELMESH\n"; FString layoutBlock; - addPushConstants(layoutBlock, uniforms); + addPushConstants(layoutBlock, shader ? &shader->Uniforms : nullptr); layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars() << "\n"; layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_vert.glsl").GetChars() << "\n"; + int varyingLocation = 11; + if(shader) for(auto &varying : shader->Varyings) + { + layoutBlock.AppendFormat("layout(location = %d) %s out %s %s;\n", varyingLocation, varying.Property.GetChars(), GetTypeStr(varying.Type), varying.Name.GetChars()); + varyingLocation++; + } + FString codeBlock; codeBlock << LoadPrivateShaderLump(vert_lump).GetChars() << "\n"; @@ -243,7 +250,7 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername .Create(shadername.GetChars(), fb->GetDevice()); } -std::unique_ptr VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *light_lump, const char *defines, const VkShaderKey& key, const UserUniforms *uniforms) +std::unique_ptr VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *light_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader) { FString definesBlock; if (fb->IsRayQueryEnabled()) definesBlock << "\n#define SUPPORTS_RAYQUERY\n"; @@ -331,10 +338,17 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername else definesBlock << "#define uFogEnabled 0\n"; FString layoutBlock; - addPushConstants(layoutBlock, uniforms); + addPushConstants(layoutBlock, shader ? &shader->Uniforms : nullptr); layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars() << "\n"; layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_frag.glsl").GetChars() << "\n"; + int varyingLocation = 11; + if(shader) for(auto &varying : shader->Varyings) + { + layoutBlock.AppendFormat("layout(location = %d) %s in %s %s;\n", varyingLocation, varying.Property.GetChars(), GetTypeStr(varying.Type), varying.Name.GetChars()); + varyingLocation++; + } + FString codeBlock; codeBlock << LoadPrivateShaderLump(frag_lump).GetChars() << "\n"; diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index 4c83f53a6..9ec499fab 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -150,8 +150,8 @@ public: VulkanShader* GetLightTilesShader() { return LightTiles.get(); } private: - std::unique_ptr LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserUniforms *uniforms); - std::unique_ptr LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *lightmodel_lump, const char *defines, const VkShaderKey& key, const UserUniforms *uniforms); + std::unique_ptr LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader); + std::unique_ptr LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *lightmodel_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader); ShaderIncludeResult OnInclude(FString headerName, FString includerName, size_t depth, bool system); diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index 4f4c13618..d88422ca8 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -114,6 +114,7 @@ struct UserShaderDesc bool disablealphatest = false; uint8_t shaderFlags = 0; + std::vector Varyings; UserUniforms Uniforms; }; diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 120aea0ca..33130f041 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -1634,6 +1634,68 @@ class GLDefsParser hasUniforms = true; ParseShaderUniform(Uniforms, usershaders.Size(), false, is_globalshader ? globaltargets.Size() : 1); } + else if (sc.Compare("varying")) + { + isProperty = true; + bool ok = true; + + sc.MustGetString(); + FString varyingProperty = ""; + + if (sc.Compare("noperspective")) + { + varyingProperty = "noperspective"; + sc.MustGetString(); + } + else if (sc.Compare("flat") == 0) + { + varyingProperty = "flat"; + sc.MustGetString(); + } + else + { + varyingProperty = ""; + } + + FString varyingType = sc.String; + varyingType.ToLower(); + + sc.MustGetString(); + FString varyingName = sc.String; + + UniformType parsedType = UniformType::Undefined; + + if (varyingType.Compare("int") == 0) + { + parsedType = UniformType::Int; + } + else if (varyingType.Compare("float") == 0) + { + parsedType = UniformType::Float; + } + else if (varyingType.Compare("vec2") == 0) + { + parsedType = UniformType::Vec2; + } + else if (varyingType.Compare("vec3") == 0) + { + parsedType = UniformType::Vec3; + } + else if (varyingType.Compare("vec4") == 0) + { + parsedType = UniformType::Vec4; + } + else + { + sc.ScriptError("Unrecognized varying type '%s'", sc.String); + ok = false; + } + + if(ok) + { + usershader.Varyings.push_back({varyingName, varyingProperty, parsedType}); + } + } else if (sc.Compare("texture")) { isProperty = true;