diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-23 01:18:33 -0300 | 
|---|---|---|
| committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 17:54:52 -0300 | 
| commit | 55e6786254d33e3501002bf7fbdd52552a0df32a (patch) | |
| tree | c4d516419aff5dfa35c1de13efa77294afc50e16 /src/video_core/shader | |
| parent | ec98e4d842d5ba04b329c866f5c9b1e7314069f2 (diff) | |
shader_decode: Implement TLDS (untested)
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 69 | ||||
| -rw-r--r-- | src/video_core/shader/glsl_decompiler.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 4 | 
3 files changed, 92 insertions, 10 deletions
| diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index cfdb92807..ce3445512 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -204,7 +204,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, u32 pc) {          break;      }      case OpCode::Id::TEXS: { -        Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; +        const TextureType texture_type{instr.texs.GetTextureType()};          const bool is_array{instr.texs.IsArrayTexture()};          const bool depth_compare = instr.texs.UsesMiscMode(TextureMiscMode::DC);          const auto process_mode = instr.texs.GetTextureProcessMode(); @@ -373,6 +373,22 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, u32 pc) {                                 GetRegister(RZ), GetRegister(RZ)));          break;      } +    case OpCode::Id::TLDS: { +        const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; +        const bool is_array{instr.tlds.IsArrayTexture()}; + +        UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), +                             "AOFFI is not implemented"); +        UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented"); + +        if (instr.tlds.UsesMiscMode(TextureMiscMode::NODEP)) { +            LOG_WARNING(HW_GPU, "TMML.NODEP implementation is incomplete"); +        } + +        const Node texture = GetTldsCode(instr, texture_type, is_array); +        WriteTexsInstructionFloat(bb, instr, texture); +        break; +    }      default:          UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName());      } @@ -576,22 +592,59 @@ Node ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool dep      for (size_t i = 0; i < coord_count; ++i) {          params.push_back(GetRegister(coord_register + i));      } -    std::size_t array_offset{}; +    std::optional<u32> array_offset;      if (is_array) { -        array_offset = params.size(); +        array_offset = static_cast<u32>(params.size());          params.push_back(GetRegister(array_register));      }      const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare); - -    std::optional<u32> array_offset_value; -    if (is_array) -        array_offset_value = static_cast<u32>(array_offset); -    MetaTexture meta{sampler, static_cast<u32>(params.size()), array_offset_value}; +    MetaTexture meta{sampler, static_cast<u32>(params.size()), array_offset};      return Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params));  } +Node ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { +    const std::size_t type_coord_count = GetCoordCount(texture_type); +    const std::size_t total_coord_count = type_coord_count + (is_array ? 1 : 0); +    const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; + +    // If enabled arrays index is always stored in the gpr8 field +    const u64 array_register = instr.gpr8.Value(); +    // if is array gpr20 is used +    const u64 coord_register = is_array ? instr.gpr20.Value() : instr.gpr8.Value(); + +    const u64 last_coord_register = +        ((type_coord_count > 2) || (type_coord_count == 2 && !lod_enabled)) && !is_array +            ? static_cast<u64>(instr.gpr20.Value()) +            : coord_register + 1; + +    std::vector<Node> params; + +    for (std::size_t i = 0; i < type_coord_count; ++i) { +        const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1); +        params.push_back(GetRegister(last ? last_coord_register : coord_register + i)); +    } +    std::optional<u32> array_offset; +    if (is_array) { +        array_offset = static_cast<u32>(params.size()); +        params.push_back(GetRegister(array_register)); +    } +    const auto coords_count = static_cast<u32>(params.size()); + +    if (lod_enabled) { +        // When lod is used always is in grp20 +        params.push_back(GetRegister(instr.gpr20)); +    } else { +        params.push_back(Immediate(0)); +    } + +    const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, false); +    MetaTexture meta{sampler, coords_count, array_offset}; + +    return Operation(OperationCode::F4TexelFetch, std::move(meta), std::move(params)); +} +  std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement(      TextureType texture_type, bool depth_compare, bool is_array, bool lod_bias_enabled,      std::size_t max_coords, std::size_t max_inputs) { diff --git a/src/video_core/shader/glsl_decompiler.cpp b/src/video_core/shader/glsl_decompiler.cpp index a513c0c4b..b93ea9ec6 100644 --- a/src/video_core/shader/glsl_decompiler.cpp +++ b/src/video_core/shader/glsl_decompiler.cpp @@ -635,8 +635,6 @@ private:                                                           result_type));      } -#pragma optimize("", off) -      std::string GenerateTexture(Operation operation, const std::string& func,                                  std::string extra_cast(std::string) = nullptr) {          constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; @@ -1100,6 +1098,32 @@ private:          return "vec4(itof(int(" + tmp + ".y)), utof(uint(" + tmp + ".x)), 0, 0)";      } +    std::string F4TexelFetch(Operation operation) { +        constexpr std::array<const char*, 4> constructors = {"int", "ivec2", "ivec3", "ivec4"}; +        const auto& meta = std::get<MetaTexture>(operation.GetMeta()); +        const auto count = static_cast<u32>(operation.GetOperandsCount()); + +        std::string expr = "texelFetch("; +        expr += GetSampler(meta.sampler); +        expr += ", "; + +        expr += constructors[meta.coords_count - 1]; +        expr += '('; +        for (u32 i = 0; i < count; ++i) { +            expr += VisitOperand(operation, i, Type::Int); +            expr += ", "; + +            if (i + 1 == meta.coords_count) { +                expr += ')'; +            } +            if (i + 1 < count) { +                expr += ", "; +            } +        } +        expr += ')'; +        return expr; +    } +      std::string Ipa(Operation operation) {          const auto& attribute = operation[0];          // TODO(Rodrigo): Special IPA attribute interactions @@ -1314,6 +1338,7 @@ private:          &F4TextureGather,          &F4TextureQueryDimensions,          &F4TextureQueryLod, +        &F4TexelFetch,          &Ipa, diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 691bd6d72..231f58f6a 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -154,6 +154,7 @@ enum class OperationCode {      F4TextureGather,          /// (MetaTexture, float[N] coords, float[M] params) -> float4      F4TextureQueryDimensions, /// (MetaTexture, float a) -> float4      F4TextureQueryLod,        /// (MetaTexture, float[N] coords) -> float4 +    F4TexelFetch,             /// (MetaTexture, int[N], int) -> float4      Ipa, /// (abuf src) -> float @@ -694,6 +695,9 @@ private:      Node GetTld4Code(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type,                       bool depth_compare, bool is_array); +    Node GetTldsCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, +                     bool is_array); +      std::tuple<std::size_t, std::size_t> ValidateAndGetCoordinateElement(          Tegra::Shader::TextureType texture_type, bool depth_compare, bool is_array,          bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs); | 
