diff options
| author | 2023-06-15 18:19:32 +0200 | |
|---|---|---|
| committer | 2023-06-15 18:19:32 +0200 | |
| commit | 42c944b250d8d5c8147b24b3a453cba29968d46c (patch) | |
| tree | 6d156e8247219bf373edd848bd3a89bbd32eb546 /src/video_core/renderer_vulkan | |
| parent | video_core: Apply AF only to samplers with normal LOD range [0, 1+x] (diff) | |
| download | yuzu-42c944b250d8d5c8147b24b3a453cba29968d46c.tar.gz yuzu-42c944b250d8d5c8147b24b3a453cba29968d46c.tar.xz yuzu-42c944b250d8d5c8147b24b3a453cba29968d46c.zip | |
video_core: Add per-image anisotropy heuristics (format & mip count)
Diffstat (limited to 'src/video_core/renderer_vulkan')
5 files changed, 50 insertions, 30 deletions
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 983e1c2e1..1632a6f26 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -178,7 +178,7 @@ public: | |||
| 178 | inline void PushImageDescriptors(TextureCache& texture_cache, | 178 | inline void PushImageDescriptors(TextureCache& texture_cache, |
| 179 | GuestDescriptorQueue& guest_descriptor_queue, | 179 | GuestDescriptorQueue& guest_descriptor_queue, |
| 180 | const Shader::Info& info, RescalingPushConstant& rescaling, | 180 | const Shader::Info& info, RescalingPushConstant& rescaling, |
| 181 | const VkSampler*& samplers, | 181 | const Sampler**& samplers, |
| 182 | const VideoCommon::ImageViewInOut*& views) { | 182 | const VideoCommon::ImageViewInOut*& views) { |
| 183 | const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors); | 183 | const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors); |
| 184 | const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors); | 184 | const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors); |
| @@ -187,10 +187,14 @@ inline void PushImageDescriptors(TextureCache& texture_cache, | |||
| 187 | for (const auto& desc : info.texture_descriptors) { | 187 | for (const auto& desc : info.texture_descriptors) { |
| 188 | for (u32 index = 0; index < desc.count; ++index) { | 188 | for (u32 index = 0; index < desc.count; ++index) { |
| 189 | const VideoCommon::ImageViewId image_view_id{(views++)->id}; | 189 | const VideoCommon::ImageViewId image_view_id{(views++)->id}; |
| 190 | const VkSampler sampler{*(samplers++)}; | ||
| 191 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; | 190 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; |
| 192 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; | 191 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; |
| 193 | guest_descriptor_queue.AddSampledImage(vk_image_view, sampler); | 192 | const Sampler& sampler{**(samplers++)}; |
| 193 | const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && | ||
| 194 | !image_view.SupportsAnisotropy()}; | ||
| 195 | const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithoutAnisotropy() | ||
| 196 | : sampler.Handle()}; | ||
| 197 | guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); | ||
| 194 | rescaling.PushTexture(texture_cache.IsRescaling(image_view)); | 198 | rescaling.PushTexture(texture_cache.IsRescaling(image_view)); |
| 195 | } | 199 | } |
| 196 | } | 200 | } |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 733e70d9d..eb292dc34 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -115,7 +115,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 115 | 115 | ||
| 116 | static constexpr size_t max_elements = 64; | 116 | static constexpr size_t max_elements = 64; |
| 117 | boost::container::static_vector<VideoCommon::ImageViewInOut, max_elements> views; | 117 | boost::container::static_vector<VideoCommon::ImageViewInOut, max_elements> views; |
| 118 | boost::container::static_vector<VkSampler, max_elements> samplers; | 118 | boost::container::static_vector<const Sampler*, max_elements> samplers; |
| 119 | 119 | ||
| 120 | const auto& qmd{kepler_compute.launch_description}; | 120 | const auto& qmd{kepler_compute.launch_description}; |
| 121 | const auto& cbufs{qmd.const_buffer_config}; | 121 | const auto& cbufs{qmd.const_buffer_config}; |
| @@ -161,7 +161,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 161 | views.push_back({handle.first}); | 161 | views.push_back({handle.first}); |
| 162 | 162 | ||
| 163 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); | 163 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); |
| 164 | samplers.push_back(sampler->Handle()); | 164 | samplers.push_back(sampler); |
| 165 | } | 165 | } |
| 166 | } | 166 | } |
| 167 | for (const auto& desc : info.image_descriptors) { | 167 | for (const auto& desc : info.image_descriptors) { |
| @@ -192,7 +192,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 192 | buffer_cache.BindHostComputeBuffers(); | 192 | buffer_cache.BindHostComputeBuffers(); |
| 193 | 193 | ||
| 194 | RescalingPushConstant rescaling; | 194 | RescalingPushConstant rescaling; |
| 195 | const VkSampler* samplers_it{samplers.data()}; | 195 | const Sampler** samplers_it{samplers.data()}; |
| 196 | const VideoCommon::ImageViewInOut* views_it{views.data()}; | 196 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 197 | PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it, | 197 | PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it, |
| 198 | views_it); | 198 | views_it); |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 506b78f08..e6e004cb6 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -298,7 +298,7 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { | |||
| 298 | template <typename Spec> | 298 | template <typename Spec> |
| 299 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | 299 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { |
| 300 | std::array<VideoCommon::ImageViewInOut, MAX_IMAGE_ELEMENTS> views; | 300 | std::array<VideoCommon::ImageViewInOut, MAX_IMAGE_ELEMENTS> views; |
| 301 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; | 301 | std::array<const Sampler*, MAX_IMAGE_ELEMENTS> samplers; |
| 302 | size_t sampler_index{}; | 302 | size_t sampler_index{}; |
| 303 | size_t view_index{}; | 303 | size_t view_index{}; |
| 304 | 304 | ||
| @@ -368,7 +368,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 368 | views[view_index++] = {handle.first}; | 368 | views[view_index++] = {handle.first}; |
| 369 | 369 | ||
| 370 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; | 370 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; |
| 371 | samplers[sampler_index++] = sampler->Handle(); | 371 | samplers[sampler_index++] = sampler; |
| 372 | } | 372 | } |
| 373 | } | 373 | } |
| 374 | if constexpr (Spec::has_images) { | 374 | if constexpr (Spec::has_images) { |
| @@ -453,7 +453,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 453 | 453 | ||
| 454 | RescalingPushConstant rescaling; | 454 | RescalingPushConstant rescaling; |
| 455 | RenderAreaPushConstant render_area; | 455 | RenderAreaPushConstant render_area; |
| 456 | const VkSampler* samplers_it{samplers.data()}; | 456 | const Sampler** samplers_it{samplers.data()}; |
| 457 | const VideoCommon::ImageViewInOut* views_it{views.data()}; | 457 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 458 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 458 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 459 | buffer_cache.BindHostStageBuffers(stage); | 459 | buffer_cache.BindHostStageBuffers(stage); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8711e2a87..0e8f8a064 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1802,27 +1802,34 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t | |||
| 1802 | // Some games have samplers with garbage. Sanitize them here. | 1802 | // Some games have samplers with garbage. Sanitize them here. |
| 1803 | const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); | 1803 | const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); |
| 1804 | 1804 | ||
| 1805 | sampler = device.GetLogical().CreateSampler(VkSamplerCreateInfo{ | 1805 | const auto create_sampler = [&](const f32 max_anisotropy) { |
| 1806 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, | 1806 | return device.GetLogical().CreateSampler(VkSamplerCreateInfo{ |
| 1807 | .pNext = pnext, | 1807 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, |
| 1808 | .flags = 0, | 1808 | .pNext = pnext, |
| 1809 | .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter), | 1809 | .flags = 0, |
| 1810 | .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter), | 1810 | .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter), |
| 1811 | .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), | 1811 | .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter), |
| 1812 | .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), | 1812 | .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), |
| 1813 | .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), | 1813 | .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), |
| 1814 | .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), | 1814 | .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), |
| 1815 | .mipLodBias = tsc.LodBias(), | 1815 | .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), |
| 1816 | .anisotropyEnable = static_cast<VkBool32>(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE), | 1816 | .mipLodBias = tsc.LodBias(), |
| 1817 | .maxAnisotropy = max_anisotropy, | 1817 | .anisotropyEnable = static_cast<VkBool32>(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE), |
| 1818 | .compareEnable = tsc.depth_compare_enabled, | 1818 | .maxAnisotropy = max_anisotropy, |
| 1819 | .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), | 1819 | .compareEnable = tsc.depth_compare_enabled, |
| 1820 | .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), | 1820 | .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), |
| 1821 | .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), | 1821 | .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), |
| 1822 | .borderColor = | 1822 | .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), |
| 1823 | arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color), | 1823 | .borderColor = |
| 1824 | .unnormalizedCoordinates = VK_FALSE, | 1824 | arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color), |
| 1825 | }); | 1825 | .unnormalizedCoordinates = VK_FALSE, |
| 1826 | }); | ||
| 1827 | }; | ||
| 1828 | |||
| 1829 | sampler = create_sampler(max_anisotropy); | ||
| 1830 | if (Settings::values.max_anisotropy.GetValue() > 0 && max_anisotropy > 1.0f) { | ||
| 1831 | sampler_without_anisotropy = create_sampler(1.0f); | ||
| 1832 | } | ||
| 1826 | } | 1833 | } |
| 1827 | 1834 | ||
| 1828 | Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers, | 1835 | Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 0f7a5ffd4..ee0d0480d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -279,8 +279,17 @@ public: | |||
| 279 | return *sampler; | 279 | return *sampler; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | [[nodiscard]] VkSampler HandleWithoutAnisotropy() const noexcept { | ||
| 283 | return *sampler_without_anisotropy; | ||
| 284 | } | ||
| 285 | |||
| 286 | [[nodiscard]] bool HasAddedAnisotropy() const noexcept { | ||
| 287 | return static_cast<bool>(sampler_without_anisotropy); | ||
| 288 | } | ||
| 289 | |||
| 282 | private: | 290 | private: |
| 283 | vk::Sampler sampler; | 291 | vk::Sampler sampler; |
| 292 | vk::Sampler sampler_without_anisotropy; | ||
| 284 | }; | 293 | }; |
| 285 | 294 | ||
| 286 | class Framebuffer { | 295 | class Framebuffer { |