summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-19 21:09:02 -0400
committerGravatar GitHub2018-04-19 21:09:02 -0400
commitf633b0c87557101ae30fa2657621e804c9d637c9 (patch)
tree4013d5a2feccf26c16060ae72c42c200d8da3482
parentMerge pull request #348 from jlachniet/patch-1 (diff)
parentShaderGen: Implemented the fmul32i shader instruction. (diff)
downloadyuzu-f633b0c87557101ae30fa2657621e804c9d637c9.tar.gz
yuzu-f633b0c87557101ae30fa2657621e804c9d637c9.tar.xz
yuzu-f633b0c87557101ae30fa2657621e804c9d637c9.zip
Merge pull request #355 from Subv/shader_instr
ShaderGen: Fixed TEXS overriding its own texcoords and implemented fmul32i
Diffstat (limited to '')
-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 6233ee358..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 }
@@ -399,11 +409,18 @@ private:
399 const std::string op_a = GetRegister(instr.gpr8); 409 const std::string op_a = GetRegister(instr.gpr8);
400 const std::string op_b = GetRegister(instr.gpr20); 410 const std::string op_b = GetRegister(instr.gpr20);
401 const std::string sampler = GetSampler(instr.sampler); 411 const std::string sampler = GetSampler(instr.sampler);
402 const std::string coord = "vec2(" + op_a + ", " + op_b + ")"; 412 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
403 const std::string texture = "texture(" + sampler + ", " + coord + ")"; 413 // Add an extra scope and declare the texture coords inside to prevent overwriting
414 // them in case they are used as outputs of the texs instruction.
415 shader.AddLine("{");
416 ++shader.scope;
417 shader.AddLine(coord);
418 const std::string texture = "texture(" + sampler + ", coords)";
404 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) { 419 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) {
405 SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4); 420 SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4);
406 } 421 }
422 --shader.scope;
423 shader.AddLine("}");
407 break; 424 break;
408 } 425 }
409 default: { 426 default: {
@@ -586,7 +603,7 @@ private:
586 std::set<Attribute::Index> declr_input_attribute; 603 std::set<Attribute::Index> declr_input_attribute;
587 std::set<Attribute::Index> declr_output_attribute; 604 std::set<Attribute::Index> declr_output_attribute;
588 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers; 605 std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers;
589}; 606}; // namespace Decompiler
590 607
591std::string GetCommonDeclarations() { 608std::string GetCommonDeclarations() {
592 return "bool exec_shader();"; 609 return "bool exec_shader();";