From 9e9aed41bebc1b7d29dbfcddcc203693bcdc680e Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 19 Dec 2023 10:55:56 -0500
Subject: shader_recompiler: use float image operations on load/store when
 required

---
 .../backend/spirv/emit_spirv_image.cpp             | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

(limited to 'src/shader_recompiler/backend/spirv/emit_spirv_image.cpp')

diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 22ceca19c0..800754554e 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -214,16 +214,16 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
     }
 }
 
-Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
+std::pair<Id, bool> Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
     if (!index.IsImmediate() || index.U32() != 0) {
         throw NotImplementedException("Indirect image indexing");
     }
     if (info.type == TextureType::Buffer) {
         const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
-        return ctx.OpLoad(def.image_type, def.id);
+        return {ctx.OpLoad(def.image_type, def.id), def.is_integer};
     } else {
         const ImageDefinition def{ctx.images.at(info.descriptor_index)};
-        return ctx.OpLoad(def.image_type, def.id);
+        return {ctx.OpLoad(def.image_type, def.id), def.is_integer};
     }
 }
 
@@ -566,13 +566,23 @@ Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id co
         LOG_WARNING(Shader_SPIRV, "Typeless image read not supported by host");
         return ctx.ConstantNull(ctx.U32[4]);
     }
-    return Emit(&EmitContext::OpImageSparseRead, &EmitContext::OpImageRead, ctx, inst, ctx.U32[4],
-                Image(ctx, index, info), coords, std::nullopt, std::span<const Id>{});
+    const auto [image, is_integer] = Image(ctx, index, info);
+    const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
+    Id color{Emit(&EmitContext::OpImageSparseRead, &EmitContext::OpImageRead, ctx, inst,
+                  result_type, image, coords, std::nullopt, std::span<const Id>{})};
+    if (!is_integer) {
+        color = ctx.OpBitcast(ctx.U32[4], color);
+    }
+    return color;
 }
 
 void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id color) {
     const auto info{inst->Flags<IR::TextureInstInfo>()};
-    ctx.OpImageWrite(Image(ctx, index, info), coords, color);
+    const auto [image, is_integer] = Image(ctx, index, info);
+    if (!is_integer) {
+        color = ctx.OpBitcast(ctx.F32[4], color);
+    }
+    ctx.OpImageWrite(image, coords, color);
 }
 
 Id EmitIsTextureScaled(EmitContext& ctx, const IR::Value& index) {
-- 
cgit v1.2.3-70-g09d2