diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 11 | 
3 files changed, 34 insertions, 9 deletions
| diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 40e2e0d38..dd6996735 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -1845,13 +1845,21 @@ private:      Expression TextureGather(Operation operation) {          const auto& meta = std::get<MetaTexture>(operation.GetMeta()); -        UNIMPLEMENTED_IF(!meta.aoffi.empty());          const Id coords = GetCoordinates(operation, Type::Float); + +        spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone; +        std::vector<Id> operands{};          Id texture{}; + +        if (!meta.aoffi.empty()) { +            mask = mask | spv::ImageOperandsMask::Offset; +            operands.push_back(GetOffsetCoordinates(operation)); +        } +          if (meta.sampler.is_shadow) {              texture = OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, -                                        AsFloat(Visit(meta.depth_compare))); +                                        AsFloat(Visit(meta.depth_compare)), mask, operands);          } else {              u32 component_value = 0;              if (meta.component) { @@ -1860,7 +1868,7 @@ private:                  component_value = component->GetValue();              }              texture = OpImageGather(t_float4, GetTextureSampler(operation), coords, -                                    Constant(t_uint, component_value)); +                                    Constant(t_uint, component_value), mask, operands);          }          return GetTextureElement(operation, texture, Type::Float);      } @@ -1928,13 +1936,22 @@ private:          const Id image = GetTextureImage(operation);          const Id coords = GetCoordinates(operation, Type::Int); + +        spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone; +        std::vector<Id> operands{};          Id fetch; +          if (meta.lod && !meta.sampler.is_buffer) { -            fetch = OpImageFetch(t_float4, image, coords, spv::ImageOperandsMask::Lod, -                                 AsInt(Visit(meta.lod))); -        } else { -            fetch = OpImageFetch(t_float4, image, coords); +            mask = mask | spv::ImageOperandsMask::Lod; +            operands.push_back(AsInt(Visit(meta.lod)));          } + +        if (!meta.aoffi.empty()) { +            mask = mask | spv::ImageOperandsMask::Offset; +            operands.push_back(GetOffsetCoordinates(operation)); +        } + +        fetch = OpImageFetch(t_float4, image, coords, mask, operands);          return GetTextureElement(operation, fetch, Type::Float);      } diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 50f4e7d35..7728f600e 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -330,6 +330,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {          case StoreType::Bits32:              (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));              break; +        case StoreType::Unsigned16:          case StoreType::Signed16: {              Node address = GetAddress(0);              Node memory = (this->*get_memory)(address); diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 833fa2a39..43087304d 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -806,6 +806,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is      const std::size_t type_coord_count = GetCoordCount(texture_type);      const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; +    const bool aoffi_enabled = instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI);      // If enabled arrays index is always stored in the gpr8 field      const u64 array_register = instr.gpr8.Value(); @@ -820,17 +821,23 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is      std::vector<Node> coords;      for (std::size_t i = 0; i < type_coord_count; ++i) {          const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1); -        coords.push_back(GetRegister(last ? last_coord_register : coord_register + i)); +        coords.push_back( +            GetRegister(last && !aoffi_enabled ? last_coord_register : coord_register + i));      }      const Node array = is_array ? GetRegister(array_register) : nullptr;      // When lod is used always is in gpr20      const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); +    std::vector<Node> aoffi{}; +    if (aoffi_enabled) { +        aoffi = GetAoffiCoordinates(GetRegister(instr.gpr20), type_coord_count, false); +    } +      Node4 values;      for (u32 element = 0; element < values.size(); ++element) {          auto coords_copy = coords; -        MetaTexture meta{*sampler, array, {}, {}, {}, {}, {}, lod, {}, element, {}}; +        MetaTexture meta{*sampler, array, {}, aoffi, {}, {}, {}, lod, {}, element, {}};          values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));      }      return values; | 
