From 6774216038f3d1e6534f5106fcb2d07ec6ceba38 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:13:50 +0300 Subject: [PATCH] shader_recompiler: Apply buffer swizzle on vertex attribs --- .../frontend/translate/translate.cpp | 29 +++++++++++++++---- src/video_core/amdgpu/resource.h | 14 +++++++++ .../renderer_vulkan/vk_pipeline_cache.cpp | 4 --- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 1c8fd30b..236c97b5 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -194,8 +194,30 @@ void Translator::EmitFetch(const GcnInst& inst) { for (const auto& attrib : attribs) { const IR::Attribute attr{IR::Attribute::Param0 + attrib.semantic}; IR::VectorReg dst_reg{attrib.dest_vgpr}; - for (u32 i = 0; i < attrib.num_elements; i++) { - ir.SetVectorReg(dst_reg++, ir.GetAttribute(attr, i)); + + // 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); + for (u32 i = 0; i < num_components; i++) { + const IR::F32 comp = [&] { + switch (buffer.GetSwizzle(i)) { + case AmdGpu::CompSwizzle::One: + return ir.Imm32(1.f); + case AmdGpu::CompSwizzle::Zero: + return ir.Imm32(0.f); + case AmdGpu::CompSwizzle::Red: + return ir.GetAttribute(attr, 0); + case AmdGpu::CompSwizzle::Green: + return ir.GetAttribute(attr, 1); + case AmdGpu::CompSwizzle::Blue: + return ir.GetAttribute(attr, 2); + case AmdGpu::CompSwizzle::Alpha: + return ir.GetAttribute(attr, 3); + default: + UNREACHABLE(); + } + }(); + ir.SetVectorReg(dst_reg++, comp); } if (attrib.instance_data == 2 || attrib.instance_data == 3) { @@ -203,9 +225,6 @@ void Translator::EmitFetch(const GcnInst& inst) { 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); info.vs_inputs.push_back({ .fmt = buffer.num_format, .binding = attrib.semantic, diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index f464d95a..17686b7a 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -10,6 +10,15 @@ namespace AmdGpu { +enum class CompSwizzle : u32 { + Zero = 0, + One = 1, + Red = 4, + Green = 5, + Blue = 6, + Alpha = 7, +}; + // Table 8.5 Buffer Resource Descriptor [Sea Islands Series Instruction Set Architecture] struct Buffer { union { @@ -24,6 +33,7 @@ struct Buffer { BitField<3, 3, u32> dst_sel_y; BitField<6, 3, u32> dst_sel_z; BitField<9, 3, u32> dst_sel_w; + BitField<0, 12, u32> dst_sel; BitField<12, 3, NumberFormat> num_format; BitField<15, 4, DataFormat> data_format; BitField<19, 2, u32> element_size; @@ -31,6 +41,10 @@ struct Buffer { BitField<23, 1, u32> add_tid_enable; }; + CompSwizzle GetSwizzle(u32 comp) const noexcept { + return static_cast((dst_sel.Value() >> (comp * 3)) & 0x7); + } + u32 GetStride() const noexcept { return stride == 0 ? 1U : stride.Value(); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 8fbe7ac2..370c03f6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -206,10 +206,6 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline() { block_pool.ReleaseContents(); inst_pool.ReleaseContents(); - if (hash == 0xa34c48f8) { - printf("bad\n"); - } - // Recompile shader to IR. try { LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x}", stage, hash);