From 61f18544c78c1efdc6f544ddb03a739f423cb91d Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Tue, 2 Jul 2024 02:24:06 +0300 Subject: [PATCH] shader_recompiler: More image atomics --- .../backend/spirv/emit_spirv_image.cpp | 1 + .../backend/spirv/spirv_emit_context.cpp | 13 +++++++- .../backend/spirv/spirv_emit_context.h | 1 + .../frontend/translate/translate.cpp | 30 +++++++++++++++++++ .../frontend/translate/translate.h | 1 + .../frontend/translate/vector_alu.cpp | 5 ++++ 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 7a54f31c..7f9f072a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -79,6 +79,7 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id of Id ms) { const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); if (Sirit::ValidId(lod)) { return ctx.OpImageFetch(ctx.F32[4], image, coords, spv::ImageOperandsMask::Lod, lod); } else { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 27040813..1d60a852 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -322,7 +322,17 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { void EmitContext::DefineImagesAndSamplers(const Info& info) { for (const auto& image_desc : info.images) { - const Id sampled_type{image_desc.nfmt == AmdGpu::NumberFormat::Uint ? U32[1] : F32[1]}; + const VectorIds* data_types = [&] { + switch (image_desc.nfmt) { + case AmdGpu::NumberFormat::Uint: + return &U32; + case AmdGpu::NumberFormat::Sint: + return &S32; + default: + return &F32; + } + }(); + const Id sampled_type = data_types->Get(1); const Id image_type{ImageType(*this, image_desc, sampled_type)}; const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; @@ -332,6 +342,7 @@ void EmitContext::DefineImagesAndSamplers(const Info& info) { image_desc.dword_offset)); images.push_back({ .id = id, + .data_types = data_types, .sampled_type = image_desc.is_storage ? sampled_type : TypeSampledImage(image_type), .pointer_type = pointer_type, .image_type = image_type, diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 08e2bf8b..e64e2d98 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -185,6 +185,7 @@ public: struct TextureDefinition { Id id; + const VectorIds* data_types; Id sampled_type; Id pointer_type; Id image_type; diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 28aee56a..f45a5960 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -382,6 +382,33 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::IMAGE_ATOMIC_ADD: translator.IMAGE_ATOMIC(AtomicOp::Add, inst); break; + case Opcode::IMAGE_ATOMIC_AND: + translator.IMAGE_ATOMIC(AtomicOp::And, inst); + break; + case Opcode::IMAGE_ATOMIC_OR: + translator.IMAGE_ATOMIC(AtomicOp::Or, inst); + break; + case Opcode::IMAGE_ATOMIC_XOR: + translator.IMAGE_ATOMIC(AtomicOp::Xor, inst); + break; + case Opcode::IMAGE_ATOMIC_UMAX: + translator.IMAGE_ATOMIC(AtomicOp::Umax, inst); + break; + case Opcode::IMAGE_ATOMIC_SMAX: + translator.IMAGE_ATOMIC(AtomicOp::Smax, inst); + break; + case Opcode::IMAGE_ATOMIC_UMIN: + translator.IMAGE_ATOMIC(AtomicOp::Umin, inst); + break; + case Opcode::IMAGE_ATOMIC_SMIN: + translator.IMAGE_ATOMIC(AtomicOp::Smin, inst); + break; + case Opcode::IMAGE_ATOMIC_INC: + translator.IMAGE_ATOMIC(AtomicOp::Inc, inst); + break; + case Opcode::IMAGE_ATOMIC_DEC: + translator.IMAGE_ATOMIC(AtomicOp::Dec, inst); + break; case Opcode::IMAGE_GET_LOD: translator.IMAGE_GET_LOD(inst); break; @@ -590,6 +617,9 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::V_CVT_I32_F32: translator.V_CVT_I32_F32(inst); break; + case Opcode::V_CVT_FLR_I32_F32: + translator.V_CVT_FLR_I32_F32(inst); + break; case Opcode::V_SUBREV_F32: translator.V_SUBREV_F32(inst); break; diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index bcc65f9a..28a84522 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -153,6 +153,7 @@ public: void V_CVT_F32_UBYTE(u32 index, const GcnInst& inst); void V_BFREV_B32(const GcnInst& inst); void V_LDEXP_F32(const GcnInst& inst); + void V_CVT_FLR_I32_F32(const GcnInst& inst); // Vector Memory void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index d1b63200..c0766825 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -508,4 +508,9 @@ void Translator::V_LDEXP_F32(const GcnInst& inst) { SetDst(inst.dst[0], ir.FPLdexp(src0, src1)); } +void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0], true)}; + SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(src0))); +} + } // namespace Shader::Gcn