mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
0791f921f6
* shader: release descriptor dependencies * shader: simplify shared-exit control flow * shader: fix scalar memory loads * shader: fix LDS counter bounds * renderer: skip inactive pixel shaders * shader: respect FP32 mode in comparisons * renderer: fix sampler border colors * shader: resolve descriptors from control flow * shader: resolve descriptors before resource planning * shader: handle scalar guards for image bounds * shader: handle reduced guards for image loops * shader: fix wave guards and material indices * shader: preserve scalar buffer offset alignment and carry * shader: prove masked loop bounds across iteration transitions * shader: preserve source and IR before resource tracking failures * shader: track material keys selected from active lanes * shader: remove obsolete post-dominator analysis * shader: follow bounds guards through control-flow joins
67 lines
2.8 KiB
C++
67 lines
2.8 KiB
C++
#include "graphics/shader/recompiler/frontend/translate/Translator.h"
|
|
|
|
namespace Libs::Graphics::ShaderRecompiler::Frontend {
|
|
|
|
void Translator::EmitCompareResult(const Decoder::Instruction& inst, IR::U1 value, bool scalar,
|
|
bool cmpx) {
|
|
if (scalar) {
|
|
ir.SetScc(value);
|
|
return;
|
|
}
|
|
const auto masked = ir.LogicalAnd(ir.GetExec(), value);
|
|
if (cmpx) {
|
|
const auto mask = BallotMask(masked);
|
|
ir.SetExec(masked);
|
|
ir.SetExecLo(mask[0]);
|
|
ir.SetExecHi(mask[1]);
|
|
return;
|
|
}
|
|
WriteMask(inst.dst, masked);
|
|
}
|
|
|
|
void Translator::EmitCompareConstant(const Decoder::Instruction& inst, bool value, bool scalar,
|
|
bool cmpx) {
|
|
EmitCompareResult(inst, IR::U1(IR::Value(value)), scalar, cmpx);
|
|
}
|
|
|
|
void Translator::EmitIntegerCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
|
|
IR::Type type, bool scalar, bool cmpx) {
|
|
const auto lhs = ReadOperand(inst.src0, type);
|
|
const auto rhs = ReadOperand(inst.src1, type);
|
|
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), scalar, cmpx);
|
|
}
|
|
|
|
void Translator::EmitInteger16Compare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
|
|
bool signed_value, bool cmpx) {
|
|
const auto lhs = ReadU16AsU32(inst.src0, signed_value);
|
|
const auto rhs = ReadU16AsU32(inst.src1, signed_value);
|
|
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), false, cmpx);
|
|
}
|
|
|
|
void Translator::EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
|
|
bool half, bool cmpx) {
|
|
const auto lhs =
|
|
half ? IR::Value(ReadF16AsF32(inst.src0)) : ReadOperand(inst.src0, IR::Type::F32);
|
|
const auto rhs =
|
|
half ? IR::Value(ReadF16AsF32(inst.src1)) : ReadOperand(inst.src1, IR::Type::F32);
|
|
const IR::FPCompareFlags flags{.flush_input_denorms = !half && flush_f32_inputs};
|
|
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs}, flags)), false, cmpx);
|
|
}
|
|
|
|
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx) {
|
|
const auto lhs = IR::F32(ReadOperand(inst.src0, IR::Type::F32));
|
|
const auto rhs = IR::F32(ReadOperand(inst.src1, IR::Type::F32));
|
|
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {lhs})),
|
|
IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {rhs})));
|
|
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false, cmpx);
|
|
}
|
|
|
|
void Translator::EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx) {
|
|
const auto value = ReadOperand(inst.src0, IR::Type::F32);
|
|
const auto mask = ReadOperand(inst.src1, IR::Type::U32);
|
|
EmitCompareResult(inst, IR::U1(ir.Emit(IR::ValueOpcode::FPCmpClass32, {value, mask})), false,
|
|
cmpx);
|
|
}
|
|
|
|
} // namespace Libs::Graphics::ShaderRecompiler::Frontend
|