diff options
16 files changed, 210 insertions, 59 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 63ba1c75f..23cb523a8 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -65,8 +65,11 @@ add_library(shader_recompiler STATIC | |||
| 65 | frontend/maxwell/translate/impl/common_funcs.h | 65 | frontend/maxwell/translate/impl/common_funcs.h |
| 66 | frontend/maxwell/translate/impl/condition_code_set.cpp | 66 | frontend/maxwell/translate/impl/condition_code_set.cpp |
| 67 | frontend/maxwell/translate/impl/double_add.cpp | 67 | frontend/maxwell/translate/impl/double_add.cpp |
| 68 | frontend/maxwell/translate/impl/double_compare_and_set.cpp | ||
| 68 | frontend/maxwell/translate/impl/double_fused_multiply_add.cpp | 69 | frontend/maxwell/translate/impl/double_fused_multiply_add.cpp |
| 70 | frontend/maxwell/translate/impl/double_min_max.cpp | ||
| 69 | frontend/maxwell/translate/impl/double_multiply.cpp | 71 | frontend/maxwell/translate/impl/double_multiply.cpp |
| 72 | frontend/maxwell/translate/impl/double_set_predicate.cpp | ||
| 70 | frontend/maxwell/translate/impl/exit_program.cpp | 73 | frontend/maxwell/translate/impl/exit_program.cpp |
| 71 | frontend/maxwell/translate/impl/find_leading_one.cpp | 74 | frontend/maxwell/translate/impl/find_leading_one.cpp |
| 72 | frontend/maxwell/translate/impl/floating_point_add.cpp | 75 | frontend/maxwell/translate/impl/floating_point_add.cpp |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index efd0b70b7..93e851133 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -152,24 +152,7 @@ void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) { | |||
| 152 | 152 | ||
| 153 | void SetupDenormControl(const Profile& profile, const IR::Program& program, EmitContext& ctx, | 153 | void SetupDenormControl(const Profile& profile, const IR::Program& program, EmitContext& ctx, |
| 154 | Id main_func) { | 154 | Id main_func) { |
| 155 | if (!profile.support_float_controls) { | ||
| 156 | return; | ||
| 157 | } | ||
| 158 | const Info& info{program.info}; | 155 | const Info& info{program.info}; |
| 159 | if (!info.uses_fp32_denorms_flush && !info.uses_fp32_denorms_preserve && | ||
| 160 | !info.uses_fp16_denorms_flush && !info.uses_fp16_denorms_preserve) { | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | ctx.AddExtension("SPV_KHR_float_controls"); | ||
| 164 | |||
| 165 | if (info.uses_fp16 && profile.support_fp16_signed_zero_nan_preserve) { | ||
| 166 | ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||
| 167 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U); | ||
| 168 | } | ||
| 169 | if (profile.support_fp32_signed_zero_nan_preserve) { | ||
| 170 | ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||
| 171 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U); | ||
| 172 | } | ||
| 173 | if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) { | 156 | if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) { |
| 174 | // LOG_ERROR(HW_GPU, "Fp32 denorm flush and preserve on the same shader"); | 157 | // LOG_ERROR(HW_GPU, "Fp32 denorm flush and preserve on the same shader"); |
| 175 | } else if (info.uses_fp32_denorms_flush) { | 158 | } else if (info.uses_fp32_denorms_flush) { |
| @@ -210,6 +193,22 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | |||
| 210 | } | 193 | } |
| 211 | } | 194 | } |
| 212 | 195 | ||
| 196 | void SetupSignedNanCapabilities(const Profile& profile, const IR::Program& program, | ||
| 197 | EmitContext& ctx, Id main_func) { | ||
| 198 | if (program.info.uses_fp16 && profile.support_fp16_signed_zero_nan_preserve) { | ||
| 199 | ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||
| 200 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U); | ||
| 201 | } | ||
| 202 | if (profile.support_fp32_signed_zero_nan_preserve) { | ||
| 203 | ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||
| 204 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U); | ||
| 205 | } | ||
| 206 | if (program.info.uses_fp64 && profile.support_fp64_signed_zero_nan_preserve) { | ||
| 207 | ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||
| 208 | ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 64U); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 213 | void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ctx) { | 212 | void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ctx) { |
| 214 | if (info.uses_sampled_1d) { | 213 | if (info.uses_sampled_1d) { |
| 215 | ctx.AddCapability(spv::Capability::Sampled1D); | 214 | ctx.AddCapability(spv::Capability::Sampled1D); |
| @@ -260,7 +259,11 @@ std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program | |||
| 260 | EmitContext ctx{profile, program, binding}; | 259 | EmitContext ctx{profile, program, binding}; |
| 261 | const Id main{DefineMain(ctx, program)}; | 260 | const Id main{DefineMain(ctx, program)}; |
| 262 | DefineEntryPoint(env, ctx, main); | 261 | DefineEntryPoint(env, ctx, main); |
| 263 | SetupDenormControl(profile, program, ctx, main); | 262 | if (profile.support_float_controls) { |
| 263 | ctx.AddExtension("SPV_KHR_float_controls"); | ||
| 264 | SetupDenormControl(profile, program, ctx, main); | ||
| 265 | SetupSignedNanCapabilities(profile, program, ctx, main); | ||
| 266 | } | ||
| 264 | SetupCapabilities(profile, program.info, ctx); | 267 | SetupCapabilities(profile, program.info, ctx); |
| 265 | return ctx.Assemble(); | 268 | return ctx.Assemble(); |
| 266 | } | 269 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 486ef10a7..960d022ff 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -136,6 +136,7 @@ Id EmitSelectU32(EmitContext& ctx, Id cond, Id true_value, Id false_value); | |||
| 136 | Id EmitSelectU64(EmitContext& ctx, Id cond, Id true_value, Id false_value); | 136 | Id EmitSelectU64(EmitContext& ctx, Id cond, Id true_value, Id false_value); |
| 137 | Id EmitSelectF16(EmitContext& ctx, Id cond, Id true_value, Id false_value); | 137 | Id EmitSelectF16(EmitContext& ctx, Id cond, Id true_value, Id false_value); |
| 138 | Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value); | 138 | Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value); |
| 139 | Id EmitSelectF64(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||
| 139 | void EmitBitCastU16F16(EmitContext& ctx); | 140 | void EmitBitCastU16F16(EmitContext& ctx); |
| 140 | Id EmitBitCastU32F32(EmitContext& ctx, Id value); | 141 | Id EmitBitCastU32F32(EmitContext& ctx, Id value); |
| 141 | void EmitBitCastU64F64(EmitContext& ctx); | 142 | void EmitBitCastU64F64(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp index 0ae127d50..8b0562da5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp | |||
| @@ -35,4 +35,8 @@ Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value) { | |||
| 35 | return ctx.OpSelect(ctx.F32[1], cond, true_value, false_value); | 35 | return ctx.OpSelect(ctx.F32[1], cond, true_value, false_value); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | Id EmitSelectF64(EmitContext& ctx, Id cond, Id true_value, Id false_value) { | ||
| 39 | return ctx.OpSelect(ctx.F64[1], cond, true_value, false_value); | ||
| 40 | } | ||
| 41 | |||
| 38 | } // namespace Shader::Backend::SPIRV | 42 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 00c909f3e..432dd29a5 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -529,6 +529,8 @@ Value IREmitter::Select(const U1& condition, const Value& true_value, const Valu | |||
| 529 | return Inst(Opcode::SelectU64, condition, true_value, false_value); | 529 | return Inst(Opcode::SelectU64, condition, true_value, false_value); |
| 530 | case Type::F32: | 530 | case Type::F32: |
| 531 | return Inst(Opcode::SelectF32, condition, true_value, false_value); | 531 | return Inst(Opcode::SelectF32, condition, true_value, false_value); |
| 532 | case Type::F64: | ||
| 533 | return Inst(Opcode::SelectF64, condition, true_value, false_value); | ||
| 532 | default: | 534 | default: |
| 533 | throw InvalidArgument("Invalid type {}", true_value.Type()); | 535 | throw InvalidArgument("Invalid type {}", true_value.Type()); |
| 534 | } | 536 | } |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 884eea7a8..bdc07b9a7 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -131,6 +131,7 @@ OPCODE(SelectU32, U32, U1, | |||
| 131 | OPCODE(SelectU64, U64, U1, U64, U64, ) | 131 | OPCODE(SelectU64, U64, U1, U64, U64, ) |
| 132 | OPCODE(SelectF16, F16, U1, F16, F16, ) | 132 | OPCODE(SelectF16, F16, U1, F16, F16, ) |
| 133 | OPCODE(SelectF32, F32, U1, F32, F32, ) | 133 | OPCODE(SelectF32, F32, U1, F32, F32, ) |
| 134 | OPCODE(SelectF64, F64, U1, F64, F64, ) | ||
| 134 | 135 | ||
| 135 | // Bitwise conversions | 136 | // Bitwise conversions |
| 136 | OPCODE(BitCastU16F16, U16, F16, ) | 137 | OPCODE(BitCastU16F16, U16, F16, ) |
diff --git a/src/shader_recompiler/frontend/maxwell/maxwell.inc b/src/shader_recompiler/frontend/maxwell/maxwell.inc index 1dfaeb92f..c6cd2a79b 100644 --- a/src/shader_recompiler/frontend/maxwell/maxwell.inc +++ b/src/shader_recompiler/frontend/maxwell/maxwell.inc | |||
| @@ -37,8 +37,8 @@ INST(DFMA_reg, "DFMA (reg)", "0101 1011 0111 ----") | |||
| 37 | INST(DFMA_rc, "DFMA (rc)", "0101 0011 0111 ----") | 37 | INST(DFMA_rc, "DFMA (rc)", "0101 0011 0111 ----") |
| 38 | INST(DFMA_cr, "DFMA (cr)", "0100 1011 0111 ----") | 38 | INST(DFMA_cr, "DFMA (cr)", "0100 1011 0111 ----") |
| 39 | INST(DFMA_imm, "DFMA (imm)", "0011 011- 0111 ----") | 39 | INST(DFMA_imm, "DFMA (imm)", "0011 011- 0111 ----") |
| 40 | INST(DMNMX_reg, "DMNMX (reg)", "0100 1100 0101 0---") | 40 | INST(DMNMX_reg, "DMNMX (reg)", "0101 1100 0101 0---") |
| 41 | INST(DMNMX_cbuf, "DMNMX (cbuf)", "0101 1100 0101 0---") | 41 | INST(DMNMX_cbuf, "DMNMX (cbuf)", "0100 1100 0101 0---") |
| 42 | INST(DMNMX_imm, "DMNMX (imm)", "0011 100- 0101 0---") | 42 | INST(DMNMX_imm, "DMNMX (imm)", "0011 100- 0101 0---") |
| 43 | INST(DMUL_reg, "DMUL (reg)", "0101 1100 1000 0---") | 43 | INST(DMUL_reg, "DMUL (reg)", "0101 1100 1000 0---") |
| 44 | INST(DMUL_cbuf, "DMUL (cbuf)", "0100 1100 1000 0---") | 44 | INST(DMUL_cbuf, "DMUL (cbuf)", "0100 1100 1000 0---") |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp new file mode 100644 index 000000000..e2ec852c9 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h" | ||
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 9 | |||
| 10 | namespace Shader::Maxwell { | ||
| 11 | namespace { | ||
| 12 | void DSET(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) { | ||
| 13 | union { | ||
| 14 | u64 insn; | ||
| 15 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 16 | BitField<8, 8, IR::Reg> src_a_reg; | ||
| 17 | BitField<39, 3, IR::Pred> pred; | ||
| 18 | BitField<42, 1, u64> neg_pred; | ||
| 19 | BitField<43, 1, u64> negate_a; | ||
| 20 | BitField<44, 1, u64> abs_b; | ||
| 21 | BitField<45, 2, BooleanOp> bop; | ||
| 22 | BitField<48, 4, FPCompareOp> compare_op; | ||
| 23 | BitField<52, 1, u64> bf; | ||
| 24 | BitField<53, 1, u64> negate_b; | ||
| 25 | BitField<54, 1, u64> abs_a; | ||
| 26 | } const dset{insn}; | ||
| 27 | |||
| 28 | const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dset.src_a_reg), dset.abs_a != 0, dset.negate_a != 0)}; | ||
| 29 | const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dset.abs_b != 0, dset.negate_b != 0)}; | ||
| 30 | |||
| 31 | IR::U1 pred{v.ir.GetPred(dset.pred)}; | ||
| 32 | if (dset.neg_pred != 0) { | ||
| 33 | pred = v.ir.LogicalNot(pred); | ||
| 34 | } | ||
| 35 | const IR::U1 cmp_result{FloatingPointCompare(v.ir, op_a, op_b, dset.compare_op)}; | ||
| 36 | const IR::U1 bop_result{PredicateCombine(v.ir, cmp_result, pred, dset.bop)}; | ||
| 37 | |||
| 38 | const IR::U32 one_mask{v.ir.Imm32(-1)}; | ||
| 39 | const IR::U32 fp_one{v.ir.Imm32(0x3f800000)}; | ||
| 40 | const IR::U32 fail_result{v.ir.Imm32(0)}; | ||
| 41 | const IR::U32 pass_result{dset.bf == 0 ? one_mask : fp_one}; | ||
| 42 | |||
| 43 | v.X(dset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)}); | ||
| 44 | } | ||
| 45 | } // Anonymous namespace | ||
| 46 | |||
| 47 | void TranslatorVisitor::DSET_reg(u64 insn) { | ||
| 48 | DSET(*this, insn, GetDoubleReg20(insn)); | ||
| 49 | } | ||
| 50 | |||
| 51 | void TranslatorVisitor::DSET_cbuf(u64 insn) { | ||
| 52 | DSET(*this, insn, GetDoubleCbuf(insn)); | ||
| 53 | } | ||
| 54 | |||
| 55 | void TranslatorVisitor::DSET_imm(u64 insn) { | ||
| 56 | DSET(*this, insn, GetDoubleImm20(insn)); | ||
| 57 | } | ||
| 58 | |||
| 59 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp new file mode 100644 index 000000000..55a224db3 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | void DMNMX(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) { | ||
| 12 | union { | ||
| 13 | u64 insn; | ||
| 14 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 15 | BitField<8, 8, IR::Reg> src_a_reg; | ||
| 16 | BitField<39, 3, IR::Pred> pred; | ||
| 17 | BitField<42, 1, u64> neg_pred; | ||
| 18 | BitField<45, 1, u64> negate_b; | ||
| 19 | BitField<46, 1, u64> abs_a; | ||
| 20 | BitField<48, 1, u64> negate_a; | ||
| 21 | BitField<49, 1, u64> abs_b; | ||
| 22 | } const dmnmx{insn}; | ||
| 23 | |||
| 24 | const IR::U1 pred{v.ir.GetPred(dmnmx.pred)}; | ||
| 25 | const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dmnmx.src_a_reg), dmnmx.abs_a != 0, dmnmx.negate_a != 0)}; | ||
| 26 | const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dmnmx.abs_b != 0, dmnmx.negate_b != 0)}; | ||
| 27 | |||
| 28 | IR::F64 max{v.ir.FPMax(op_a, op_b)}; | ||
| 29 | IR::F64 min{v.ir.FPMin(op_a, op_b)}; | ||
| 30 | |||
| 31 | if (dmnmx.neg_pred != 0) { | ||
| 32 | std::swap(min, max); | ||
| 33 | } | ||
| 34 | v.D(dmnmx.dest_reg, IR::F64{v.ir.Select(pred, min, max)}); | ||
| 35 | } | ||
| 36 | } // Anonymous namespace | ||
| 37 | |||
| 38 | void TranslatorVisitor::DMNMX_reg(u64 insn) { | ||
| 39 | DMNMX(*this, insn, GetDoubleReg20(insn)); | ||
| 40 | } | ||
| 41 | |||
| 42 | void TranslatorVisitor::DMNMX_cbuf(u64 insn) { | ||
| 43 | DMNMX(*this, insn, GetDoubleCbuf(insn)); | ||
| 44 | } | ||
| 45 | |||
| 46 | void TranslatorVisitor::DMNMX_imm(u64 insn) { | ||
| 47 | DMNMX(*this, insn, GetDoubleImm20(insn)); | ||
| 48 | } | ||
| 49 | |||
| 50 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_set_predicate.cpp new file mode 100644 index 000000000..b8e74ee44 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_set_predicate.cpp | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h" | ||
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 9 | |||
| 10 | namespace Shader::Maxwell { | ||
| 11 | namespace { | ||
| 12 | void DSETP(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) { | ||
| 13 | union { | ||
| 14 | u64 insn; | ||
| 15 | BitField<0, 3, IR::Pred> dest_pred_b; | ||
| 16 | BitField<3, 3, IR::Pred> dest_pred_a; | ||
| 17 | BitField<6, 1, u64> negate_b; | ||
| 18 | BitField<7, 1, u64> abs_a; | ||
| 19 | BitField<8, 8, IR::Reg> src_a_reg; | ||
| 20 | BitField<39, 3, IR::Pred> bop_pred; | ||
| 21 | BitField<42, 1, u64> neg_bop_pred; | ||
| 22 | BitField<43, 1, u64> negate_a; | ||
| 23 | BitField<44, 1, u64> abs_b; | ||
| 24 | BitField<45, 2, BooleanOp> bop; | ||
| 25 | BitField<48, 4, FPCompareOp> compare_op; | ||
| 26 | } const dsetp{insn}; | ||
| 27 | |||
| 28 | const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dsetp.src_a_reg), dsetp.abs_a != 0, dsetp.negate_a != 0)}; | ||
| 29 | const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dsetp.abs_b != 0, dsetp.negate_b != 0)}; | ||
| 30 | |||
| 31 | const BooleanOp bop{dsetp.bop}; | ||
| 32 | const FPCompareOp compare_op{dsetp.compare_op}; | ||
| 33 | const IR::U1 comparison{FloatingPointCompare(v.ir, op_a, op_b, compare_op)}; | ||
| 34 | const IR::U1 bop_pred{v.ir.GetPred(dsetp.bop_pred, dsetp.neg_bop_pred != 0)}; | ||
| 35 | const IR::U1 result_a{PredicateCombine(v.ir, comparison, bop_pred, bop)}; | ||
| 36 | const IR::U1 result_b{PredicateCombine(v.ir, v.ir.LogicalNot(comparison), bop_pred, bop)}; | ||
| 37 | v.ir.SetPred(dsetp.dest_pred_a, result_a); | ||
| 38 | v.ir.SetPred(dsetp.dest_pred_b, result_b); | ||
| 39 | } | ||
| 40 | } // Anonymous namespace | ||
| 41 | |||
| 42 | void TranslatorVisitor::DSETP_reg(u64 insn) { | ||
| 43 | DSETP(*this, insn, GetDoubleReg20(insn)); | ||
| 44 | } | ||
| 45 | |||
| 46 | void TranslatorVisitor::DSETP_cbuf(u64 insn) { | ||
| 47 | DSETP(*this, insn, GetDoubleCbuf(insn)); | ||
| 48 | } | ||
| 49 | |||
| 50 | void TranslatorVisitor::DSETP_imm(u64 insn) { | ||
| 51 | DSETP(*this, insn, GetDoubleImm20(insn)); | ||
| 52 | } | ||
| 53 | |||
| 54 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp index c3180a9bd..343d91032 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp | |||
| @@ -24,7 +24,7 @@ void FMNMX(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { | |||
| 24 | 24 | ||
| 25 | const IR::U1 pred{v.ir.GetPred(fmnmx.pred)}; | 25 | const IR::U1 pred{v.ir.GetPred(fmnmx.pred)}; |
| 26 | const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fmnmx.src_a_reg), fmnmx.abs_a != 0, fmnmx.negate_a != 0)}; | 26 | const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fmnmx.src_a_reg), fmnmx.abs_a != 0, fmnmx.negate_a != 0)}; |
| 27 | const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0); | 27 | const IR::F32 op_b{v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0)}; |
| 28 | 28 | ||
| 29 | const IR::FpControl control{ | 29 | const IR::FpControl control{ |
| 30 | .no_contraction{false}, | 30 | .no_contraction{false}, |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 08f6eb788..27b12ff3c 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -81,42 +81,6 @@ void TranslatorVisitor::DEPBAR() { | |||
| 81 | // DEPBAR is a no-op | 81 | // DEPBAR is a no-op |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void TranslatorVisitor::DMNMX_reg(u64) { | ||
| 85 | ThrowNotImplemented(Opcode::DMNMX_reg); | ||
| 86 | } | ||
| 87 | |||
| 88 | void TranslatorVisitor::DMNMX_cbuf(u64) { | ||
| 89 | ThrowNotImplemented(Opcode::DMNMX_cbuf); | ||
| 90 | } | ||
| 91 | |||
| 92 | void TranslatorVisitor::DMNMX_imm(u64) { | ||
| 93 | ThrowNotImplemented(Opcode::DMNMX_imm); | ||
| 94 | } | ||
| 95 | |||
| 96 | void TranslatorVisitor::DSET_reg(u64) { | ||
| 97 | ThrowNotImplemented(Opcode::DSET_reg); | ||
| 98 | } | ||
| 99 | |||
| 100 | void TranslatorVisitor::DSET_cbuf(u64) { | ||
| 101 | ThrowNotImplemented(Opcode::DSET_cbuf); | ||
| 102 | } | ||
| 103 | |||
| 104 | void TranslatorVisitor::DSET_imm(u64) { | ||
| 105 | ThrowNotImplemented(Opcode::DSET_imm); | ||
| 106 | } | ||
| 107 | |||
| 108 | void TranslatorVisitor::DSETP_reg(u64) { | ||
| 109 | ThrowNotImplemented(Opcode::DSETP_reg); | ||
| 110 | } | ||
| 111 | |||
| 112 | void TranslatorVisitor::DSETP_cbuf(u64) { | ||
| 113 | ThrowNotImplemented(Opcode::DSETP_cbuf); | ||
| 114 | } | ||
| 115 | |||
| 116 | void TranslatorVisitor::DSETP_imm(u64) { | ||
| 117 | ThrowNotImplemented(Opcode::DSETP_imm); | ||
| 118 | } | ||
| 119 | |||
| 120 | void TranslatorVisitor::FCHK_reg(u64) { | 84 | void TranslatorVisitor::FCHK_reg(u64) { |
| 121 | ThrowNotImplemented(Opcode::FCHK_reg); | 85 | ThrowNotImplemented(Opcode::FCHK_reg); |
| 122 | } | 86 | } |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index e9f64cf3f..f44eac5d8 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -130,6 +130,7 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 130 | case IR::Opcode::CompositeInsertF64x2: | 130 | case IR::Opcode::CompositeInsertF64x2: |
| 131 | case IR::Opcode::CompositeInsertF64x3: | 131 | case IR::Opcode::CompositeInsertF64x3: |
| 132 | case IR::Opcode::CompositeInsertF64x4: | 132 | case IR::Opcode::CompositeInsertF64x4: |
| 133 | case IR::Opcode::SelectF64: | ||
| 133 | case IR::Opcode::BitCastU64F64: | 134 | case IR::Opcode::BitCastU64F64: |
| 134 | case IR::Opcode::BitCastF64U64: | 135 | case IR::Opcode::BitCastF64U64: |
| 135 | case IR::Opcode::PackDouble2x32: | 136 | case IR::Opcode::PackDouble2x32: |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index a39db2bf1..ef7766d22 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -229,7 +229,6 @@ void FoldISub32(IR::Inst& inst) { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | template <typename T> | ||
| 233 | void FoldSelect(IR::Inst& inst) { | 232 | void FoldSelect(IR::Inst& inst) { |
| 234 | const IR::Value cond{inst.Arg(0)}; | 233 | const IR::Value cond{inst.Arg(0)}; |
| 235 | if (cond.IsImmediate()) { | 234 | if (cond.IsImmediate()) { |
| @@ -340,8 +339,15 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 340 | return FoldBitCast<IR::Opcode::BitCastU32F32, u32, f32>(inst, IR::Opcode::BitCastF32U32); | 339 | return FoldBitCast<IR::Opcode::BitCastU32F32, u32, f32>(inst, IR::Opcode::BitCastF32U32); |
| 341 | case IR::Opcode::IAdd64: | 340 | case IR::Opcode::IAdd64: |
| 342 | return FoldAdd<u64>(block, inst); | 341 | return FoldAdd<u64>(block, inst); |
| 342 | case IR::Opcode::SelectU1: | ||
| 343 | case IR::Opcode::SelectU8: | ||
| 344 | case IR::Opcode::SelectU16: | ||
| 343 | case IR::Opcode::SelectU32: | 345 | case IR::Opcode::SelectU32: |
| 344 | return FoldSelect<u32>(inst); | 346 | case IR::Opcode::SelectU64: |
| 347 | case IR::Opcode::SelectF16: | ||
| 348 | case IR::Opcode::SelectF32: | ||
| 349 | case IR::Opcode::SelectF64: | ||
| 350 | return FoldSelect(inst); | ||
| 345 | case IR::Opcode::LogicalAnd: | 351 | case IR::Opcode::LogicalAnd: |
| 346 | return FoldLogicalAnd(inst); | 352 | return FoldLogicalAnd(inst); |
| 347 | case IR::Opcode::LogicalOr: | 353 | case IR::Opcode::LogicalOr: |
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 770299524..3181c79fb 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h | |||
| @@ -18,6 +18,7 @@ struct Profile { | |||
| 18 | bool support_fp32_denorm_flush{}; | 18 | bool support_fp32_denorm_flush{}; |
| 19 | bool support_fp16_signed_zero_nan_preserve{}; | 19 | bool support_fp16_signed_zero_nan_preserve{}; |
| 20 | bool support_fp32_signed_zero_nan_preserve{}; | 20 | bool support_fp32_signed_zero_nan_preserve{}; |
| 21 | bool support_fp64_signed_zero_nan_preserve{}; | ||
| 21 | 22 | ||
| 22 | // FClamp is broken and OpFMax + OpFMin should be used instead | 23 | // FClamp is broken and OpFMax + OpFMin should be used instead |
| 23 | bool has_broken_spirv_clamp{}; | 24 | bool has_broken_spirv_clamp{}; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 90e1a30f6..75f7c1e61 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -244,6 +244,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_, | |||
| 244 | float_control.shaderSignedZeroInfNanPreserveFloat16 != VK_FALSE, | 244 | float_control.shaderSignedZeroInfNanPreserveFloat16 != VK_FALSE, |
| 245 | .support_fp32_signed_zero_nan_preserve = | 245 | .support_fp32_signed_zero_nan_preserve = |
| 246 | float_control.shaderSignedZeroInfNanPreserveFloat32 != VK_FALSE, | 246 | float_control.shaderSignedZeroInfNanPreserveFloat32 != VK_FALSE, |
| 247 | .support_fp64_signed_zero_nan_preserve = | ||
| 248 | float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE, | ||
| 247 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | 249 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, |
| 248 | }; | 250 | }; |
| 249 | } | 251 | } |