diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index d9a8b7ca..58b286e9 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -364,6 +364,16 @@ enum class Filter : u64 { AnisoLinear = 3, }; +constexpr bool IsAnisoFilter(const Filter filter) { + switch (filter) { + case Filter::AnisoPoint: + case Filter::AnisoLinear: + return true; + default: + return false; + } +} + enum class MipFilter : u64 { None = 0, Point = 1, @@ -435,6 +445,23 @@ struct Sampler { float MaxLod() const noexcept { return static_cast(max_lod.Value()) / 256.0f; } + + float MaxAniso() const { + switch (max_aniso) { + case AnisoRatio::One: + return 1.0f; + case AnisoRatio::Two: + return 2.0f; + case AnisoRatio::Four: + return 4.0f; + case AnisoRatio::Eight: + return 8.0f; + case AnisoRatio::Sixteen: + return 16.0f; + default: + UNREACHABLE(); + } + } }; } // namespace AmdGpu diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 54a9b987..62838140 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -249,6 +249,11 @@ public: return properties.limits.maxSamplerLodBias; } + /// Returns the maximum sampler anisotropy. + float MaxSamplerAnisotropy() const { + return properties.limits.maxSamplerAnisotropy; + } + /// Returns the maximum number of push descriptors. u32 MaxPushDescriptors() const { return push_descriptor_props.maxPushDescriptors; diff --git a/src/video_core/texture_cache/sampler.cpp b/src/video_core/texture_cache/sampler.cpp index 9f4bc7a7..5ce10ff0 100644 --- a/src/video_core/texture_cache/sampler.cpp +++ b/src/video_core/texture_cache/sampler.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include "video_core/amdgpu/resource.h" #include "video_core/renderer_vulkan/liverpool_to_vk.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/texture_cache/sampler.h" @@ -12,6 +14,11 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample LOG_WARNING(Render_Vulkan, "Texture requires gamma correction"); } using namespace Vulkan; + const bool anisotropyEnable = instance.IsAnisotropicFilteringSupported() && + (AmdGpu::IsAnisoFilter(sampler.xy_mag_filter) || + AmdGpu::IsAnisoFilter(sampler.xy_min_filter)); + const float maxAnisotropy = + std::clamp(sampler.MaxAniso(), 1.0f, instance.MaxSamplerAnisotropy()); const vk::SamplerCreateInfo sampler_ci = { .magFilter = LiverpoolToVK::Filter(sampler.xy_mag_filter), .minFilter = LiverpoolToVK::Filter(sampler.xy_min_filter), @@ -20,6 +27,8 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample .addressModeV = LiverpoolToVK::ClampMode(sampler.clamp_y), .addressModeW = LiverpoolToVK::ClampMode(sampler.clamp_z), .mipLodBias = std::min(sampler.LodBias(), instance.MaxSamplerLodBias()), + .anisotropyEnable = anisotropyEnable, + .maxAnisotropy = maxAnisotropy, .compareEnable = sampler.depth_compare_func != AmdGpu::DepthCompare::Never, .compareOp = LiverpoolToVK::DepthCompare(sampler.depth_compare_func), .minLod = sampler.MinLod(),