From 82b78cde7374c04e5c3a4d6255ddb6c26ecae946 Mon Sep 17 00:00:00 2001
From: Wollnashorn <Wollnashorn@users.noreply.github.com>
Date: Wed, 5 Apr 2023 18:00:35 +0200
Subject: [PATCH] shader_recompiler: Use vector arithmetic rather than
 component-wise in ImageGatherSubpixelOffset Should be more efficient and
 better readable

---
 .../backend/spirv/emit_spirv_image.cpp        | 27 +++++++------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 968901d42b..7d901c04b1 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -266,30 +266,21 @@ Id ImageGatherSubpixelOffset(EmitContext& ctx, const IR::TextureInstInfo& info,
                              Id coords) {
     // Apply a subpixel offset of 1/512 the texel size of the texture to ensure same rounding on
     // AMD hardware as on Maxwell or other Nvidia architectures.
-    const auto calculate_offset{[&](size_t dim) -> std::array<Id, 2> {
+    const auto calculate_coords{[&](size_t dim) {
         const Id nudge{ctx.Const(0x1p-9f)};
         const Id image_size{ctx.OpImageQuerySizeLod(ctx.U32[dim], texture, ctx.u32_zero_value)};
-        const Id offset_x{ctx.OpFDiv(
-            ctx.F32[1], nudge,
-            ctx.OpConvertUToF(ctx.F32[1], ctx.OpCompositeExtract(ctx.U32[1], image_size, 0)))};
-        const Id offset_y{ctx.OpFDiv(
-            ctx.F32[1], nudge,
-            ctx.OpConvertUToF(ctx.F32[1], ctx.OpCompositeExtract(ctx.U32[1], image_size, 1)))};
-        return {ctx.OpFAdd(ctx.F32[1], ctx.OpCompositeExtract(ctx.F32[1], coords, 0), offset_x),
-                ctx.OpFAdd(ctx.F32[1], ctx.OpCompositeExtract(ctx.F32[1], coords, 1), offset_y)};
+        Id offset{dim == 2 ? ctx.ConstantComposite(ctx.F32[dim], nudge, nudge)
+                           : ctx.ConstantComposite(ctx.F32[dim], nudge, nudge, ctx.f32_zero_value)};
+        offset = ctx.OpFDiv(ctx.F32[dim], offset, ctx.OpConvertUToF(ctx.F32[dim], image_size));
+        return ctx.OpFAdd(ctx.F32[dim], coords, offset);
     }};
     switch (info.type) {
     case TextureType::Color2D:
-    case TextureType::Color2DRect: {
-        const auto offset{calculate_offset(2)};
-        return ctx.OpCompositeConstruct(ctx.F32[2], offset[0], offset[1]);
-    }
+    case TextureType::Color2DRect:
+        return calculate_coords(2);
     case TextureType::ColorArray2D:
-    case TextureType::ColorCube: {
-        const auto offset{calculate_offset(3)};
-        return ctx.OpCompositeConstruct(ctx.F32[3], offset[0], offset[1],
-                                        ctx.OpCompositeExtract(ctx.F32[1], coords, 2));
-    }
+    case TextureType::ColorCube:
+        return calculate_coords(3);
     default:
         return coords;
     }