diff options
| author | 2018-07-04 15:25:48 -0500 | |
|---|---|---|
| committer | 2018-07-04 15:44:37 -0500 | |
| commit | b0c92b80b156e75fcc5eedbbb8370fedd18b5ac4 (patch) | |
| tree | 2fd76c932b7ca4bed70e9a6c1f7b71e9e93090ab /src | |
| parent | Merge pull request #618 from Subv/clear_used_buffers (diff) | |
| download | yuzu-b0c92b80b156e75fcc5eedbbb8370fedd18b5ac4.tar.gz yuzu-b0c92b80b156e75fcc5eedbbb8370fedd18b5ac4.tar.xz yuzu-b0c92b80b156e75fcc5eedbbb8370fedd18b5ac4.zip | |
GPU: Implemented the IMNMX shader instruction.
It's similar to the FMNMX instruction but it works on integers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 14 |
2 files changed, 31 insertions, 3 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c1226a649..31684c410 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -194,6 +194,13 @@ enum class UniformType : u64 { | |||
| 194 | Double = 5, | 194 | Double = 5, |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
| 197 | enum class IMinMaxExchange : u64 { | ||
| 198 | None = 0, | ||
| 199 | XLo = 1, | ||
| 200 | XMed = 2, | ||
| 201 | XHi = 3, | ||
| 202 | }; | ||
| 203 | |||
| 197 | union Instruction { | 204 | union Instruction { |
| 198 | Instruction& operator=(const Instruction& instr) { | 205 | Instruction& operator=(const Instruction& instr) { |
| 199 | value = instr.value; | 206 | value = instr.value; |
| @@ -279,6 +286,13 @@ union Instruction { | |||
| 279 | } alu_integer; | 286 | } alu_integer; |
| 280 | 287 | ||
| 281 | union { | 288 | union { |
| 289 | BitField<39, 3, u64> pred; | ||
| 290 | BitField<42, 1, u64> negate_pred; | ||
| 291 | BitField<43, 2, IMinMaxExchange> exchange; | ||
| 292 | BitField<48, 1, u64> is_signed; | ||
| 293 | } imnmx; | ||
| 294 | |||
| 295 | union { | ||
| 282 | BitField<54, 1, u64> saturate; | 296 | BitField<54, 1, u64> saturate; |
| 283 | BitField<56, 1, u64> negate_a; | 297 | BitField<56, 1, u64> negate_a; |
| 284 | } iadd32i; | 298 | } iadd32i; |
| @@ -682,9 +696,9 @@ private: | |||
| 682 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), | 696 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), |
| 683 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), | 697 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), |
| 684 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), | 698 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), |
| 685 | INST("0100110000100---", Id::IMNMX_C, Type::Arithmetic, "FMNMX_IMM"), | 699 | INST("0100110000100---", Id::IMNMX_C, Type::ArithmeticInteger, "IMNMX_C"), |
| 686 | INST("0101110000100---", Id::IMNMX_R, Type::Arithmetic, "FMNMX_IMM"), | 700 | INST("0101110000100---", Id::IMNMX_R, Type::ArithmeticInteger, "IMNMX_R"), |
| 687 | INST("0011100-00100---", Id::IMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), | 701 | INST("0011100-00100---", Id::IMNMX_IMM, Type::ArithmeticInteger, "IMNMX_IMM"), |
| 688 | INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), | 702 | INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), |
| 689 | INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), | 703 | INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), |
| 690 | INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), | 704 | INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index ec9956edb..9d43d0fb1 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1127,6 +1127,20 @@ private: | |||
| 1127 | WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b); | 1127 | WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b); |
| 1128 | break; | 1128 | break; |
| 1129 | } | 1129 | } |
| 1130 | case OpCode::Id::IMNMX_C: | ||
| 1131 | case OpCode::Id::IMNMX_R: | ||
| 1132 | case OpCode::Id::IMNMX_IMM: { | ||
| 1133 | ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, | ||
| 1134 | "Unimplemented"); | ||
| 1135 | std::string condition = | ||
| 1136 | GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); | ||
| 1137 | std::string parameters = op_a + ',' + op_b; | ||
| 1138 | regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, | ||
| 1139 | '(' + condition + ") ? min(" + parameters + ") : max(" + | ||
| 1140 | parameters + ')', | ||
| 1141 | 1, 1); | ||
| 1142 | break; | ||
| 1143 | } | ||
| 1130 | default: { | 1144 | default: { |
| 1131 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", | 1145 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", |
| 1132 | opcode->GetName()); | 1146 | opcode->GetName()); |