From cd1689b74b69aefae9cbeabefc6621a1e12877e2 Mon Sep 17 00:00:00 2001 From: psucien Date: Fri, 21 Jun 2024 22:32:10 +0200 Subject: [PATCH] shader_recompiler: added support for fetch instance id --- src/shader_recompiler/frontend/fetch_shader.cpp | 3 +++ src/shader_recompiler/frontend/fetch_shader.h | 11 ++++++----- .../frontend/translate/translate.cpp | 6 ++++++ src/shader_recompiler/runtime_info.h | 8 ++++++++ .../renderer_vulkan/vk_graphics_pipeline.cpp | 4 +++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/shader_recompiler/frontend/fetch_shader.cpp b/src/shader_recompiler/frontend/fetch_shader.cpp index 7f4f50e94..80917e0a3 100644 --- a/src/shader_recompiler/frontend/fetch_shader.cpp +++ b/src/shader_recompiler/frontend/fetch_shader.cpp @@ -72,6 +72,9 @@ std::vector ParseFetchShader(const u32* code) { attrib.sgpr_base = it->base_sgpr; attrib.dword_offset = it->dword_offset; + // Store instance id rate + attrib.instance_data = inst.src[0].code; + // Mark load as used. it->dst_reg = -1; } diff --git a/src/shader_recompiler/frontend/fetch_shader.h b/src/shader_recompiler/frontend/fetch_shader.h index 2f8eae12c..14f2bf4d4 100644 --- a/src/shader_recompiler/frontend/fetch_shader.h +++ b/src/shader_recompiler/frontend/fetch_shader.h @@ -9,11 +9,12 @@ namespace Shader::Gcn { struct VertexAttribute { - u8 semantic; ///< Semantic index of the attribute - u8 dest_vgpr; ///< Destination VGPR to load first component. - u8 num_elements; ///< Number of components to load - u8 sgpr_base; ///< SGPR that contains the pointer to the list of vertex V# - u8 dword_offset; ///< The dword offset of the V# that describes this attribute. + u8 semantic; ///< Semantic index of the attribute + u8 dest_vgpr; ///< Destination VGPR to load first component. + u8 num_elements; ///< Number of components to load + u8 sgpr_base; ///< SGPR that contains the pointer to the list of vertex V# + u8 dword_offset; ///< The dword offset of the V# that describes this attribute. + u8 instance_data; ///< Indicates that the buffer will be accessed in instance rate }; std::vector ParseFetchShader(const u32* code); diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 344fdc8bb..2d1679f37 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -194,6 +194,11 @@ void Translator::EmitFetch(const GcnInst& inst) { ir.SetVectorReg(dst_reg++, ir.GetAttribute(attr, i)); } + if (attrib.instance_data == 2 || attrib.instance_data == 3) { + LOG_WARNING(Render_Recompiler, "Unsupported instance step rate = {}", + attrib.instance_data); + } + // Read the V# of the attribute to figure out component number and type. const auto buffer = info.ReadUd(attrib.sgpr_base, attrib.dword_offset); const u32 num_components = AmdGpu::NumComponents(buffer.data_format); @@ -203,6 +208,7 @@ void Translator::EmitFetch(const GcnInst& inst) { .num_components = std::min(attrib.num_elements, num_components), .sgpr_base = attrib.sgpr_base, .dword_offset = attrib.dword_offset, + .instance_step_rate = static_cast(attrib.instance_data), }); } } diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index 634749585..196fad013 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -72,11 +72,19 @@ using SamplerResourceList = boost::container::static_vector; struct Info { struct VsInput { + enum InstanceIdType : u8 { + None = 0, + OverStepRate0 = 1, + OverStepRate1 = 2, + Plain = 3, + }; + AmdGpu::NumberFormat fmt; u16 binding; u16 num_components; u8 sgpr_base; u8 dword_offset; + InstanceIdType instance_step_rate; }; boost::container::static_vector vs_inputs{}; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 787fb774a..89f3c086d 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -53,7 +53,9 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul bindings.push_back({ .binding = input.binding, .stride = buffer.GetStride(), - .inputRate = vk::VertexInputRate::eVertex, + .inputRate = input.instance_step_rate == Shader::Info::VsInput::None + ? vk::VertexInputRate::eVertex + : vk::VertexInputRate::eInstance, }); }