Skip to content

Commit

Permalink
Fix the vertex attribute bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed Jan 23, 2025
1 parent 4ff328e commit 68489d6
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 23 deletions.
12 changes: 1 addition & 11 deletions src/common/rendering/vulkan/pipelines/vk_renderpass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ std::unique_ptr<VulkanPipeline> 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]);
Expand All @@ -325,20 +325,10 @@ std::unique_ptr<VulkanPipeline> 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);
Expand Down
10 changes: 5 additions & 5 deletions src/common/rendering/vulkan/pipelines/vk_renderpass.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,22 @@ 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; }
bool operator!=(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) != 0; }
};

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
{
Expand Down
31 changes: 27 additions & 4 deletions src/common/rendering/vulkan/shaders/vk_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "vk_shader.h"
#include "vk_ppshader.h"
#include "vulkan/vk_renderdevice.h"
#include "vulkan/pipelines/vk_renderpass.h"
#include <zvulkan/vulkanbuilders.h>
#include "hw_shaderpatcher.h"
#include "filesystem.h"
Expand Down Expand Up @@ -224,7 +225,17 @@ static std::vector<BuiltinFieldDesc> fragShaderOutputs
{"FragNormal", "", UniformType::Vec4, FieldCondition::GBUFFER_PASS}, //2
};

void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector<VaryingFieldDesc> &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<VaryingFieldDesc> &fields)
{
for(auto &field : fields)
{
Expand All @@ -233,7 +244,7 @@ void AddFields(FString &layoutBlock, int &index, bool is_in, const std::vector<V
}
}

void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const std::vector<BuiltinFieldDesc> &fields, const VkShaderKey& key, bool hasClipDistance)
static void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const std::vector<BuiltinFieldDesc> &fields, const VkShaderKey& key, bool hasClipDistance)
{
for(auto &field : fields)
{
Expand Down Expand Up @@ -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);
}

{
Expand Down Expand Up @@ -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<bool> 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<VulkanShader> VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader)
Expand Down
4 changes: 3 additions & 1 deletion src/common/rendering/vulkan/shaders/vk_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion src/common/rendering/vulkan/vk_renderdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/common/rendering/vulkan/vk_renderstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ void VkRenderState::ApplyRenderPass(int dt)
VkPipelineKey pipelineKey;
pipelineKey.DrawType = dt;
pipelineKey.DrawLine = mDrawLine || mWireframe;
pipelineKey.VertexFormat = mVertexBuffer ? static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat : mRSBuffers->Flatbuffer.VertexFormat;
pipelineKey.RenderStyle = mRenderStyle;
pipelineKey.DepthTest = mDepthTest && !mWireframe;
pipelineKey.DepthWrite = mDepthTest && !mWireframe && mDepthWrite;
Expand All @@ -260,6 +259,7 @@ void VkRenderState::ApplyRenderPass(int dt)
pipelineKey.StencilPassOp = mStencilOp;
pipelineKey.ColorMask = mColorMask;
pipelineKey.CullMode = mCullMode;
pipelineKey.ShaderKey.VertexFormat = mVertexBuffer ? static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat : mRSBuffers->Flatbuffer.VertexFormat;
if (mSpecialEffect > EFF_NONE)
{
pipelineKey.ShaderKey.SpecialEffect = mSpecialEffect;
Expand Down

0 comments on commit 68489d6

Please sign in to comment.