From 27e7fa10d96c12f2b8c22b8f97e3c0e82486b470 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Tue, 11 Aug 2026 21:00:58 -0400 Subject: [PATCH] [TEST] Fix missing barrier + removal of required aligments checks inside swizzle textures --- .../translate/impl/texture_fetch_swizzled.cpp | 22 ------------------- .../impl/texture_gather_swizzled.cpp | 11 ---------- .../translate/impl/texture_load_swizzled.cpp | 15 ------------- .../renderer_vulkan/vk_texture_cache.cpp | 3 ++- 4 files changed, 2 insertions(+), 49 deletions(-) diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp index 50e618c2f1..98e177a92e 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp @@ -50,12 +50,6 @@ constexpr std::array RGBA_LUT{ R | G | B | A, // }; -void CheckAlignment(IR::Reg reg, size_t alignment) { - if (!IR::IsAligned(reg, alignment)) { - throw NotImplementedException("Unaligned source register {}", reg); - } -} - template IR::Value Composite(TranslatorVisitor& v, Args... regs) { return v.ir.CompositeConstruct(v.F(regs)...); @@ -86,67 +80,53 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) { info.type.Assign(TextureType::Color2D); return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_b), zero, {}, info); case 3: // 2D.LL - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::Color2D); return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b), {}, info); case 4: // 2D.DC - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::Color2D); info.is_depth.Assign(1); return v.ir.ImageSampleDrefImplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b), {}, {}, {}, info); case 5: // 2D.LL.DC - CheckAlignment(reg_a, 2); - CheckAlignment(reg_b, 2); info.type.Assign(TextureType::Color2D); info.is_depth.Assign(1); return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b + 1), v.F(reg_b), {}, info); case 6: // 2D.LZ.DC - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::Color2D); info.is_depth.Assign(1); return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b), zero, {}, info); case 7: // ARRAY_2D - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::ColorArray2D); return v.ir.ImageSampleImplicitLod( handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))), {}, {}, {}, info); case 8: // ARRAY_2D.LZ - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::ColorArray2D); return v.ir.ImageSampleExplicitLod( handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))), zero, {}, info); case 9: // ARRAY_2D.LZ.DC - CheckAlignment(reg_a, 2); - CheckAlignment(reg_b, 2); info.type.Assign(TextureType::ColorArray2D); info.is_depth.Assign(1); return v.ir.ImageSampleDrefExplicitLod( handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))), v.F(reg_b + 1), zero, {}, info); case 10: // 3D - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::Color3D); return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {}, {}, info); case 11: // 3D.LZ - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::Color3D); return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), zero, {}, info); case 12: // CUBE - CheckAlignment(reg_a, 2); info.type.Assign(TextureType::ColorCube); return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {}, {}, info); case 13: // CUBE.LL - CheckAlignment(reg_a, 2); - CheckAlignment(reg_b, 2); info.type.Assign(TextureType::ColorCube); return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), v.F(reg_b + 1), {}, info); @@ -187,12 +167,10 @@ IR::Reg RegStoreComponent32(u64 insn, unsigned index) { case 0: return texs.dest_reg_a; case 1: - CheckAlignment(texs.dest_reg_a, 2); return texs.dest_reg_a + 1; case 2: return texs.dest_reg_b; case 3: - CheckAlignment(texs.dest_reg_b, 2); return texs.dest_reg_b + 1; } throw LogicError("Invalid store index {}", index); diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp index e4c6581450..4a27433739 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp @@ -34,12 +34,6 @@ union Encoding { BitField<36, 13, u64> cbuf_offset; }; -void CheckAlignment(IR::Reg reg, size_t alignment) { - if (!IR::IsAligned(reg, alignment)) { - throw NotImplementedException("Unaligned source register {}", reg); - } -} - IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg) { const IR::U32 value{v.X(reg)}; return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(6), true), @@ -60,18 +54,15 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) { info.is_depth.Assign(tld4s.dc != 0 ? 1 : 0); IR::Value coords; if (tld4s.aoffi != 0) { - CheckAlignment(reg_a, 2); coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1)); IR::Value offset = MakeOffset(v, reg_b); if (tld4s.dc != 0) { - CheckAlignment(reg_b, 2); IR::F32 dref = v.F(reg_b + 1); return v.ir.ImageGatherDref(handle, coords, offset, {}, dref, info); } return v.ir.ImageGather(handle, coords, offset, {}, info); } if (tld4s.dc != 0) { - CheckAlignment(reg_a, 2); coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1)); IR::F32 dref = v.F(reg_b); return v.ir.ImageGatherDref(handle, coords, {}, {}, dref, info); @@ -86,12 +77,10 @@ IR::Reg RegStoreComponent32(u64 insn, size_t index) { case 0: return tlds4.dest_reg_a; case 1: - CheckAlignment(tlds4.dest_reg_a, 2); return tlds4.dest_reg_a + 1; case 2: return tlds4.dest_reg_b; case 3: - CheckAlignment(tlds4.dest_reg_b, 2); return tlds4.dest_reg_b + 1; } throw LogicError("Invalid store index {}", index); diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp index 0362f076af..0fd7c1cda5 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp @@ -55,12 +55,6 @@ union Encoding { BitField<53, 4, u64> encoding; }; -void CheckAlignment(IR::Reg reg, size_t alignment) { - if (!IR::IsAligned(reg, alignment)) { - throw NotImplementedException("Unaligned source register {}", reg); - } -} - IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg) { const IR::U32 value{v.X(reg)}; return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true), @@ -92,38 +86,31 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) { coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_b)); break; case 4: - CheckAlignment(reg_a, 2); texture_type = Shader::TextureType::Color2D; coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1)); offsets = MakeOffset(v, reg_b); break; case 5: - CheckAlignment(reg_a, 2); texture_type = Shader::TextureType::Color2D; coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1)); lod = v.X(reg_b); break; case 6: - CheckAlignment(reg_a, 2); texture_type = Shader::TextureType::Color2D; coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1)); multisample = v.X(reg_b); break; case 7: - CheckAlignment(reg_a, 2); texture_type = Shader::TextureType::Color3D; coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1), v.X(reg_b)); break; case 8: { - CheckAlignment(reg_b, 2); const IR::U32 array{v.ir.BitFieldExtract(v.X(reg_a), v.ir.Imm32(0), v.ir.Imm32(16))}; texture_type = Shader::TextureType::ColorArray2D; coords = v.ir.CompositeConstruct(v.X(reg_b), v.X(reg_b + 1), array); break; } case 12: - CheckAlignment(reg_a, 2); - CheckAlignment(reg_b, 2); texture_type = Shader::TextureType::Color2D; coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1)); lod = v.X(reg_b); @@ -166,12 +153,10 @@ IR::Reg RegStoreComponent32(u64 insn, unsigned index) { case 0: return tlds.dest_reg_a; case 1: - CheckAlignment(tlds.dest_reg_a, 2); return tlds.dest_reg_a + 1; case 2: return tlds.dest_reg_b; case 3: - CheckAlignment(tlds.dest_reg_b, 2); return tlds.dest_reg_b + 1; } throw LogicError("Invalid store index {}", index); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 3db16d43ae..db4e8a00a3 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1193,7 +1193,8 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER, {}, middle_out_barrier); - cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies); + cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + vk_out_copies); cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, {}, {}, post_barriers); });