diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 51 |
2 files changed, 53 insertions, 12 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 51cf4af9f..c368fa7fd 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstring> | ||
| 7 | #include <map> | 8 | #include <map> |
| 8 | #include <string> | 9 | #include <string> |
| 9 | #include "common/bit_field.h" | 10 | #include "common/bit_field.h" |
| @@ -289,6 +290,7 @@ enum class SubOp : u64 { | |||
| 289 | Lg2 = 0x3, | 290 | Lg2 = 0x3, |
| 290 | Rcp = 0x4, | 291 | Rcp = 0x4, |
| 291 | Rsq = 0x5, | 292 | Rsq = 0x5, |
| 293 | Min = 0x8, | ||
| 292 | }; | 294 | }; |
| 293 | 295 | ||
| 294 | union Instruction { | 296 | union Instruction { |
| @@ -307,11 +309,22 @@ union Instruction { | |||
| 307 | BitField<39, 8, Register> gpr39; | 309 | BitField<39, 8, Register> gpr39; |
| 308 | 310 | ||
| 309 | union { | 311 | union { |
| 312 | BitField<20, 19, u64> imm20; | ||
| 310 | BitField<45, 1, u64> negate_b; | 313 | BitField<45, 1, u64> negate_b; |
| 311 | BitField<46, 1, u64> abs_a; | 314 | BitField<46, 1, u64> abs_a; |
| 312 | BitField<48, 1, u64> negate_a; | 315 | BitField<48, 1, u64> negate_a; |
| 313 | BitField<49, 1, u64> abs_b; | 316 | BitField<49, 1, u64> abs_b; |
| 314 | BitField<50, 1, u64> abs_d; | 317 | BitField<50, 1, u64> abs_d; |
| 318 | BitField<56, 1, u64> negate_imm; | ||
| 319 | |||
| 320 | float GetImm20() const { | ||
| 321 | float result{}; | ||
| 322 | u32 imm{static_cast<u32>(imm20)}; | ||
| 323 | imm <<= 12; | ||
| 324 | imm |= negate_imm ? 0x80000000 : 0; | ||
| 325 | std::memcpy(&result, &imm, sizeof(imm)); | ||
| 326 | return result; | ||
| 327 | } | ||
| 315 | } alu; | 328 | } alu; |
| 316 | 329 | ||
| 317 | union { | 330 | union { |
| @@ -319,6 +332,7 @@ union Instruction { | |||
| 319 | BitField<49, 1, u64> negate_c; | 332 | BitField<49, 1, u64> negate_c; |
| 320 | } ffma; | 333 | } ffma; |
| 321 | 334 | ||
| 335 | BitField<61, 1, u64> is_b_imm; | ||
| 322 | BitField<60, 1, u64> is_b_gpr; | 336 | BitField<60, 1, u64> is_b_gpr; |
| 323 | BitField<59, 1, u64> is_c_gpr; | 337 | BitField<59, 1, u64> is_c_gpr; |
| 324 | 338 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 1d8057927..aa435e5cc 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -190,6 +190,11 @@ private: | |||
| 190 | } | 190 | } |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | /// Generates code representing an immediate value | ||
| 194 | static std::string GetImmediate(const Instruction& instr) { | ||
| 195 | return std::to_string(instr.alu.GetImm20()); | ||
| 196 | } | ||
| 197 | |||
| 193 | /// Generates code representing a temporary (GPR) register. | 198 | /// Generates code representing a temporary (GPR) register. |
| 194 | std::string GetRegister(const Register& reg, unsigned elem = 0) { | 199 | std::string GetRegister(const Register& reg, unsigned elem = 0) { |
| 195 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) { | 200 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) { |
| @@ -269,24 +274,32 @@ private: | |||
| 269 | } | 274 | } |
| 270 | 275 | ||
| 271 | std::string op_b = instr.alu.negate_b ? "-" : ""; | 276 | std::string op_b = instr.alu.negate_b ? "-" : ""; |
| 272 | if (instr.is_b_gpr) { | 277 | |
| 273 | op_b += GetRegister(instr.gpr20); | 278 | if (instr.is_b_imm) { |
| 279 | op_b += GetImmediate(instr); | ||
| 274 | } else { | 280 | } else { |
| 275 | op_b += GetUniform(instr.uniform); | 281 | if (instr.is_b_gpr) { |
| 282 | op_b += GetRegister(instr.gpr20); | ||
| 283 | } else { | ||
| 284 | op_b += GetUniform(instr.uniform); | ||
| 285 | } | ||
| 276 | } | 286 | } |
| 287 | |||
| 277 | if (instr.alu.abs_b) { | 288 | if (instr.alu.abs_b) { |
| 278 | op_b = "abs(" + op_b + ")"; | 289 | op_b = "abs(" + op_b + ")"; |
| 279 | } | 290 | } |
| 280 | 291 | ||
| 281 | switch (instr.opcode.EffectiveOpCode()) { | 292 | switch (instr.opcode.EffectiveOpCode()) { |
| 282 | case OpCode::Id::FMUL_C: | 293 | case OpCode::Id::FMUL_C: |
| 283 | case OpCode::Id::FMUL_R: { | 294 | case OpCode::Id::FMUL_R: |
| 284 | SetDest(0, dest, op_a + " * " + op_b, 1, 1); | 295 | case OpCode::Id::FMUL_IMM: { |
| 296 | SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); | ||
| 285 | break; | 297 | break; |
| 286 | } | 298 | } |
| 287 | case OpCode::Id::FADD_C: | 299 | case OpCode::Id::FADD_C: |
| 288 | case OpCode::Id::FADD_R: { | 300 | case OpCode::Id::FADD_R: |
| 289 | SetDest(0, dest, op_a + " + " + op_b, 1, 1); | 301 | case OpCode::Id::FADD_IMM: { |
| 302 | SetDest(0, dest, op_a + " + " + op_b, 1, 1, instr.alu.abs_d); | ||
| 290 | break; | 303 | break; |
| 291 | } | 304 | } |
| 292 | case OpCode::Id::MUFU: { | 305 | case OpCode::Id::MUFU: { |
| @@ -316,16 +329,28 @@ private: | |||
| 316 | 329 | ||
| 317 | std::string dest = GetRegister(instr.gpr0); | 330 | std::string dest = GetRegister(instr.gpr0); |
| 318 | std::string op_a = GetRegister(instr.gpr8); | 331 | std::string op_a = GetRegister(instr.gpr8); |
| 319 | |||
| 320 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 332 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |
| 321 | op_b += GetUniform(instr.uniform); | ||
| 322 | |||
| 323 | std::string op_c = instr.ffma.negate_c ? "-" : ""; | 333 | std::string op_c = instr.ffma.negate_c ? "-" : ""; |
| 324 | op_c += GetRegister(instr.gpr39); | ||
| 325 | 334 | ||
| 326 | switch (instr.opcode.EffectiveOpCode()) { | 335 | switch (instr.opcode.EffectiveOpCode()) { |
| 327 | case OpCode::Id::FFMA_CR: { | 336 | case OpCode::Id::FFMA_CR: { |
| 328 | SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1); | 337 | op_b += GetUniform(instr.uniform); |
| 338 | op_c += GetRegister(instr.gpr39); | ||
| 339 | break; | ||
| 340 | } | ||
| 341 | case OpCode::Id::FFMA_RR: { | ||
| 342 | op_b += GetRegister(instr.gpr20); | ||
| 343 | op_c += GetRegister(instr.gpr39); | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | case OpCode::Id::FFMA_RC: { | ||
| 347 | op_b += GetRegister(instr.gpr39); | ||
| 348 | op_c += GetUniform(instr.uniform); | ||
| 349 | break; | ||
| 350 | } | ||
| 351 | case OpCode::Id::FFMA_IMM: { | ||
| 352 | op_b += GetImmediate(instr); | ||
| 353 | op_c += GetRegister(instr.gpr39); | ||
| 329 | break; | 354 | break; |
| 330 | } | 355 | } |
| 331 | default: { | 356 | default: { |
| @@ -336,6 +361,8 @@ private: | |||
| 336 | break; | 361 | break; |
| 337 | } | 362 | } |
| 338 | } | 363 | } |
| 364 | |||
| 365 | SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1); | ||
| 339 | break; | 366 | break; |
| 340 | } | 367 | } |
| 341 | case OpCode::Type::Memory: { | 368 | case OpCode::Type::Memory: { |