Browse Source

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

true-eds
CamilleLaVey 4 weeks ago
committed by Caio Oliveira
parent
commit
dd74bb459b
No known key found for this signature in database GPG Key ID: AAAE6C7FD4186B0C
  1. 2
      src/video_core/renderer_vulkan/pipeline_helper.h
  2. 35
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  3. 4
      src/video_core/renderer_vulkan/vk_texture_cache.h
  4. 33
      src/video_core/surface.cpp
  5. 1
      src/video_core/surface.h

2
src/video_core/renderer_vulkan/pipeline_helper.h

@ -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()};

35
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -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;
@ -2234,22 +2235,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 {

4
src/video_core/renderer_vulkan/vk_texture_cache.h

@ -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;

33
src/video_core/surface.cpp

@ -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:

1
src/video_core/surface.h

@ -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);

Loading…
Cancel
Save