diff options
| author | 2021-02-26 21:41:46 -0500 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | a8c41c50d3f7a1c2871487862f68925db8b5e27f (patch) | |
| tree | 06c37fb9cb9071b9fdeea4a61518d4b1e11a5968 | |
| parent | shader: Implement SHR (diff) | |
| download | yuzu-a8c41c50d3f7a1c2871487862f68925db8b5e27f.tar.gz yuzu-a8c41c50d3f7a1c2871487862f68925db8b5e27f.tar.xz yuzu-a8c41c50d3f7a1c2871487862f68925db8b5e27f.zip | |
shader: Implement POPC
8 files changed, 59 insertions, 12 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 14dc51b5f..b4d2dcc42 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -69,6 +69,7 @@ add_library(shader_recompiler STATIC | |||
| 69 | frontend/maxwell/translate/impl/impl.cpp | 69 | frontend/maxwell/translate/impl/impl.cpp |
| 70 | frontend/maxwell/translate/impl/impl.h | 70 | frontend/maxwell/translate/impl/impl.h |
| 71 | frontend/maxwell/translate/impl/integer_add.cpp | 71 | frontend/maxwell/translate/impl/integer_add.cpp |
| 72 | frontend/maxwell/translate/impl/integer_popcount.cpp | ||
| 72 | frontend/maxwell/translate/impl/integer_scaled_add.cpp | 73 | frontend/maxwell/translate/impl/integer_scaled_add.cpp |
| 73 | frontend/maxwell/translate/impl/integer_set_predicate.cpp | 74 | frontend/maxwell/translate/impl/integer_set_predicate.cpp |
| 74 | frontend/maxwell/translate/impl/integer_shift_left.cpp | 75 | frontend/maxwell/translate/impl/integer_shift_left.cpp |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 90afbcc90..64c8e9ef6 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -228,6 +228,8 @@ Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count) | |||
| 228 | Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); | 228 | Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); |
| 229 | Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); | 229 | Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); |
| 230 | Id EmitBitReverse32(EmitContext& ctx, Id value); | 230 | Id EmitBitReverse32(EmitContext& ctx, Id value); |
| 231 | Id EmitBitCount32(EmitContext& ctx, Id value); | ||
| 232 | Id EmitBitwiseNot32(EmitContext& ctx, Id a); | ||
| 231 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); | 233 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); |
| 232 | Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); | 234 | Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); |
| 233 | Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); | 235 | Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index 406df1b78..e49ca7bde 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | |||
| @@ -106,6 +106,14 @@ Id EmitBitReverse32(EmitContext& ctx, Id value) { | |||
| 106 | return ctx.OpBitReverse(ctx.U32[1], value); | 106 | return ctx.OpBitReverse(ctx.U32[1], value); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | Id EmitBitCount32(EmitContext& ctx, Id value) { | ||
| 110 | return ctx.OpBitCount(ctx.U32[1], value); | ||
| 111 | } | ||
| 112 | |||
| 113 | Id EmitBitwiseNot32(EmitContext& ctx, Id a) { | ||
| 114 | return ctx.OpNot(ctx.U32[1], a); | ||
| 115 | } | ||
| 116 | |||
| 109 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) { | 117 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) { |
| 110 | return ctx.OpSLessThan(ctx.U1, lhs, rhs); | 118 | return ctx.OpSLessThan(ctx.U1, lhs, rhs); |
| 111 | } | 119 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 7c3908398..54fdf9559 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -808,6 +808,14 @@ U32 IREmitter::BitReverse(const U32& value) { | |||
| 808 | return Inst<U32>(Opcode::BitReverse32, value); | 808 | return Inst<U32>(Opcode::BitReverse32, value); |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | U32 IREmitter::BitCount(const U32& value) { | ||
| 812 | return Inst<U32>(Opcode::BitCount32, value); | ||
| 813 | } | ||
| 814 | |||
| 815 | U32 IREmitter::BitwiseNot(const U32& a) { | ||
| 816 | return Inst<U32>(Opcode::BitwiseNot32, a); | ||
| 817 | } | ||
| 818 | |||
| 811 | U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) { | 819 | U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) { |
| 812 | return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs); | 820 | return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs); |
| 813 | } | 821 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index f7998e156..9dec22145 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -160,6 +160,8 @@ public: | |||
| 160 | [[nodiscard]] U32 BitFieldExtract(const U32& base, const U32& offset, const U32& count, | 160 | [[nodiscard]] U32 BitFieldExtract(const U32& base, const U32& offset, const U32& count, |
| 161 | bool is_signed); | 161 | bool is_signed); |
| 162 | [[nodiscard]] U32 BitReverse(const U32& value); | 162 | [[nodiscard]] U32 BitReverse(const U32& value); |
| 163 | [[nodiscard]] U32 BitCount(const U32& value); | ||
| 164 | [[nodiscard]] U32 BitwiseNot(const U32& a); | ||
| 163 | 165 | ||
| 164 | [[nodiscard]] U1 ILessThan(const U32& lhs, const U32& rhs, bool is_signed); | 166 | [[nodiscard]] U1 ILessThan(const U32& lhs, const U32& rhs, bool is_signed); |
| 165 | [[nodiscard]] U1 IEqual(const U32& lhs, const U32& rhs); | 167 | [[nodiscard]] U1 IEqual(const U32& lhs, const U32& rhs); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index f420f1161..59a13e911 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -232,6 +232,8 @@ OPCODE(BitFieldInsert, U32, U32, | |||
| 232 | OPCODE(BitFieldSExtract, U32, U32, U32, U32, ) | 232 | OPCODE(BitFieldSExtract, U32, U32, U32, U32, ) |
| 233 | OPCODE(BitFieldUExtract, U32, U32, U32, U32, ) | 233 | OPCODE(BitFieldUExtract, U32, U32, U32, U32, ) |
| 234 | OPCODE(BitReverse32, U32, U32, ) | 234 | OPCODE(BitReverse32, U32, U32, ) |
| 235 | OPCODE(BitCount32, U32, U32, ) | ||
| 236 | OPCODE(BitwiseNot32, U32, U32, ) | ||
| 235 | 237 | ||
| 236 | OPCODE(SLessThan, U1, U32, U32, ) | 238 | OPCODE(SLessThan, U1, U32, U32, ) |
| 237 | OPCODE(ULessThan, U1, U32, U32, ) | 239 | OPCODE(ULessThan, U1, U32, U32, ) |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_popcount.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_popcount.cpp new file mode 100644 index 000000000..5ece7678d --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_popcount.cpp | |||
| @@ -0,0 +1,36 @@ | |||
| 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 POPC(TranslatorVisitor& v, u64 insn, const IR::U32& src) { | ||
| 12 | union { | ||
| 13 | u64 raw; | ||
| 14 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 15 | BitField<40, 1, u64> tilde; | ||
| 16 | } const popc{insn}; | ||
| 17 | |||
| 18 | const IR::U32 operand = popc.tilde == 0 ? src : v.ir.BitwiseNot(src); | ||
| 19 | const IR::U32 result = v.ir.BitCount(operand); | ||
| 20 | v.X(popc.dest_reg, result); | ||
| 21 | } | ||
| 22 | } // Anonymous namespace | ||
| 23 | |||
| 24 | void TranslatorVisitor::POPC_reg(u64 insn) { | ||
| 25 | POPC(*this, insn, GetReg20(insn)); | ||
| 26 | } | ||
| 27 | |||
| 28 | void TranslatorVisitor::POPC_cbuf(u64 insn) { | ||
| 29 | POPC(*this, insn, GetCbuf(insn)); | ||
| 30 | } | ||
| 31 | |||
| 32 | void TranslatorVisitor::POPC_imm(u64 insn) { | ||
| 33 | POPC(*this, insn, GetImm20(insn)); | ||
| 34 | } | ||
| 35 | |||
| 36 | } // namespace Shader::Maxwell | ||
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 45ed04e25..127686b43 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -653,18 +653,6 @@ void TranslatorVisitor::PLONGJMP(u64) { | |||
| 653 | ThrowNotImplemented(Opcode::PLONGJMP); | 653 | ThrowNotImplemented(Opcode::PLONGJMP); |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | void TranslatorVisitor::POPC_reg(u64) { | ||
| 657 | ThrowNotImplemented(Opcode::POPC_reg); | ||
| 658 | } | ||
| 659 | |||
| 660 | void TranslatorVisitor::POPC_cbuf(u64) { | ||
| 661 | ThrowNotImplemented(Opcode::POPC_cbuf); | ||
| 662 | } | ||
| 663 | |||
| 664 | void TranslatorVisitor::POPC_imm(u64) { | ||
| 665 | ThrowNotImplemented(Opcode::POPC_imm); | ||
| 666 | } | ||
| 667 | |||
| 668 | void TranslatorVisitor::PRET(u64) { | 656 | void TranslatorVisitor::PRET(u64) { |
| 669 | ThrowNotImplemented(Opcode::PRET); | 657 | ThrowNotImplemented(Opcode::PRET); |
| 670 | } | 658 | } |