diff options
| author | 2018-08-19 12:55:50 -0500 | |
|---|---|---|
| committer | 2018-08-19 12:57:58 -0500 | |
| commit | 7fb406c3fca2f7c8266a5cc1988aa8d741921310 (patch) | |
| tree | 39e3f35542360e99d58ee81662a3c01a1424e8e6 /src | |
| parent | Shader: Use the right sampler type in the TEX, TEXS and TLDS instructions. (diff) | |
| download | yuzu-7fb406c3fca2f7c8266a5cc1988aa8d741921310.tar.gz yuzu-7fb406c3fca2f7c8266a5cc1988aa8d741921310.tar.xz yuzu-7fb406c3fca2f7c8266a5cc1988aa8d741921310.zip | |
Shader: Implemented the TLD4 and TLD4S opcodes using GLSL's textureGather.
It is unknown how TLD4S determines the sampler type, more research is needed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6562be102..f466b9427 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1567,6 +1567,57 @@ private: | |||
| 1567 | WriteTexsInstruction(instr, coord, texture); | 1567 | WriteTexsInstruction(instr, coord, texture); |
| 1568 | break; | 1568 | break; |
| 1569 | } | 1569 | } |
| 1570 | case OpCode::Id::TLD4: { | ||
| 1571 | ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); | ||
| 1572 | ASSERT(instr.tld4.array == 0); | ||
| 1573 | std::string coord{}; | ||
| 1574 | |||
| 1575 | switch (instr.tld4.texture_type) { | ||
| 1576 | case Tegra::Shader::TextureType::Texture2D: { | ||
| 1577 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 1578 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 1579 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 1580 | break; | ||
| 1581 | } | ||
| 1582 | default: | ||
| 1583 | UNIMPLEMENTED(); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | const std::string sampler = | ||
| 1587 | GetSampler(instr.sampler, instr.tld4.texture_type, instr.tld4.array); | ||
| 1588 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1589 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1590 | shader.AddLine("{"); | ||
| 1591 | ++shader.scope; | ||
| 1592 | shader.AddLine(coord); | ||
| 1593 | const std::string texture = "textureGather(" + sampler + ", coords, " + | ||
| 1594 | std::to_string(instr.tld4.component) + ')'; | ||
| 1595 | |||
| 1596 | size_t dest_elem{}; | ||
| 1597 | for (size_t elem = 0; elem < 4; ++elem) { | ||
| 1598 | if (!instr.tex.IsComponentEnabled(elem)) { | ||
| 1599 | // Skip disabled components | ||
| 1600 | continue; | ||
| 1601 | } | ||
| 1602 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); | ||
| 1603 | ++dest_elem; | ||
| 1604 | } | ||
| 1605 | --shader.scope; | ||
| 1606 | shader.AddLine("}"); | ||
| 1607 | break; | ||
| 1608 | } | ||
| 1609 | case OpCode::Id::TLD4S: { | ||
| 1610 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 1611 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 1612 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. | ||
| 1613 | const std::string sampler = | ||
| 1614 | GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false); | ||
| 1615 | const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | ||
| 1616 | const std::string texture = "textureGather(" + sampler + ", coords, " + | ||
| 1617 | std::to_string(instr.tld4s.component) + ')'; | ||
| 1618 | WriteTexsInstruction(instr, coord, texture); | ||
| 1619 | break; | ||
| 1620 | } | ||
| 1570 | default: { | 1621 | default: { |
| 1571 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); | 1622 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); |
| 1572 | UNREACHABLE(); | 1623 | UNREACHABLE(); |