From dd7185981848b0883ad5e31fb22b2ba08d1cd291 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 20 Aug 2023 00:14:31 +0300 Subject: [PATCH] vk_rasterizer: More robust attribute loading --- .../renderer_vulkan/vk_graphics_pipeline.h | 4 +- .../renderer_vulkan/vk_rasterizer.cpp | 57 ++++++++++--------- .../renderer_vulkan/vk_rasterizer.h | 2 +- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 26d1daa50..13267b59b 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -43,7 +43,7 @@ class RenderpassCache; constexpr u32 MAX_SHADER_STAGES = 3; constexpr u32 MAX_VERTEX_ATTRIBUTES = 16; -constexpr u32 MAX_VERTEX_BINDINGS = 16; +constexpr u32 MAX_VERTEX_BINDINGS = 13; /** * The pipeline state is tightly packed with bitfields to reduce @@ -125,12 +125,12 @@ struct AttachmentInfo { * Information about a graphics/compute pipeline */ struct PipelineInfo { - VertexLayout vertex_layout; BlendingState blending; AttachmentInfo attachments; RasterizationState rasterization; DepthStencilState depth_stencil; DynamicState dynamic; + VertexLayout vertex_layout; [[nodiscard]] u64 Hash(const Instance& instance) const; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index fdbb11a2a..a9d64d677 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -166,13 +166,12 @@ void RasterizerVulkan::SetupVertexArray() { * or interleave them in the same loader. **/ const auto& vertex_attributes = regs.pipeline.vertex_attributes; - PAddr base_address = vertex_attributes.GetPhysicalBaseAddress(); // GPUREG_ATTR_BUF_BASE - + const PAddr base_address = vertex_attributes.GetPhysicalBaseAddress(); // GPUREG_ATTR_BUF_BASE const u32 stride_alignment = instance.GetMinVertexStrideAlignment(); VertexLayout& layout = pipeline_info.vertex_layout; - layout.attribute_count = 0; layout.binding_count = 0; + layout.attribute_count = 16; enable_attributes.fill(false); u32 buffer_offset = 0; @@ -184,32 +183,34 @@ void RasterizerVulkan::SetupVertexArray() { // Analyze the attribute loader by checking which attributes it provides u32 offset = 0; for (u32 comp = 0; comp < loader.component_count && comp < 12; comp++) { - u32 attribute_index = loader.GetComponent(comp); - if (attribute_index < 12) { - if (u32 size = vertex_attributes.GetNumElements(attribute_index); size != 0) { - offset = Common::AlignUp( - offset, vertex_attributes.GetElementSizeInBytes(attribute_index)); - - const u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index); - const Pica::PipelineRegs::VertexAttributeFormat format = - vertex_attributes.GetFormat(attribute_index); - - VertexAttribute& attribute = layout.attributes[layout.attribute_count++]; - attribute.binding.Assign(layout.binding_count); - attribute.location.Assign(input_reg); - attribute.offset.Assign(offset); - attribute.type.Assign(format); - attribute.size.Assign(size); - - enable_attributes[input_reg] = true; - offset += vertex_attributes.GetStride(attribute_index); - } - } else { - // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings - // respectively + const u32 attribute_index = loader.GetComponent(comp); + if (attribute_index >= 12) { + // Attribute ids 12, to 15 signify 4, 8, 12 and 16-byte paddings respectively. offset = Common::AlignUp(offset, 4); offset += (attribute_index - 11) * 4; + continue; } + + const u32 size = vertex_attributes.GetNumElements(attribute_index); + if (size == 0) { + continue; + } + + offset = + Common::AlignUp(offset, vertex_attributes.GetElementSizeInBytes(attribute_index)); + + const u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index); + const auto format = vertex_attributes.GetFormat(attribute_index); + + VertexAttribute& attribute = layout.attributes[input_reg]; + attribute.binding.Assign(layout.binding_count); + attribute.location.Assign(input_reg); + attribute.offset.Assign(offset); + attribute.type.Assign(format); + attribute.size.Assign(size); + + enable_attributes[input_reg] = true; + offset += vertex_attributes.GetStride(attribute_index); } const PAddr data_addr = @@ -282,7 +283,7 @@ void RasterizerVulkan::SetupFixedAttribs() { const u32 data_size = sizeof(float) * static_cast(data.size()); std::memcpy(fixed_ptr + offset, data.data(), data_size); - VertexAttribute& attribute = layout.attributes[layout.attribute_count++]; + VertexAttribute& attribute = layout.attributes[reg]; attribute.binding.Assign(layout.binding_count); attribute.location.Assign(reg); attribute.offset.Assign(offset); @@ -300,7 +301,7 @@ void RasterizerVulkan::SetupFixedAttribs() { // errors if the shader ever decides to use it. for (u32 i = 0; i < 16; i++) { if (!enable_attributes[i]) { - VertexAttribute& attribute = layout.attributes[layout.attribute_count++]; + VertexAttribute& attribute = layout.attributes[i]; attribute.binding.Assign(layout.binding_count); attribute.location.Assign(i); attribute.offset.Assign(0); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 8034412c0..4d5faee60 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -153,7 +153,7 @@ private: std::array enable_attributes{}; std::array vertex_buffers; VertexArrayInfo vertex_info; - PipelineInfo pipeline_info; + PipelineInfo pipeline_info{}; StreamBuffer stream_buffer; ///< Vertex+Index buffer StreamBuffer uniform_buffer; ///< Uniform buffer