From 4362a85bbe7b3e8215109b2481bc16978691ad87 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 12:51:46 +0100 Subject: [PATCH 1/6] Fix "The Vulkan spec states" not getting muted --- libraries/ZVulkan/src/vulkaninstance.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/ZVulkan/src/vulkaninstance.cpp b/libraries/ZVulkan/src/vulkaninstance.cpp index 169dd6daa9..f34c9b3544 100644 --- a/libraries/ZVulkan/src/vulkaninstance.cpp +++ b/libraries/ZVulkan/src/vulkaninstance.cpp @@ -351,10 +351,13 @@ VkBool32 VulkanInstance::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT me if (parts.size() == 3) { msg = parts[2]; - size_t pos = msg.find(" The Vulkan spec states:"); + size_t pos = msg.find("The Vulkan spec states:"); if (pos != std::string::npos) msg = msg.substr(0, pos); + while (!msg.empty() && (msg.back() == '\n' || msg.back() == '\r' || msg.back() == ' ')) + msg.pop_back(); + if (callbackData->objectCount > 0) { msg += " ("; From f813ff517f0e8506ead2e72a39263c5057156b99 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 12:52:19 +0100 Subject: [PATCH 2/6] Fix BLAS vertex format (has to be XYZ and not XYZW) --- src/common/rendering/vulkan/vk_levelmesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/rendering/vulkan/vk_levelmesh.cpp b/src/common/rendering/vulkan/vk_levelmesh.cpp index 4da23e4434..45aeb19199 100644 --- a/src/common/rendering/vulkan/vk_levelmesh.cpp +++ b/src/common/rendering/vulkan/vk_levelmesh.cpp @@ -333,7 +333,7 @@ VkLevelMesh::BLAS VkLevelMesh::CreateBLAS(bool preferFastBuild, int indexOffset, accelStructBLDesc.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; accelStructBLDesc.flags = VK_GEOMETRY_OPAQUE_BIT_KHR; accelStructBLDesc.geometry.triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR }; - accelStructBLDesc.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; + accelStructBLDesc.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT; accelStructBLDesc.geometry.triangles.vertexData.deviceAddress = VertexBuffer->GetDeviceAddress(); accelStructBLDesc.geometry.triangles.vertexStride = sizeof(FFlatVertex); accelStructBLDesc.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32; From 02603370b573c0a047aa0fc18f0300356839a9fa Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 13:19:31 +0100 Subject: [PATCH 3/6] Fix how layout_shared is added to the shader --- src/common/rendering/vulkan/shaders/vk_shader.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 5d2387ca80..e0fea8f956 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -314,11 +314,6 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const int index = 0; AddBuiltinFields(layoutBlock, index, false, fragShaderOutputs, key, hasClipDistance); } - - layoutBlock << "#line 1\n"; - - layoutBlock << LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars() << "\n"; - } void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader) @@ -436,7 +431,6 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername FString layoutBlock; BuildLayoutBlock(layoutBlock, false, key, shader); - FString codeBlock; codeBlock << LoadPrivateShaderLump(vert_lump).GetChars() << "\n"; if(vert_lump_custom) @@ -469,7 +463,6 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername FString layoutBlock; BuildLayoutBlock(layoutBlock, true, key, shader); - FString codeBlock; codeBlock << LoadPrivateShaderLump(frag_lump).GetChars() << "\n"; @@ -554,6 +547,7 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername .AddSource("VersionBlock", GetVersionBlock().GetChars()) .AddSource("DefinesBlock", definesBlock.GetChars()) .AddSource("LayoutBlock", layoutBlock.GetChars()) + .AddSource("shaders/scene/layout_shared.glsl", layoutBlock.GetChars()) .AddSource("shaders/scene/includes.glsl", LoadPrivateShaderLump("shaders/scene/includes.glsl").GetChars()) .AddSource(mateffectname.GetChars(), mateffectBlock.GetChars()) .AddSource(materialname.GetChars(), materialBlock.GetChars()) From 4ff328e074867cfded912c12ca95b46df1a4ae3e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 13:22:38 +0100 Subject: [PATCH 4/6] Should have launched the app before committing the previous commit :) --- src/common/rendering/vulkan/shaders/vk_shader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index e0fea8f956..0e8a580437 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -448,7 +448,8 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername .DebugName(shadername.GetChars()) .AddSource("VersionBlock", GetVersionBlock().GetChars()) .AddSource("DefinesBlock", definesBlock.GetChars()) - .AddSource("shaders/scene/layout_shared.glsl", layoutBlock.GetChars()) + .AddSource("LayoutBlock", layoutBlock.GetChars()) + .AddSource("shaders/scene/layout_shared.glsl", LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars()) .AddSource(vert_lump_custom ? vert_lump_custom : vert_lump, codeBlock.GetChars()) .OnIncludeLocal([=](std::string headerName, std::string includerName, size_t depth) { return OnInclude(headerName.c_str(), includerName.c_str(), depth, false); }) .OnIncludeSystem([=](std::string headerName, std::string includerName, size_t depth) { return OnInclude(headerName.c_str(), includerName.c_str(), depth, true); }) @@ -547,7 +548,7 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername .AddSource("VersionBlock", GetVersionBlock().GetChars()) .AddSource("DefinesBlock", definesBlock.GetChars()) .AddSource("LayoutBlock", layoutBlock.GetChars()) - .AddSource("shaders/scene/layout_shared.glsl", layoutBlock.GetChars()) + .AddSource("shaders/scene/layout_shared.glsl", LoadPrivateShaderLump("shaders/scene/layout_shared.glsl").GetChars()) .AddSource("shaders/scene/includes.glsl", LoadPrivateShaderLump("shaders/scene/includes.glsl").GetChars()) .AddSource(mateffectname.GetChars(), mateffectBlock.GetChars()) .AddSource(materialname.GetChars(), materialBlock.GetChars()) From 68489d6bf07d90846042a850220da6b6e9ca1820 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 14:52:25 +0100 Subject: [PATCH 5/6] Fix the vertex attribute bindings --- .../vulkan/pipelines/vk_renderpass.cpp | 12 +------ .../vulkan/pipelines/vk_renderpass.h | 10 +++--- .../rendering/vulkan/shaders/vk_shader.cpp | 31 ++++++++++++++++--- .../rendering/vulkan/shaders/vk_shader.h | 4 ++- .../rendering/vulkan/vk_renderdevice.cpp | 2 +- .../rendering/vulkan/vk_renderstate.cpp | 2 +- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp index f293d47f83..de4c790fcd 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp @@ -309,7 +309,7 @@ std::unique_ptr VkRenderPassSetup::CreatePipeline(const VkPipeli if (program->frag) builder.AddFragmentShader(program->frag.get()); - const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat); + const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.ShaderKey.VertexFormat); for (int i = 0; i < vfmt.BufferStrides.size(); i++) builder.AddVertexBufferBinding(i, vfmt.BufferStrides[i]); @@ -325,20 +325,10 @@ std::unique_ptr VkRenderPassSetup::CreatePipeline(const VkPipeli VK_FORMAT_R32_SINT }; - bool inputLocations[VATTR_MAX] = {}; - for (size_t i = 0; i < vfmt.Attrs.size(); i++) { const auto &attr = vfmt.Attrs[i]; builder.AddVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset); - inputLocations[attr.location] = true; - } - - // Vulkan requires an attribute binding for each location specified in the shader - for (int i = 0; i < VATTR_MAX; i++) - { - if (!inputLocations[i]) - builder.AddVertexAttribute(i, 0, i != 8 ? VK_FORMAT_R32G32B32_SFLOAT : VK_FORMAT_R8G8B8A8_UINT, 0); } builder.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT); diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.h b/src/common/rendering/vulkan/pipelines/vk_renderpass.h index 433ba8a984..b1e114a92a 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.h +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.h @@ -40,13 +40,13 @@ class VkPipelineKey uint64_t AsQWORD = 0; }; - int VertexFormat = 0; - int Padding0 = 0; + int Padding1 = 0; + int Padding2 = 0; VkShaderKey ShaderKey; FRenderStyle RenderStyle; - int Padding1 = 0; // for 64 bit alignment + int Padding3 = 0; // for 64 bit alignment bool operator<(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) < 0; } bool operator==(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) == 0; } @@ -54,8 +54,8 @@ class VkPipelineKey }; static_assert(sizeof(FRenderStyle) == 4, "sizeof(FRenderStyle) is not its expected size!"); -static_assert(sizeof(VkShaderKey) == 16, "sizeof(VkShaderKey) is not its expected size!"); -static_assert(sizeof(VkPipelineKey) == 16 + 16 + 8, "sizeof(VkPipelineKey) is not its expected size!"); // If this assert fails, the flags union no longer adds up to 64 bits. Or there are gaps in the class so the memcmp doesn't work. +static_assert(sizeof(VkShaderKey) == 24, "sizeof(VkShaderKey) is not its expected size!"); +static_assert(sizeof(VkPipelineKey) == 16 + 24 + 8, "sizeof(VkPipelineKey) is not its expected size!"); // If this assert fails, the flags union no longer adds up to 64 bits. Or there are gaps in the class so the memcmp doesn't work. class VkRenderPassKey { diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 0e8a580437..686e2f27d5 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -23,6 +23,7 @@ #include "vk_shader.h" #include "vk_ppshader.h" #include "vulkan/vk_renderdevice.h" +#include "vulkan/pipelines/vk_renderpass.h" #include #include "hw_shaderpatcher.h" #include "filesystem.h" @@ -224,7 +225,17 @@ static std::vector fragShaderOutputs {"FragNormal", "", UniformType::Vec4, FieldCondition::GBUFFER_PASS}, //2 }; -void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector &fields) +static void AddVertexInFields(VulkanRenderDevice* fb, FString& layoutBlock, const VkShaderKey& key) +{ + const VkVertexFormat& vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat); + for (const FVertexBufferAttribute& attr : vfmt.Attrs) + { + const VaryingFieldDesc& desc = vertexShaderInputs[attr.location]; + layoutBlock.AppendFormat("layout(location = %d) %s %s %s %s;\n", attr.location, desc.Property.GetChars(), "in", GetTypeStr(desc.Type), desc.Name.GetChars()); + } +} + +static void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector &fields) { for(auto &field : fields) { @@ -233,7 +244,7 @@ void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector &fields, const VkShaderKey& key, bool hasClipDistance) +static void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const std::vector &fields, const VkShaderKey& key, bool hasClipDistance) { for(auto &field : fields) { @@ -294,8 +305,7 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const if(!isFrag) { - int index = 0; - AddFields(layoutBlock, index, true, vertexShaderInputs); + AddVertexInFields(fb, layoutBlock, key); } { @@ -421,6 +431,19 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin if (key.UseSpriteCenter) definesBlock << "#define USE_SPRITE_CENTER\n"; definesBlock << ((key.Simple2D) ? "#define uFogEnabled -3\n" : "#define uFogEnabled 0\n"); + + // Setup fake variables for the 'in' attributes that aren't actually available because the garbage shader code thinks they exist + // God I hate this engine... :( + std::vector definedFields(vertexShaderInputs.size()); + bool hasNormal = false; + const VkVertexFormat& vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat); + for (const FVertexBufferAttribute& attr : vfmt.Attrs) + definedFields[attr.location] = true; + for (size_t i = 0; i < vertexShaderInputs.size(); i++) + { + if (!definedFields[i]) + definesBlock << "#define " << vertexShaderInputs[i].Name << " " << GetTypeStr(vertexShaderInputs[i].Type) << "(0)\n"; + } } 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) diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index cb8d2c501f..1accd8373f 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -118,13 +118,15 @@ class VkShaderKey int SpecialEffect = 0; int EffectState = 0; + int VertexFormat = 0; + int Padding = 0; bool operator<(const VkShaderKey& other) const { return memcmp(this, &other, sizeof(VkShaderKey)) < 0; } bool operator==(const VkShaderKey& other) const { return memcmp(this, &other, sizeof(VkShaderKey)) == 0; } bool operator!=(const VkShaderKey& other) const { return memcmp(this, &other, sizeof(VkShaderKey)) != 0; } }; -static_assert(sizeof(VkShaderKey) == 16, "sizeof(VkShaderKey) is not its expected size!"); // If this assert fails, the flags union no longer adds up to 64 bits. Or there are gaps in the class so the memcmp doesn't work. +static_assert(sizeof(VkShaderKey) == 24, "sizeof(VkShaderKey) is not its expected size!"); // If this assert fails, the flags union no longer adds up to 64 bits. Or there are gaps in the class so the memcmp doesn't work. class VkShaderProgram { diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index fc7e3f7007..e27c8d33ab 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -686,9 +686,9 @@ int VulkanRenderDevice::GetLevelMeshPipelineID(const MeshApplyData& applyData, c VkPipelineKey pipelineKey; pipelineKey.DrawType = DT_Triangles; - pipelineKey.VertexFormat = levelVertexFormatIndex; pipelineKey.RenderStyle = applyData.RenderStyle; pipelineKey.DepthFunc = applyData.DepthFunc; + pipelineKey.ShaderKey.VertexFormat = levelVertexFormatIndex; if (applyData.SpecialEffect > EFF_NONE) { pipelineKey.ShaderKey.SpecialEffect = applyData.SpecialEffect; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index e80f7d1c7c..52a8e4e38e 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -249,7 +249,6 @@ void VkRenderState::ApplyRenderPass(int dt) VkPipelineKey pipelineKey; pipelineKey.DrawType = dt; pipelineKey.DrawLine = mDrawLine || mWireframe; - pipelineKey.VertexFormat = mVertexBuffer ? static_cast(mVertexBuffer)->VertexFormat : mRSBuffers->Flatbuffer.VertexFormat; pipelineKey.RenderStyle = mRenderStyle; pipelineKey.DepthTest = mDepthTest && !mWireframe; pipelineKey.DepthWrite = mDepthTest && !mWireframe && mDepthWrite; @@ -260,6 +259,7 @@ void VkRenderState::ApplyRenderPass(int dt) pipelineKey.StencilPassOp = mStencilOp; pipelineKey.ColorMask = mColorMask; pipelineKey.CullMode = mCullMode; + pipelineKey.ShaderKey.VertexFormat = mVertexBuffer ? static_cast(mVertexBuffer)->VertexFormat : mRSBuffers->Flatbuffer.VertexFormat; if (mSpecialEffect > EFF_NONE) { pipelineKey.ShaderKey.SpecialEffect = mSpecialEffect; From 1d2a4961adc7261187424f621af4075aa3fe183c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 Jan 2025 15:01:23 +0100 Subject: [PATCH 6/6] Fix descriptor set bug --- .../rendering/vulkan/descriptorsets/vk_descriptorset.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index f2dfc3ff60..4e8849e079 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -73,7 +73,7 @@ void VkDescriptorSetManager::Init() .AddBuffer(RSBuffer.Set.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Viewpoint.UBO.get(), 0, sizeof(HWViewpointUniforms)) .AddBuffer(RSBuffer.Set.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO(), 0, sizeof(MatricesUBO)) .AddBuffer(RSBuffer.Set.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->SurfaceUniformsBuffer->UBO(), 0, sizeof(SurfaceUniformsUBO)) - .AddBuffer(RSBuffer.Set.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Lightbuffer.SSO.get(), 0, sizeof(LightBufferSSO)) + .AddBuffer(RSBuffer.Set.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.SSO.get(), 0, sizeof(LightBufferSSO)) .AddBuffer(RSBuffer.Set.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Fogballbuffer.UBO.get(), 0, sizeof(FogballBufferUBO)) .AddBuffer(RSBuffer.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) .Execute(fb->GetDevice()); @@ -263,7 +263,7 @@ void VkDescriptorSetManager::CreateRSBufferLayout() .AddBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) - .AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT) .DebugName("VkDescriptorSetManager.RSBuffer.Layout")