summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-08-19 12:55:50 -0500
committerGravatar Subv2018-08-19 12:57:58 -0500
commit7fb406c3fca2f7c8266a5cc1988aa8d741921310 (patch)
tree39e3f35542360e99d58ee81662a3c01a1424e8e6 /src
parentShader: Use the right sampler type in the TEX, TEXS and TLDS instructions. (diff)
downloadyuzu-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.cpp51
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();