From bec1b9056f7ca5c94efef424985eb54a63cad518 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sun, 13 Apr 2025 23:46:30 -0700 Subject: [PATCH] shader_recompiler: Misc shader fixes. (#2781) * shader_recompiler: Fix frexp exponent type. * shader_recompiler: Implement V_CMP_CLASS_F32 negative class mask. * shader_recompiler: Define operands for DS_ORDERED_COUNT. --- .../backend/spirv/emit_spirv_floating_point.cpp | 4 ++-- src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 4 ++-- src/shader_recompiler/frontend/format.cpp | 3 +-- src/shader_recompiler/frontend/translate/vector_alu.cpp | 4 +++- src/shader_recompiler/ir/reg.h | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp index 8de903ce6..347c4cb0a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp @@ -267,12 +267,12 @@ Id EmitFPFrexpSig64(EmitContext& ctx, Id value) { Id EmitFPFrexpExp32(EmitContext& ctx, Id value) { const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f32, value); - return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1); + return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1)); } Id EmitFPFrexpExp64(EmitContext& ctx, Id value) { const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f64, value); - return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1); + return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1)); } Id EmitFPOrdEqual16(EmitContext& ctx, Id lhs, Id rhs) { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index e20cfeae2..8433251ff 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -153,9 +153,9 @@ void EmitContext::DefineArithmeticTypes() { full_result_i32x2 = Name(TypeStruct(S32[1], S32[1]), "full_result_i32x2"); full_result_u32x2 = Name(TypeStruct(U32[1], U32[1]), "full_result_u32x2"); - frexp_result_f32 = Name(TypeStruct(F32[1], U32[1]), "frexp_result_f32"); + frexp_result_f32 = Name(TypeStruct(F32[1], S32[1]), "frexp_result_f32"); if (info.uses_fp64) { - frexp_result_f64 = Name(TypeStruct(F64[1], U32[1]), "frexp_result_f64"); + frexp_result_f64 = Name(TypeStruct(F64[1], S32[1]), "frexp_result_f64"); } } diff --git a/src/shader_recompiler/frontend/format.cpp b/src/shader_recompiler/frontend/format.cpp index 76b1cc818..f89f0a582 100644 --- a/src/shader_recompiler/frontend/format.cpp +++ b/src/shader_recompiler/frontend/format.cpp @@ -2784,8 +2784,7 @@ constexpr std::array InstructionFormatDS = {{ // 62 = DS_APPEND {InstClass::DsAppendCon, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, // 63 = DS_ORDERED_COUNT - {InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Undefined, - ScalarType::Undefined}, + {InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, // 64 = DS_ADD_U64 {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 22020d59f..da25f5434 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -1010,8 +1010,10 @@ void Translator::V_CMP_CLASS_F32(const GcnInst& inst) { value = ir.FPIsNan(src0); } else if ((class_mask & IR::FloatClassFunc::Infinity) == IR::FloatClassFunc::Infinity) { value = ir.FPIsInf(src0); + } else if ((class_mask & IR::FloatClassFunc::Negative) == IR::FloatClassFunc::Negative) { + value = ir.FPLessThanEqual(src0, ir.Imm32(-0.f)); } else { - UNREACHABLE(); + UNREACHABLE_MSG("Unsupported float class mask: {:#x}", static_cast(class_mask)); } } else { // We don't know the type yet, delay its resolution. diff --git a/src/shader_recompiler/ir/reg.h b/src/shader_recompiler/ir/reg.h index 40c4b61c3..622190cf0 100644 --- a/src/shader_recompiler/ir/reg.h +++ b/src/shader_recompiler/ir/reg.h @@ -25,6 +25,7 @@ enum class FloatClassFunc : u32 { NaN = SignalingNan | QuietNan, Infinity = PositiveInfinity | NegativeInfinity, + Negative = NegativeInfinity | NegativeNormal | NegativeDenorm | NegativeZero, Finite = NegativeNormal | NegativeDenorm | NegativeZero | PositiveNormal | PositiveDenorm | PositiveZero, };