diff options
| author | 2018-04-15 20:45:56 -0400 | |
|---|---|---|
| committer | 2018-04-17 16:36:42 -0400 | |
| commit | 5a28dce9eb8db4571cc47352174c78f2c3cfd606 (patch) | |
| tree | f879ecc81cb6737df1e2e0adea45acf53cba1e1e /src/video_core/renderer_opengl | |
| parent | gl_shader_decompiler: Allow vertex position to be used in fragment shader. (diff) | |
| download | yuzu-5a28dce9eb8db4571cc47352174c78f2c3cfd606.tar.gz yuzu-5a28dce9eb8db4571cc47352174c78f2c3cfd606.tar.xz yuzu-5a28dce9eb8db4571cc47352174c78f2c3cfd606.zip | |
gl_shader_decompiler: Implement FMUL/FADD/FFMA immediate instructions.
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 51 |
1 files changed, 39 insertions, 12 deletions
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: { |