shader_recompiler: Port some dark souls things

This commit is contained in:
IndecisiveTurtle 2024-07-30 19:48:04 +03:00
parent 5e35a30607
commit de2d5ecc29
3 changed files with 29 additions and 0 deletions

View File

@ -88,6 +88,10 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
case Opcode::S_SUB_U32: case Opcode::S_SUB_U32:
case Opcode::S_SUB_I32: case Opcode::S_SUB_I32:
return S_SUB_U32(inst); return S_SUB_U32(inst);
case Opcode::S_MIN_U32:
return S_MIN_U32(inst);
case Opcode::S_MAX_U32:
return S_MAX_U32(inst);
case Opcode::S_WQM_B64: case Opcode::S_WQM_B64:
break; break;
default: default:
@ -443,4 +447,20 @@ void Translator::S_ADDC_U32(const GcnInst& inst) {
SetDst(inst.dst[0], ir.IAdd(ir.IAdd(src0, src1), ir.GetSccLo())); SetDst(inst.dst[0], ir.IAdd(ir.IAdd(src0, src1), ir.GetSccLo()));
} }
void Translator::S_MAX_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 result = ir.UMax(src0, src1);
SetDst(inst.dst[0], result);
ir.SetScc(ir.IEqual(result, src0));
}
void Translator::S_MIN_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 result = ir.UMin(src0, src1);
SetDst(inst.dst[0], result);
ir.SetScc(ir.IEqual(result, src0));
}
} // namespace Shader::Gcn } // namespace Shader::Gcn

View File

@ -25,6 +25,7 @@ enum class ConditionOp : u32 {
LT, LT,
LE, LE,
TRU, TRU,
U,
}; };
enum class AtomicOp : u32 { enum class AtomicOp : u32 {
@ -95,6 +96,8 @@ public:
void S_ADDC_U32(const GcnInst& inst); void S_ADDC_U32(const GcnInst& inst);
void S_MULK_I32(const GcnInst& inst); void S_MULK_I32(const GcnInst& inst);
void S_ADDK_I32(const GcnInst& inst); void S_ADDK_I32(const GcnInst& inst);
void S_MAX_U32(const GcnInst& inst);
void S_MIN_U32(const GcnInst& inst);
// Scalar Memory // Scalar Memory
void S_LOAD_DWORD(int num_dwords, const GcnInst& inst); void S_LOAD_DWORD(int num_dwords, const GcnInst& inst);

View File

@ -111,6 +111,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
return V_CMP_F32(ConditionOp::LE, false, inst); return V_CMP_F32(ConditionOp::LE, false, inst);
case Opcode::V_CMP_NGE_F32: case Opcode::V_CMP_NGE_F32:
return V_CMP_F32(ConditionOp::LT, false, inst); return V_CMP_F32(ConditionOp::LT, false, inst);
case Opcode::V_CMP_U_F32:
return V_CMP_F32(ConditionOp::U, false, inst);
case Opcode::V_CNDMASK_B32: case Opcode::V_CNDMASK_B32:
return V_CNDMASK_B32(inst); return V_CNDMASK_B32(inst);
case Opcode::V_MAX_I32: case Opcode::V_MAX_I32:
@ -293,6 +295,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
return V_CMP_U32(ConditionOp::GE, false, true, inst); return V_CMP_U32(ConditionOp::GE, false, true, inst);
case Opcode::V_CMPX_TRU_U32: case Opcode::V_CMPX_TRU_U32:
return V_CMP_U32(ConditionOp::TRU, false, true, inst); return V_CMP_U32(ConditionOp::TRU, false, true, inst);
case Opcode::V_CMPX_LG_I32:
return V_CMP_U32(ConditionOp::LG, true, true, inst);
case Opcode::V_MBCNT_LO_U32_B32: case Opcode::V_MBCNT_LO_U32_B32:
return V_MBCNT_U32_B32(true, inst); return V_MBCNT_U32_B32(true, inst);
@ -518,6 +522,8 @@ void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) {
return ir.FPLessThanEqual(src0, src1); return ir.FPLessThanEqual(src0, src1);
case ConditionOp::GE: case ConditionOp::GE:
return ir.FPGreaterThanEqual(src0, src1); return ir.FPGreaterThanEqual(src0, src1);
case ConditionOp::U:
return ir.LogicalNot(ir.LogicalAnd(ir.FPIsNan(src0), ir.FPIsNan(src1)));
default: default:
UNREACHABLE(); UNREACHABLE();
} }