summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h17
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp22
2 files changed, 30 insertions, 9 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index ed66d893a..7cd125f05 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -90,6 +90,7 @@ union OpCode {
90 enum class Id : u64 { 90 enum class Id : u64 {
91 TEXS = 0x6C, 91 TEXS = 0x6C,
92 IPA = 0xE0, 92 IPA = 0xE0,
93 FMUL32_IMM = 0x1E,
93 FFMA_IMM = 0x65, 94 FFMA_IMM = 0x65,
94 FFMA_CR = 0x93, 95 FFMA_CR = 0x93,
95 FFMA_RC = 0xA3, 96 FFMA_RC = 0xA3,
@@ -142,6 +143,7 @@ union OpCode {
142 143
143 switch (op2) { 144 switch (op2) {
144 case Id::IPA: 145 case Id::IPA:
146 case Id::FMUL32_IMM:
145 return op2; 147 return op2;
146 } 148 }
147 149
@@ -235,6 +237,7 @@ union OpCode {
235 info_table[Id::FMUL_R] = {Type::Arithmetic, "fmul_r"}; 237 info_table[Id::FMUL_R] = {Type::Arithmetic, "fmul_r"};
236 info_table[Id::FMUL_C] = {Type::Arithmetic, "fmul_c"}; 238 info_table[Id::FMUL_C] = {Type::Arithmetic, "fmul_c"};
237 info_table[Id::FMUL_IMM] = {Type::Arithmetic, "fmul_imm"}; 239 info_table[Id::FMUL_IMM] = {Type::Arithmetic, "fmul_imm"};
240 info_table[Id::FMUL32_IMM] = {Type::Arithmetic, "fmul32_imm"};
238 info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"}; 241 info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"};
239 info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"}; 242 info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"};
240 info_table[Id::EXIT] = {Type::Trivial, "exit"}; 243 info_table[Id::EXIT] = {Type::Trivial, "exit"};
@@ -309,7 +312,8 @@ union Instruction {
309 BitField<39, 8, Register> gpr39; 312 BitField<39, 8, Register> gpr39;
310 313
311 union { 314 union {
312 BitField<20, 19, u64> imm20; 315 BitField<20, 19, u64> imm20_19;
316 BitField<20, 32, u64> imm20_32;
313 BitField<45, 1, u64> negate_b; 317 BitField<45, 1, u64> negate_b;
314 BitField<46, 1, u64> abs_a; 318 BitField<46, 1, u64> abs_a;
315 BitField<48, 1, u64> negate_a; 319 BitField<48, 1, u64> negate_a;
@@ -317,14 +321,21 @@ union Instruction {
317 BitField<50, 1, u64> abs_d; 321 BitField<50, 1, u64> abs_d;
318 BitField<56, 1, u64> negate_imm; 322 BitField<56, 1, u64> negate_imm;
319 323
320 float GetImm20() const { 324 float GetImm20_19() const {
321 float result{}; 325 float result{};
322 u32 imm{static_cast<u32>(imm20)}; 326 u32 imm{static_cast<u32>(imm20_19)};
323 imm <<= 12; 327 imm <<= 12;
324 imm |= negate_imm ? 0x80000000 : 0; 328 imm |= negate_imm ? 0x80000000 : 0;
325 std::memcpy(&result, &imm, sizeof(imm)); 329 std::memcpy(&result, &imm, sizeof(imm));
326 return result; 330 return result;
327 } 331 }
332
333 float GetImm20_32() const {
334 float result{};
335 u32 imm{static_cast<u32>(imm20_32)};
336 std::memcpy(&result, &imm, sizeof(imm));
337 return result;
338 }
328 } alu; 339 } alu;
329 340
330 union { 341 union {
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index b18f25026..4cc617c97 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -190,9 +190,14 @@ private:
190 } 190 }
191 } 191 }
192 192
193 /// Generates code representing an immediate value 193 /// Generates code representing a 19-bit immediate value
194 static std::string GetImmediate(const Instruction& instr) { 194 static std::string GetImmediate19(const Instruction& instr) {
195 return std::to_string(instr.alu.GetImm20()); 195 return std::to_string(instr.alu.GetImm20_19());
196 }
197
198 /// Generates code representing a 32-bit immediate value
199 static std::string GetImmediate32(const Instruction& instr) {
200 return std::to_string(instr.alu.GetImm20_32());
196 } 201 }
197 202
198 /// Generates code representing a temporary (GPR) register. 203 /// Generates code representing a temporary (GPR) register.
@@ -276,7 +281,7 @@ private:
276 std::string op_b = instr.alu.negate_b ? "-" : ""; 281 std::string op_b = instr.alu.negate_b ? "-" : "";
277 282
278 if (instr.is_b_imm) { 283 if (instr.is_b_imm) {
279 op_b += GetImmediate(instr); 284 op_b += GetImmediate19(instr);
280 } else { 285 } else {
281 if (instr.is_b_gpr) { 286 if (instr.is_b_gpr) {
282 op_b += GetRegister(instr.gpr20); 287 op_b += GetRegister(instr.gpr20);
@@ -296,6 +301,11 @@ private:
296 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); 301 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d);
297 break; 302 break;
298 } 303 }
304 case OpCode::Id::FMUL32_IMM: {
305 // fmul32i doesn't have abs or neg bits.
306 SetDest(0, dest, GetRegister(instr.gpr8) + " * " + GetImmediate32(instr), 1, 1);
307 break;
308 }
299 case OpCode::Id::FADD_C: 309 case OpCode::Id::FADD_C:
300 case OpCode::Id::FADD_R: 310 case OpCode::Id::FADD_R:
301 case OpCode::Id::FADD_IMM: { 311 case OpCode::Id::FADD_IMM: {
@@ -364,7 +374,7 @@ private:
364 break; 374 break;
365 } 375 }
366 case OpCode::Id::FFMA_IMM: { 376 case OpCode::Id::FFMA_IMM: {
367 op_b += GetImmediate(instr); 377 op_b += GetImmediate19(instr);
368 op_c += GetRegister(instr.gpr39); 378 op_c += GetRegister(instr.gpr39);
369 break; 379 break;
370 } 380 }
@@ -593,7 +603,7 @@ private:
593 std::set<Attribute::Index> declr_input_attribute; 603 std::set<Attribute::Index> declr_input_attribute;
594 std::set<Attribute::Index> declr_output_attribute; 604 std::set<Attribute::Index> declr_output_attribute;
595 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers; 605 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers;
596}; 606}; // namespace Decompiler
597 607
598std::string GetCommonDeclarations() { 608std::string GetCommonDeclarations() {
599 return "bool exec_shader();"; 609 return "bool exec_shader();";