mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-10-11 21:49:59 +00:00
Implement proper clamping and handling for V_RCP_CLAMP_F32, V_RSQ_CLAMP_F32, V_RSQ_LEGACY_F32, V_LOG_CLAMP_F32 (#5346)
* Implement proper clamping and handling for V_RCP_CLAMP_F32, V_RSQ_CLAMP_F32, V_RSQ_LEGACY_F32, V_LOG_CLAMP_F32, and V_CVT_PK_U8_F32. * -
This commit is contained in:
@@ -225,11 +225,15 @@ public:
|
||||
void V_RNDNE_F32(const GcnInst& inst);
|
||||
void V_FLOOR_F32(const GcnInst& inst);
|
||||
void V_EXP_F32(const GcnInst& inst);
|
||||
void V_LOG_CLAMP_F32(const GcnInst& inst);
|
||||
void V_LOG_F32(const GcnInst& inst);
|
||||
void V_RCP_F32(const GcnInst& inst);
|
||||
void V_RCP_CLAMP_F32(const GcnInst& inst);
|
||||
void V_RCP_LEGACY_F32(const GcnInst& inst);
|
||||
void V_RCP_F64(const GcnInst& inst);
|
||||
void V_RSQ_LEGACY_F32(const GcnInst& inst);
|
||||
void V_RSQ_F32(const GcnInst& inst);
|
||||
void V_RSQ_CLAMP_F32(const GcnInst& inst);
|
||||
void V_SQRT_F32(const GcnInst& inst);
|
||||
void V_SIN_F32(const GcnInst& inst);
|
||||
void V_COS_F32(const GcnInst& inst);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <limits>
|
||||
#include "shader_recompiler/frontend/opcodes.h"
|
||||
#include "shader_recompiler/frontend/translate/translate.h"
|
||||
#include "shader_recompiler/ir/attribute.h"
|
||||
@@ -170,7 +171,7 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
||||
case Opcode::V_EXP_F32:
|
||||
return V_EXP_F32(inst);
|
||||
case Opcode::V_LOG_CLAMP_F32:
|
||||
return V_LOG_F32(inst);
|
||||
return V_LOG_CLAMP_F32(inst);
|
||||
case Opcode::V_LOG_F32:
|
||||
return V_LOG_F32(inst);
|
||||
case Opcode::V_RCP_F32:
|
||||
@@ -182,11 +183,11 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
||||
case Opcode::V_RCP_IFLAG_F32:
|
||||
return V_RCP_F32(inst);
|
||||
case Opcode::V_RCP_CLAMP_F32:
|
||||
return V_RCP_F32(inst);
|
||||
return V_RCP_CLAMP_F32(inst);
|
||||
case Opcode::V_RSQ_CLAMP_F32:
|
||||
return V_RSQ_F32(inst);
|
||||
return V_RSQ_CLAMP_F32(inst);
|
||||
case Opcode::V_RSQ_LEGACY_F32:
|
||||
return V_RSQ_F32(inst);
|
||||
return V_RSQ_LEGACY_F32(inst);
|
||||
case Opcode::V_RSQ_F32:
|
||||
return V_RSQ_F32(inst);
|
||||
case Opcode::V_SQRT_F32:
|
||||
@@ -1046,6 +1047,14 @@ void Translator::V_EXP_F32(const GcnInst& inst) {
|
||||
SetDst(inst.dst[0], ir.FPExp2(src0));
|
||||
}
|
||||
|
||||
void Translator::V_LOG_CLAMP_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 result{ir.FPLog2(src0)};
|
||||
const IR::F32 max_val{ir.Imm32(std::numeric_limits<float>::max())};
|
||||
const IR::F32 min_val{ir.Imm32(-std::numeric_limits<float>::max())};
|
||||
SetDst(inst.dst[0], ir.FPClamp(result, min_val, max_val));
|
||||
}
|
||||
|
||||
void Translator::V_LOG_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
SetDst(inst.dst[0], ir.FPLog2(src0));
|
||||
@@ -1075,11 +1084,38 @@ void Translator::V_RCP_F64(const GcnInst& inst) {
|
||||
SetDst64(inst.dst[0], ir.FPRecip(src0));
|
||||
}
|
||||
|
||||
void Translator::V_RSQ_LEGACY_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 result{ir.FPRecipSqrt(src0)};
|
||||
const IR::F32 max_val{ir.Imm32(std::numeric_limits<float>::max())};
|
||||
const IR::F32 min_val{ir.Imm32(-std::numeric_limits<float>::max())};
|
||||
const IR::F32 clamped{ir.FPClamp(result, min_val, max_val)};
|
||||
const IR::F32 zero{ir.Imm32(0.0f)};
|
||||
const IR::F32 output{ir.Select(ir.FPEqual(src0, zero), zero, clamped)};
|
||||
SetDst(inst.dst[0], output);
|
||||
}
|
||||
|
||||
void Translator::V_RSQ_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
SetDst(inst.dst[0], ir.FPRecipSqrt(src0));
|
||||
}
|
||||
|
||||
void Translator::V_RCP_CLAMP_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 result{ir.FPRecip(src0)};
|
||||
const IR::F32 max_val{ir.Imm32(std::numeric_limits<float>::max())};
|
||||
const IR::F32 min_val{ir.Imm32(-std::numeric_limits<float>::max())};
|
||||
SetDst(inst.dst[0], ir.FPClamp(result, min_val, max_val));
|
||||
}
|
||||
|
||||
void Translator::V_RSQ_CLAMP_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 result{ir.FPRecipSqrt(src0)};
|
||||
const IR::F32 max_val{ir.Imm32(std::numeric_limits<float>::max())};
|
||||
const IR::F32 min_val{ir.Imm32(-std::numeric_limits<float>::max())};
|
||||
SetDst(inst.dst[0], ir.FPClamp(result, min_val, max_val));
|
||||
}
|
||||
|
||||
void Translator::V_SQRT_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
SetDst(inst.dst[0], ir.FPSqrt(src0));
|
||||
|
||||
Reference in New Issue
Block a user