summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar Wollnashorn2023-06-15 18:19:32 +0200
committerGravatar Wollnashorn2023-06-15 18:19:32 +0200
commit42c944b250d8d5c8147b24b3a453cba29968d46c (patch)
tree6d156e8247219bf373edd848bd3a89bbd32eb546 /src/video_core/renderer_vulkan
parentvideo_core: Apply AF only to samplers with normal LOD range [0, 1+x] (diff)
downloadyuzu-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')
-rw-r--r--src/video_core/renderer_vulkan/pipeline_helper.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp49
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h9
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:
178inline void PushImageDescriptors(TextureCache& texture_cache, 178inline 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) {
298template <typename Spec> 298template <typename Spec>
299void GraphicsPipeline::ConfigureImpl(bool is_indexed) { 299void 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
1828Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers, 1835Framebuffer::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
282private: 290private:
283 vk::Sampler sampler; 291 vk::Sampler sampler;
292 vk::Sampler sampler_without_anisotropy;
284}; 293};
285 294
286class Framebuffer { 295class Framebuffer {