diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 73 | 
1 files changed, 65 insertions, 8 deletions
| diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 3f23ba749..6c5c6500a 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -836,24 +836,81 @@ private:                     : Emit(OpCompositeConstruct(t_float_lut.at(coords.size() - 1), coords));      } +    Id GetTextureElement(Operation operation, Id sample_value) { +        const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); +        ASSERT(meta); +        return Emit(OpCompositeExtract(t_float, sample_value, meta->element)); +    } +      Id Texture(Operation operation) { -        UNIMPLEMENTED(); -        return {}; +        const Id texture = Emit(OpImageSampleImplicitLod(t_float4, GetTextureSampler(operation), +                                                         GetTextureCoordinates(operation))); +        return GetTextureElement(operation, texture);      }      Id TextureLod(Operation operation) { -        UNIMPLEMENTED(); -        return {}; +        const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); +        const Id texture = Emit(OpImageSampleExplicitLod( +            t_float4, GetTextureSampler(operation), GetTextureCoordinates(operation), +            spv::ImageOperandsMask::Lod, Visit(meta->lod))); +        return GetTextureElement(operation, texture);      }      Id TextureGather(Operation operation) { -        UNIMPLEMENTED(); -        return {}; +        const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); +        const auto coords = GetTextureCoordinates(operation); + +        Id texture; +        if (meta->sampler.IsShadow()) { +            texture = Emit(OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, +                                             Visit(meta->component))); +        } else { +            u32 component_value = 0; +            if (meta->component) { +                const auto component = std::get_if<ImmediateNode>(meta->component); +                ASSERT_MSG(component, "Component is not an immediate value"); +                component_value = component->GetValue(); +            } +            texture = Emit(OpImageGather(t_float4, GetTextureSampler(operation), coords, +                                         Constant(t_uint, component_value))); +        } + +        return GetTextureElement(operation, texture);      }      Id TextureQueryDimensions(Operation operation) { -        UNIMPLEMENTED(); -        return {}; +        const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); +        const auto image_id = GetTextureImage(operation); +        AddCapability(spv::Capability::ImageQuery); + +        if (meta->element == 3) { +            return BitcastTo<Type::Float>(Emit(OpImageQueryLevels(t_int, image_id))); +        } + +        const Id lod = VisitOperand<Type::Uint>(operation, 0); +        const std::size_t coords_count = [&]() { +            switch (const auto type = meta->sampler.GetType(); type) { +            case Tegra::Shader::TextureType::Texture1D: +                return 1; +            case Tegra::Shader::TextureType::Texture2D: +            case Tegra::Shader::TextureType::TextureCube: +                return 2; +            case Tegra::Shader::TextureType::Texture3D: +                return 3; +            default: +                UNREACHABLE_MSG("Invalid texture type={}", static_cast<u32>(type)); +                return 2; +            } +        }(); + +        if (meta->element >= coords_count) { +            return Constant(t_float, 0.0f); +        } + +        const std::array<Id, 3> types = {t_int, t_int2, t_int3}; +        const Id sizes = Emit(OpImageQuerySizeLod(types.at(coords_count - 1), image_id, lod)); +        const Id size = Emit(OpCompositeExtract(t_int, sizes, meta->element)); +        return BitcastTo<Type::Float>(size);      }      Id TextureQueryLod(Operation operation) { | 
