[surface, vk, pipeline, texture_cache] Texture Sampling Fix

This commit is contained in:
CamilleLaVey
2025-11-24 19:53:02 -04:00
parent f63818be3c
commit 8315f15cc1
5 changed files with 65 additions and 10 deletions

View File

@@ -192,7 +192,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
const VideoCommon::ImageViewId image_view_id{(views++)->id};
const VideoCommon::SamplerId sampler_id{*(samplers++)};
ImageView& image_view{texture_cache.GetImageView(image_view_id)};
const VkImageView vk_image_view{image_view.SampledHandle(desc.type)};
const VkImageView vk_image_view{image_view.SampledHandle(desc.type, desc.is_integer)};
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
!image_view.SupportsAnisotropy()};

View File

@@ -45,6 +45,7 @@ using VideoCore::Surface::BytesPerBlock;
using VideoCore::Surface::HasAlpha;
using VideoCore::Surface::IsPixelFormatASTC;
using VideoCore::Surface::IsPixelFormatInteger;
using VideoCore::Surface::IntegerCompatibleFormat;
using VideoCore::Surface::NormalizedCompatibleFormat;
using VideoCore::Surface::SurfaceType;
@@ -2223,22 +2224,40 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
return *view;
}
VkImageView ImageView::SampledHandle(Shader::TextureType texture_type) {
if (!IsPixelFormatInteger(format)) {
return Handle(texture_type);
VkImageView ImageView::SampledHandle(Shader::TextureType texture_type, bool use_integer_view) {
const auto type_index = static_cast<size_t>(texture_type);
if (use_integer_view || !IsPixelFormatInteger(format)) {
if (!use_integer_view || IsPixelFormatInteger(format)) {
return Handle(texture_type);
}
const auto compatible_integer = IntegerCompatibleFormat(format);
if (!compatible_integer) {
return Handle(texture_type);
}
auto& int_view = sampled_integer_views[type_index];
if (int_view) {
return *int_view;
}
const auto format_info =
MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, *compatible_integer);
int_view = CreateSampledView(texture_type, format_info.format);
return *int_view;
}
const auto compatible_format = NormalizedCompatibleFormat(format);
if (!compatible_format) {
return Handle(texture_type);
}
auto& view = sampled_float_views[static_cast<size_t>(texture_type)];
if (view) {
return *view;
auto& float_view = sampled_float_views[type_index];
if (float_view) {
return *float_view;
}
const auto format_info =
MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, *compatible_format);
view = CreateSampledView(texture_type, format_info.format);
return *view;
float_view = CreateSampledView(texture_type, format_info.format);
return *float_view;
}
bool ImageView::IsRescaled() const noexcept {

View File

@@ -247,7 +247,8 @@ public:
return *image_views[static_cast<size_t>(texture_type)];
}
[[nodiscard]] VkImageView SampledHandle(Shader::TextureType texture_type);
[[nodiscard]] VkImageView SampledHandle(Shader::TextureType texture_type,
bool use_integer_view);
[[nodiscard]] VkImage ImageHandle() const noexcept {
return image_handle;
@@ -284,6 +285,7 @@ private:
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> sampled_float_views;
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> sampled_integer_views;
std::array<std::optional<u32>, Shader::NUM_TEXTURE_TYPES> view_layer_counts{};
std::unique_ptr<StorageViews> storage_views;
vk::ImageView depth_view;

View File

@@ -443,6 +443,39 @@ std::optional<PixelFormat> NormalizedCompatibleFormat(PixelFormat format) {
}
}
std::optional<PixelFormat> IntegerCompatibleFormat(PixelFormat format) {
switch (format) {
case PixelFormat::A8B8G8R8_UNORM:
return PixelFormat::A8B8G8R8_UINT;
case PixelFormat::A8B8G8R8_SNORM:
return PixelFormat::A8B8G8R8_SINT;
case PixelFormat::A2B10G10R10_UNORM:
return PixelFormat::A2B10G10R10_UINT;
case PixelFormat::R8_UNORM:
return PixelFormat::R8_UINT;
case PixelFormat::R8_SNORM:
return PixelFormat::R8_SINT;
case PixelFormat::R8G8_UNORM:
return PixelFormat::R8G8_UINT;
case PixelFormat::R8G8_SNORM:
return PixelFormat::R8G8_SINT;
case PixelFormat::R16_UNORM:
return PixelFormat::R16_UINT;
case PixelFormat::R16_SNORM:
return PixelFormat::R16_SINT;
case PixelFormat::R16G16_UNORM:
return PixelFormat::R16G16_UINT;
case PixelFormat::R16G16_SNORM:
return PixelFormat::R16G16_SINT;
case PixelFormat::R16G16B16A16_UNORM:
return PixelFormat::R16G16B16A16_UINT;
case PixelFormat::R16G16B16A16_SNORM:
return PixelFormat::R16G16B16A16_SINT;
default:
return std::nullopt;
}
}
size_t PixelComponentSizeBitsInteger(PixelFormat format) {
switch (format) {
case PixelFormat::A8B8G8R8_SINT:

View File

@@ -520,6 +520,7 @@ bool IsPixelFormatInteger(PixelFormat format);
bool IsPixelFormatSignedInteger(PixelFormat format);
std::optional<PixelFormat> NormalizedCompatibleFormat(PixelFormat format);
std::optional<PixelFormat> IntegerCompatibleFormat(PixelFormat format);
size_t PixelComponentSizeBitsInteger(PixelFormat format);