shader_recompiler: Use VK_AMD_shader_trinary_minmax when available. (#2739)

* shader_recompiler: Use VK_AMD_shader_trinary_minmax when available.

* shader_recompiler: Simplify signed/unsigned trinary instruction variants.
This commit is contained in:
squidbus 2025-04-02 13:36:54 -07:00 committed by GitHub
parent eb300d0aa7
commit afd0251dd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 168 additions and 34 deletions

View file

@ -238,13 +238,11 @@ public:
void V_FMA_F32(const GcnInst& inst);
void V_FMA_F64(const GcnInst& inst);
void V_MIN3_F32(const GcnInst& inst);
void V_MIN3_I32(const GcnInst& inst);
void V_MIN3_U32(const GcnInst& inst);
void V_MIN3_U32(bool is_signed, const GcnInst& inst);
void V_MAX3_F32(const GcnInst& inst);
void V_MAX3_U32(bool is_signed, const GcnInst& inst);
void V_MED3_F32(const GcnInst& inst);
void V_MED3_I32(const GcnInst& inst);
void V_MED3_U32(const GcnInst& inst);
void V_MED3_U32(bool is_signed, const GcnInst& inst);
void V_SAD(const GcnInst& inst);
void V_SAD_U32(const GcnInst& inst);
void V_CVT_PK_U16_U32(const GcnInst& inst);

View file

@ -359,9 +359,9 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
case Opcode::V_MIN3_F32:
return V_MIN3_F32(inst);
case Opcode::V_MIN3_I32:
return V_MIN3_I32(inst);
return V_MIN3_U32(true, inst);
case Opcode::V_MIN3_U32:
return V_MIN3_U32(inst);
return V_MIN3_U32(false, inst);
case Opcode::V_MAX3_F32:
return V_MAX3_F32(inst);
case Opcode::V_MAX3_I32:
@ -371,9 +371,9 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
case Opcode::V_MED3_F32:
return V_MED3_F32(inst);
case Opcode::V_MED3_I32:
return V_MED3_I32(inst);
return V_MED3_U32(true, inst);
case Opcode::V_MED3_U32:
return V_MED3_U32(inst);
return V_MED3_U32(false, inst);
case Opcode::V_SAD_U32:
return V_SAD_U32(inst);
case Opcode::V_CVT_PK_U16_U32:
@ -1166,59 +1166,42 @@ void Translator::V_MIN3_F32(const GcnInst& inst) {
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
SetDst(inst.dst[0], ir.FPMin(src0, ir.FPMin(src1, src2)));
SetDst(inst.dst[0], ir.FPMinTri(src0, src1, src2));
}
void Translator::V_MIN3_I32(const GcnInst& inst) {
void Translator::V_MIN3_U32(bool is_signed, const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 src2{GetSrc(inst.src[2])};
SetDst(inst.dst[0], ir.SMin(src0, ir.SMin(src1, src2)));
}
void Translator::V_MIN3_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 src2{GetSrc(inst.src[2])};
SetDst(inst.dst[0], ir.UMin(src0, ir.UMin(src1, src2)));
SetDst(inst.dst[0], ir.IMinTri(src0, src1, src2, is_signed));
}
void Translator::V_MAX3_F32(const GcnInst& inst) {
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
SetDst(inst.dst[0], ir.FPMax(src0, ir.FPMax(src1, src2)));
SetDst(inst.dst[0], ir.FPMaxTri(src0, src1, src2));
}
void Translator::V_MAX3_U32(bool is_signed, const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 src2{GetSrc(inst.src[2])};
SetDst(inst.dst[0], ir.IMax(src0, ir.IMax(src1, src2, is_signed), is_signed));
SetDst(inst.dst[0], ir.IMaxTri(src0, src1, src2, is_signed));
}
void Translator::V_MED3_F32(const GcnInst& inst) {
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
const IR::F32 mmx = ir.FPMin(ir.FPMax(src0, src1), src2);
SetDst(inst.dst[0], ir.FPMax(ir.FPMin(src0, src1), mmx));
SetDst(inst.dst[0], ir.FPMedTri(src0, src1, src2));
}
void Translator::V_MED3_I32(const GcnInst& inst) {
void Translator::V_MED3_U32(bool is_signed, const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 src2{GetSrc(inst.src[2])};
const IR::U32 mmx = ir.SMin(ir.SMax(src0, src1), src2);
SetDst(inst.dst[0], ir.SMax(ir.SMin(src0, src1), mmx));
}
void Translator::V_MED3_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 src2{GetSrc(inst.src[2])};
const IR::U32 mmx = ir.UMin(ir.UMax(src0, src1), src2);
SetDst(inst.dst[0], ir.UMax(ir.UMin(src0, src1), mmx));
SetDst(inst.dst[0], ir.IMedTri(src0, src1, src2, is_signed));
}
void Translator::V_SAD(const GcnInst& inst) {