[surface, vk, pipeline, texture_cache] Texture Sampling Fix
This commit is contained in:
@@ -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()};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user