diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 56 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 4 | 
4 files changed, 65 insertions, 40 deletions
| diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d14cd5f20..f62ae8801 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -325,11 +325,11 @@ enum class TextureQueryType : u64 {  enum class TextureProcessMode : u64 {      None = 0, -    LZ = 1,  // Unknown, appears to be the same as none. +    LZ = 1,  // Load LOD of zero.      LB = 2,  // Load Bias. -    LL = 3,  // Load LOD (LevelOfDetail) -    LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB -    LLA = 7  // Load LOD. The A is unknown, does not appear to differ with LL +    LL = 3,  // Load LOD. +    LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB. +    LLA = 7  // Load LOD. The A is unknown, does not appear to differ with LL.  };  enum class TextureMiscMode : u64 { diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 72ff6ac6a..11d1169f0 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -5,7 +5,9 @@  #include <array>  #include <string>  #include <string_view> +#include <utility>  #include <variant> +#include <vector>  #include <fmt/format.h> @@ -717,7 +719,7 @@ private:      }      std::string GenerateTexture(Operation operation, const std::string& func, -                                bool is_extra_int = false) { +                                const std::vector<std::pair<Type, Node>>& extras) {          constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"};          const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); @@ -738,36 +740,47 @@ private:              expr += Visit(operation[i]);              const std::size_t next = i + 1; -            if (next < count || has_array || has_shadow) +            if (next < count)                  expr += ", ";          }          if (has_array) { -            expr += "float(ftoi(" + Visit(meta->array) + "))"; +            expr += ", float(ftoi(" + Visit(meta->array) + "))";          }          if (has_shadow) { -            if (has_array) -                expr += ", "; -            expr += Visit(meta->depth_compare); +            expr += ", " + Visit(meta->depth_compare);          }          expr += ')'; -        for (const Node extra : meta->extras) { +        for (const auto& extra_pair : extras) { +            const auto [type, operand] = extra_pair; +            if (operand == nullptr) { +                continue; +            }              expr += ", "; -            if (is_extra_int) { -                if (const auto immediate = std::get_if<ImmediateNode>(extra)) { + +            switch (type) { +            case Type::Int: +                if (const auto immediate = std::get_if<ImmediateNode>(operand)) {                      // Inline the string as an immediate integer in GLSL (some extra arguments are                      // required to be constant)                      expr += std::to_string(static_cast<s32>(immediate->GetValue()));                  } else { -                    expr += "ftoi(" + Visit(extra) + ')'; +                    expr += "ftoi(" + Visit(operand) + ')';                  } -            } else { -                expr += Visit(extra); +                break; +            case Type::Float: +                expr += Visit(operand); +                break; +            default: { +                const auto type_int = static_cast<u32>(type); +                UNIMPLEMENTED_MSG("Unimplemented extra type={}", type_int); +                expr += '0'; +                break; +            }              }          } -        expr += ')'; -        return expr; +        return expr + ')';      }      std::string Assign(Operation operation) { @@ -1146,7 +1159,7 @@ private:          const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());          ASSERT(meta); -        std::string expr = GenerateTexture(operation, "texture"); +        std::string expr = GenerateTexture(operation, "texture", {{Type::Float, meta->bias}});          if (meta->sampler.IsShadow()) {              expr = "vec4(" + expr + ')';          } @@ -1157,7 +1170,7 @@ private:          const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());          ASSERT(meta); -        std::string expr = GenerateTexture(operation, "textureLod"); +        std::string expr = GenerateTexture(operation, "textureLod", {{Type::Float, meta->lod}});          if (meta->sampler.IsShadow()) {              expr = "vec4(" + expr + ')';          } @@ -1168,7 +1181,8 @@ private:          const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());          ASSERT(meta); -        return GenerateTexture(operation, "textureGather", !meta->sampler.IsShadow()) + +        const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int; +        return GenerateTexture(operation, "textureGather", {{type, meta->component}}) +                 GetSwizzle(meta->element);      } @@ -1197,8 +1211,8 @@ private:          ASSERT(meta);          if (meta->element < 2) { -            return "itof(int((" + GenerateTexture(operation, "textureQueryLod") + " * vec2(256))" + -                   GetSwizzle(meta->element) + "))"; +            return "itof(int((" + GenerateTexture(operation, "textureQueryLod", {}) + +                   " * vec2(256))" + GetSwizzle(meta->element) + "))";          }          return "0";      } @@ -1224,9 +1238,9 @@ private:              else if (next < count)                  expr += ", ";          } -        for (std::size_t i = 0; i < meta->extras.size(); ++i) { +        if (meta->lod) {              expr += ", "; -            expr += CastOperand(Visit(meta->extras.at(i)), Type::Int); +            expr += CastOperand(Visit(meta->lod), Type::Int);          }          expr += ')'; diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 50e2d0584..a99ae19bf 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -119,8 +119,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {              coords.push_back(op_a);              coords.push_back(op_b);          } -        std::vector<Node> extras; -        extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component))); +        const Node component = Immediate(static_cast<u32>(instr.tld4s.component));          const auto& sampler =              GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare); @@ -128,7 +127,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {          Node4 values;          for (u32 element = 0; element < values.size(); ++element) {              auto coords_copy = coords; -            MetaTexture meta{sampler, {}, {}, extras, element}; +            MetaTexture meta{sampler, {}, {}, {}, {}, component, element};              values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));          } @@ -153,7 +152,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {                  if (!instr.txq.IsComponentEnabled(element)) {                      continue;                  } -                MetaTexture meta{sampler, {}, {}, {}, element}; +                MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};                  const Node value =                      Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8));                  SetTemporal(bb, indexer++, value); @@ -203,7 +202,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {          for (u32 element = 0; element < 2; ++element) {              auto params = coords; -            MetaTexture meta{sampler, {}, {}, {}, element}; +            MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};              const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));              SetTemporal(bb, element, value);          } @@ -347,25 +346,35 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,            (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));      const OperationCode read_method = -        lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture; +        (lod_needed && gl_lod_supported) ? OperationCode::TextureLod : OperationCode::Texture;      UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); -    std::vector<Node> extras; +    Node bias = {}; +    Node lod = {};      if (process_mode != TextureProcessMode::None && gl_lod_supported) { -        if (process_mode == TextureProcessMode::LZ) { -            extras.push_back(Immediate(0.0f)); -        } else { +        switch (process_mode) { +        case TextureProcessMode::LZ: +            lod = Immediate(0.0f); +            break; +        case TextureProcessMode::LB:              // If present, lod or bias are always stored in the register indexed by the gpr20              // field with an offset depending on the usage of the other registers -            extras.push_back(GetRegister(instr.gpr20.Value() + bias_offset)); +            bias = GetRegister(instr.gpr20.Value() + bias_offset); +            break; +        case TextureProcessMode::LL: +            lod = GetRegister(instr.gpr20.Value() + bias_offset); +            break; +        default: +            UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode)); +            break;          }      }      Node4 values;      for (u32 element = 0; element < values.size(); ++element) {          auto copy_coords = coords; -        MetaTexture meta{sampler, array, depth_compare, extras, element}; +        MetaTexture meta{sampler, array, depth_compare, bias, lod, {}, element};          values[element] = Operation(read_method, meta, std::move(copy_coords));      } @@ -462,7 +471,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de      Node4 values;      for (u32 element = 0; element < values.size(); ++element) {          auto coords_copy = coords; -        MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element}; +        MetaTexture meta{sampler, GetRegister(array_register), {}, {}, {}, {}, element};          values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));      } @@ -498,7 +507,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is      Node4 values;      for (u32 element = 0; element < values.size(); ++element) {          auto coords_copy = coords; -        MetaTexture meta{sampler, array, {}, {lod}, element}; +        MetaTexture meta{sampler, array, {}, {}, lod, {}, element};          values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));      }      return values; diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 0548c46f0..5bc3a3900 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -290,7 +290,9 @@ struct MetaTexture {      const Sampler& sampler;      Node array{};      Node depth_compare{}; -    std::vector<Node> extras; +    Node bias{}; +    Node lod{}; +    Node component{};      u32 element{};  }; | 
