diff options
| author | 2018-04-19 21:09:02 -0400 | |
|---|---|---|
| committer | 2018-04-19 21:09:02 -0400 | |
| commit | f633b0c87557101ae30fa2657621e804c9d637c9 (patch) | |
| tree | 4013d5a2feccf26c16060ae72c42c200d8da3482 | |
| parent | Merge pull request #348 from jlachniet/patch-1 (diff) | |
| parent | ShaderGen: Implemented the fmul32i shader instruction. (diff) | |
| download | yuzu-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.h | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 33 |
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 | ||
| 591 | std::string GetCommonDeclarations() { | 608 | std::string GetCommonDeclarations() { |
| 592 | return "bool exec_shader();"; | 609 | return "bool exec_shader();"; |