Преглед изворни кода

rescaling_pass: Fix rescaling Color2DArray ImageFetch offsets

ImageFetch offsets for 2D array coordinates have a different composite size than the coordinates. The rescaling pass was not taking this into account.

Fixes broken shaders when scaling is enabled in Astral Chain, and likely other titles.
ameerj пре 4 година
родитељ
комит
f87f8d4610
1 измењених фајлова са 27 додато и 2 уклоњено
  1. 27 2
      src/shader_recompiler/ir_opt/rescaling_pass.cpp

+ 27 - 2
src/shader_recompiler/ir_opt/rescaling_pass.cpp

@@ -183,6 +183,31 @@ void ScaleIntegerComposite(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_s
     }
     }
 }
 }
 
 
+void ScaleIntegerOffsetComposite(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled,
+                                 size_t index) {
+    const IR::Value composite{inst.Arg(index)};
+    if (composite.IsEmpty()) {
+        return;
+    }
+    const auto info{inst.Flags<IR::TextureInstInfo>()};
+    const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(composite, 0)})};
+    const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(composite, 1)})};
+    switch (info.type) {
+    case TextureType::ColorArray2D:
+    case TextureType::Color2D:
+        inst.SetArg(index, ir.CompositeConstruct(x, y));
+        break;
+    case TextureType::Color1D:
+    case TextureType::ColorArray1D:
+    case TextureType::Color3D:
+    case TextureType::ColorCube:
+    case TextureType::ColorArrayCube:
+    case TextureType::Buffer:
+        // Nothing to patch here
+        break;
+    }
+}
+
 void SubScaleCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) {
 void SubScaleCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) {
     const auto info{inst.Flags<IR::TextureInstInfo>()};
     const auto info{inst.Flags<IR::TextureInstInfo>()};
     const IR::Value coord{inst.Arg(1)};
     const IR::Value coord{inst.Arg(1)};
@@ -220,7 +245,7 @@ void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) {
     const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
     const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
     SubScaleCoord(ir, inst, is_scaled);
     SubScaleCoord(ir, inst, is_scaled);
     // Scale ImageFetch offset
     // Scale ImageFetch offset
-    ScaleIntegerComposite(ir, inst, is_scaled, 2);
+    ScaleIntegerOffsetComposite(ir, inst, is_scaled, 2);
 }
 }
 
 
 void SubScaleImageRead(IR::Block& block, IR::Inst& inst) {
 void SubScaleImageRead(IR::Block& block, IR::Inst& inst) {
@@ -242,7 +267,7 @@ void PatchImageFetch(IR::Block& block, IR::Inst& inst) {
     const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
     const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
     ScaleIntegerComposite(ir, inst, is_scaled, 1);
     ScaleIntegerComposite(ir, inst, is_scaled, 1);
     // Scale ImageFetch offset
     // Scale ImageFetch offset
-    ScaleIntegerComposite(ir, inst, is_scaled, 2);
+    ScaleIntegerOffsetComposite(ir, inst, is_scaled, 2);
 }
 }
 
 
 void PatchImageRead(IR::Block& block, IR::Inst& inst) {
 void PatchImageRead(IR::Block& block, IR::Inst& inst) {