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.cpp33
2 files changed, 39 insertions, 11 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 22a413b73..de137558d 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -208,9 +208,14 @@ private:
208 } 208 }
209 } 209 }
210 210
211 /// Generates code representing an immediate value 211 /// Generates code representing a 19-bit immediate value
212 static std::string GetImmediate(const Instruction& instr) { 212 static std::string GetImmediate19(const Instruction& instr) {
213 return std::to_string(instr.alu.GetImm20()); 213 return std::to_string(instr.alu.GetImm20_19());
214 }
215
216 /// Generates code representing a 32-bit immediate value
217 static std::string GetImmediate32(const Instruction& instr) {
218 return std::to_string(instr.alu.GetImm20_32());
214 } 219 }
215 220
216 /// Generates code representing a temporary (GPR) register. 221 /// Generates code representing a temporary (GPR) register.
@@ -294,7 +299,7 @@ private:
294 std::string op_b = instr.alu.negate_b ? "-" : ""; 299 std::string op_b = instr.alu.negate_b ? "-" : "";
295 300
296 if (instr.is_b_imm) { 301 if (instr.is_b_imm) {
297 op_b += GetImmediate(instr); 302 op_b += GetImmediate19(instr);
298 } else { 303 } else {
299 if (instr.is_b_gpr) { 304 if (instr.is_b_gpr) {
300 op_b += GetRegister(instr.gpr20); 305 op_b += GetRegister(instr.gpr20);
@@ -314,6 +319,11 @@ private:
314 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); 319 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d);
315 break; 320 break;
316 } 321 }
322 case OpCode::Id::FMUL32_IMM: {
323 // fmul32i doesn't have abs or neg bits.
324 SetDest(0, dest, GetRegister(instr.gpr8) + " * " + GetImmediate32(instr), 1, 1);
325 break;
326 }
317 case OpCode::Id::FADD_C: 327 case OpCode::Id::FADD_C:
318 case OpCode::Id::FADD_R: 328 case OpCode::Id::FADD_R:
319 case OpCode::Id::FADD_IMM: { 329 case OpCode::Id::FADD_IMM: {
@@ -382,7 +392,7 @@ private:
382 break; 392 break;
383 } 393 }
384 case OpCode::Id::FFMA_IMM: { 394 case OpCode::Id::FFMA_IMM: {
385 op_b += GetImmediate(instr); 395 op_b += GetImmediate19(instr);
386 op_c += GetRegister(instr.gpr39); 396 op_c += GetRegister(instr.gpr39);
387 break; 397 break;
388 } 398 }
@@ -417,11 +427,18 @@ private:
417 const std::string op_a = GetRegister(instr.gpr8); 427 const std::string op_a = GetRegister(instr.gpr8);
418 const std::string op_b = GetRegister(instr.gpr20); 428 const std::string op_b = GetRegister(instr.gpr20);
419 const std::string sampler = GetSampler(instr.sampler); 429 const std::string sampler = GetSampler(instr.sampler);
420 const std::string coord = "vec2(" + op_a + ", " + op_b + ")"; 430 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
421 const std::string texture = "texture(" + sampler + ", " + coord + ")"; 431 // Add an extra scope and declare the texture coords inside to prevent overwriting
432 // them in case they are used as outputs of the texs instruction.
433 shader.AddLine("{");
434 ++shader.scope;
435 shader.AddLine(coord);
436 const std::string texture = "texture(" + sampler + ", coords)";
422 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) { 437 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) {
423 SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4); 438 SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4);
424 } 439 }
440 --shader.scope;
441 shader.AddLine("}");
425 break; 442 break;
426 } 443 }
427 default: { 444 default: {
@@ -604,7 +621,7 @@ private:
604 std::set<Attribute::Index> declr_input_attribute; 621 std::set<Attribute::Index> declr_input_attribute;
605 std::set<Attribute::Index> declr_output_attribute; 622 std::set<Attribute::Index> declr_output_attribute;
606 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers; 623 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers;
607}; 624}; // namespace Decompiler
608 625
609std::string GetCommonDeclarations() { 626std::string GetCommonDeclarations() {
610 return "bool exec_shader();"; 627 return "bool exec_shader();";