Browse Source

[vulkan] Fix vuid 04553

vuid04553
wildcard 3 weeks ago
parent
commit
bd23a55ad8
  1. 10
      src/video_core/renderer_vulkan/pipeline_helper.h
  2. 30
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  3. 10
      src/video_core/renderer_vulkan/vk_texture_cache.h

10
src/video_core/renderer_vulkan/pipeline_helper.h

@ -12,12 +12,14 @@
#include "shader_recompiler/shader_info.h"
#include "video_core/renderer_vulkan/vk_texture_cache.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/types.h"
#include "video_core/vulkan_common/vulkan_device.h"
namespace Vulkan {
using Shader::Backend::SPIRV::NUM_TEXTURE_AND_IMAGE_SCALING_WORDS;
using VideoCore::Surface::IsPixelFormatInteger;
class DescriptorLayoutBuilder {
public:
@ -191,10 +193,14 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
ImageView& image_view{texture_cache.GetImageView(image_view_id)};
const VkImageView vk_image_view{image_view.Handle(desc.type)};
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
// Integer formats don't support VK_FILTER_LINEAR in Vulkan.
const bool needs_nearest{sampler.HasLinearFilter() &&
IsPixelFormatInteger(image_view.format)};
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
!image_view.SupportsAnisotropy()};
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
: sampler.Handle()};
const VkSampler vk_sampler{needs_nearest ? sampler.HandleWithNearestFilter()
: use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
: sampler.Handle()};
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
}

30
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -38,6 +38,7 @@ namespace Vulkan {
using Tegra::Engines::Fermi2D;
using Tegra::Texture::SwizzleSource;
using Tegra::Texture::TextureFilter;
using Tegra::Texture::TextureMipmapFilter;
using VideoCommon::BufferImageCopy;
using VideoCommon::ImageFlagBits;
@ -2356,6 +2357,35 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
if (max_anisotropy > max_anisotropy_default) {
sampler_default_anisotropy = create_sampler(max_anisotropy_default);
}
// Create a nearest-filter fallback for integer format image views.
// but Vulkan requires the format to support linear filtering.
const bool is_mag_linear = tsc.mag_filter == TextureFilter::Linear;
const bool is_min_linear = tsc.min_filter == TextureFilter::Linear;
has_linear_filter = is_mag_linear || is_min_linear;
if (has_linear_filter) {
sampler_nearest = device.GetLogical().CreateSampler(VkSamplerCreateInfo{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.pNext = pnext,
.flags = 0,
.magFilter = VK_FILTER_NEAREST,
.minFilter = VK_FILTER_NEAREST,
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
.addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter),
.addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter),
.addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter),
.mipLodBias = tsc.LodBias(),
.anisotropyEnable = VK_FALSE,
.maxAnisotropy = 1.0f,
.compareEnable = tsc.depth_compare_enabled,
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
.borderColor = has_custom_border_colors ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
: ConvertBorderColor(color),
.unnormalizedCoordinates = VK_FALSE,
});
}
}
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,

10
src/video_core/renderer_vulkan/vk_texture_cache.h

@ -408,9 +408,19 @@ public:
return static_cast<bool>(sampler_default_anisotropy);
}
[[nodiscard]] bool HasLinearFilter() const noexcept {
return has_linear_filter;
}
[[nodiscard]] VkSampler HandleWithNearestFilter() const noexcept {
return sampler_nearest ? *sampler_nearest : *sampler;
}
private:
vk::Sampler sampler;
vk::Sampler sampler_default_anisotropy;
vk::Sampler sampler_nearest;
bool has_linear_filter = false;
};
struct TextureCacheParams {

Loading…
Cancel
Save