diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 6efdc8974..77e30485b 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -114,6 +114,7 @@ public: void V_SAD(const GcnInst& inst); void V_MAC_F32(const GcnInst& inst); void V_CVT_PKRTZ_F16_F32(const GcnInst& inst); + void V_CVT_PKNORM_U16_F32(const GcnInst& inst); void V_CVT_F32_F16(const GcnInst& inst); void V_CVT_F16_F32(const GcnInst& inst); void V_MUL_F32(const GcnInst& inst); @@ -232,7 +233,7 @@ private: [[nodiscard]] T GetSrc64(const InstOperand& operand); void SetDst(const InstOperand& operand, const IR::U32F32& value); void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw); - + IR::U16 Convert_F32_to_U16_Normalized(const IR::F32& src); void LogMissingOpcode(const GcnInst& inst); private: diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index a07e70785..06fa4c37d 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -52,6 +52,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) { return V_CVT_F32_U32(inst); case Opcode::V_CVT_PKRTZ_F16_F32: return V_CVT_PKRTZ_F16_F32(inst); + case Opcode::V_CVT_PKNORM_U16_F32: + return V_CVT_PKNORM_U16_F32(inst); case Opcode::V_CVT_F32_F16: return V_CVT_F32_F16(inst); case Opcode::V_CVT_F16_F32: @@ -342,6 +344,27 @@ void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) { ir.SetVectorReg(dst_reg, ir.PackHalf2x16(vec_f32)); } +IR::U16 Translator::Convert_F32_to_U16_Normalized(const IR::F32& src) { + const IR::F32 as_float = ir.FPMul(src, ir.Imm32((f32)std::numeric_limits::max())); + const IR::U32 as_unsigned = ir.ConvertFToU(32, as_float); + return ir.UConvert(16, as_unsigned); +} + +void Translator::V_CVT_PKNORM_U16_F32(const GcnInst& inst) { + const IR::VectorReg dst_reg{inst.dst[0].code}; + + const IR::F32 src0 = GetSrc(inst.src[0]); + const IR::F32 src1 = GetSrc(inst.src[1]); + + const IR::Value vec_u16 = + ir.CompositeConstruct( + Convert_F32_to_U16_Normalized(src0), + Convert_F32_to_U16_Normalized(src1) + ); + + ir.SetVectorReg(dst_reg, ir.PackHalf2x16(vec_u16)); +} + void Translator::V_CVT_F32_F16(const GcnInst& inst) { const IR::U32 src0 = GetSrc(inst.src[0]); const IR::U16 src0l = ir.UConvert(16, src0);