diff options
Diffstat (limited to 'src/video_core')
| -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:          }      } +    std::string WriteTexsInstruction(const Instruction& instr, const std::string& coord, +                                     const std::string& texture) { +        // Add an extra scope and declare the texture coords inside to prevent +        // overwriting them in case they are used as outputs of the texs instruction. +        shader.AddLine('{'); +        ++shader.scope; +        shader.AddLine(coord); + +        // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA +        // goes into gpr28+0 and gpr28+1 +        size_t texs_offset{}; + +        for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { +            for (unsigned elem = 0; elem < 2; ++elem) { +                if (!instr.texs.IsComponentEnabled(elem)) { +                    // Skip disabled components +                    continue; +                } +                regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); +            } + +            if (!instr.texs.HasTwoDestinations()) { +                // Skip the second destination +                break; +            } + +            texs_offset += 2; +        } +        --shader.scope; +        shader.AddLine('}'); +    } +      /**       * Compiles a single instruction from Tegra to GLSL.       * @param offset the offset of the Tegra shader instruction. @@ -1348,36 +1380,18 @@ private:                  const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);                  const std::string sampler = GetSampler(instr.sampler);                  const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; -                // Add an extra scope and declare the texture coords inside to prevent -                // overwriting them in case they are used as outputs of the texs instruction. -                shader.AddLine("{"); -                ++shader.scope; -                shader.AddLine(coord); -                const std::string texture = "texture(" + sampler + ", coords)"; - -                // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA -                // goes into gpr28+0 and gpr28+1 -                size_t texs_offset{}; - -                for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { -                    for (unsigned elem = 0; elem < 2; ++elem) { -                        if (!instr.texs.IsComponentEnabled(elem)) { -                            // Skip disabled components -                            continue; -                        } -                        regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, -                                                elem); -                    } - -                    if (!instr.texs.HasTwoDestinations()) { -                        // Skip the second destination -                        break; -                    } -                    texs_offset += 2; -                } -                --shader.scope; -                shader.AddLine("}"); +                const std::string texture = "texture(" + sampler + ", coords)"; +                WriteTexsInstruction(instr, coord, texture); +                break; +            } +            case OpCode::Id::TLDS: { +                const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); +                const std::string op_b = regs.GetRegisterAsInteger(instr.gpr20); +                const std::string sampler = GetSampler(instr.sampler); +                const std::string coord = "ivec2 coords = ivec2(" + op_a + ", " + op_b + ");"; +                const std::string texture = "texelFetch(" + sampler + ", coords, 0)"; +                WriteTexsInstruction(instr, coord, texture);                  break;              }              default: {  | 
