diff options
| author | 2018-07-23 19:14:01 -0700 | |
|---|---|---|
| committer | 2018-07-23 19:14:01 -0700 | |
| commit | f6657bc8d78c19d41cf64e6c0086f862b4b9a515 (patch) | |
| tree | 3e9086c247781a70756d476503bda59425769769 /src | |
| parent | Merge pull request #786 from lioncash/exclusive (diff) | |
| parent | gl_shader_decompiler: Implement shader instruction TLDS. (diff) | |
| download | yuzu-f6657bc8d78c19d41cf64e6c0086f862b4b9a515.tar.gz yuzu-f6657bc8d78c19d41cf64e6c0086f862b4b9a515.tar.xz yuzu-f6657bc8d78c19d41cf64e6c0086f862b4b9a515.zip | |
Merge pull request #787 from bunnei/tlds
gl_shader_decompiler: Implement shader instruction TLDS.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e771411ef..4e36b6de8 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -750,6 +750,38 @@ private: | |||
| 750 | } | 750 | } |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | std::string WriteTexsInstruction(const Instruction& instr, const std::string& coord, | ||
| 754 | const std::string& texture) { | ||
| 755 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 756 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 757 | shader.AddLine('{'); | ||
| 758 | ++shader.scope; | ||
| 759 | shader.AddLine(coord); | ||
| 760 | |||
| 761 | // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA | ||
| 762 | // goes into gpr28+0 and gpr28+1 | ||
| 763 | size_t texs_offset{}; | ||
| 764 | |||
| 765 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { | ||
| 766 | for (unsigned elem = 0; elem < 2; ++elem) { | ||
| 767 | if (!instr.texs.IsComponentEnabled(elem)) { | ||
| 768 | // Skip disabled components | ||
| 769 | continue; | ||
| 770 | } | ||
| 771 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); | ||
| 772 | } | ||
| 773 | |||
| 774 | if (!instr.texs.HasTwoDestinations()) { | ||
| 775 | // Skip the second destination | ||
| 776 | break; | ||
| 777 | } | ||
| 778 | |||
| 779 | texs_offset += 2; | ||
| 780 | } | ||
| 781 | --shader.scope; | ||
| 782 | shader.AddLine('}'); | ||
| 783 | } | ||
| 784 | |||
| 753 | /** | 785 | /** |
| 754 | * Compiles a single instruction from Tegra to GLSL. | 786 | * Compiles a single instruction from Tegra to GLSL. |
| 755 | * @param offset the offset of the Tegra shader instruction. | 787 | * @param offset the offset of the Tegra shader instruction. |
| @@ -1348,36 +1380,18 @@ private: | |||
| 1348 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); | 1380 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); |
| 1349 | const std::string sampler = GetSampler(instr.sampler); | 1381 | const std::string sampler = GetSampler(instr.sampler); |
| 1350 | const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | 1382 | const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; |
| 1351 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1352 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1353 | shader.AddLine("{"); | ||
| 1354 | ++shader.scope; | ||
| 1355 | shader.AddLine(coord); | ||
| 1356 | const std::string texture = "texture(" + sampler + ", coords)"; | ||
| 1357 | |||
| 1358 | // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA | ||
| 1359 | // goes into gpr28+0 and gpr28+1 | ||
| 1360 | size_t texs_offset{}; | ||
| 1361 | |||
| 1362 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { | ||
| 1363 | for (unsigned elem = 0; elem < 2; ++elem) { | ||
| 1364 | if (!instr.texs.IsComponentEnabled(elem)) { | ||
| 1365 | // Skip disabled components | ||
| 1366 | continue; | ||
| 1367 | } | ||
| 1368 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, | ||
| 1369 | elem); | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | if (!instr.texs.HasTwoDestinations()) { | ||
| 1373 | // Skip the second destination | ||
| 1374 | break; | ||
| 1375 | } | ||
| 1376 | 1383 | ||
| 1377 | texs_offset += 2; | 1384 | const std::string texture = "texture(" + sampler + ", coords)"; |
| 1378 | } | 1385 | WriteTexsInstruction(instr, coord, texture); |
| 1379 | --shader.scope; | 1386 | break; |
| 1380 | shader.AddLine("}"); | 1387 | } |
| 1388 | case OpCode::Id::TLDS: { | ||
| 1389 | const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1390 | const std::string op_b = regs.GetRegisterAsInteger(instr.gpr20); | ||
| 1391 | const std::string sampler = GetSampler(instr.sampler); | ||
| 1392 | const std::string coord = "ivec2 coords = ivec2(" + op_a + ", " + op_b + ");"; | ||
| 1393 | const std::string texture = "texelFetch(" + sampler + ", coords, 0)"; | ||
| 1394 | WriteTexsInstruction(instr, coord, texture); | ||
| 1381 | break; | 1395 | break; |
| 1382 | } | 1396 | } |
| 1383 | default: { | 1397 | default: { |