From 42c944b250d8d5c8147b24b3a453cba29968d46c Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 18:19:32 +0200 Subject: video_core: Add per-image anisotropy heuristics (format & mip count) --- src/video_core/texture_cache/image_view_base.cpp | 39 ++++++++++++++++++++++++ src/video_core/texture_cache/image_view_base.h | 2 ++ 2 files changed, 41 insertions(+) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index d134b6738..26fa6d63e 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -45,4 +45,43 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} +bool ImageViewBase::SupportsAnisotropy() const noexcept { + using namespace VideoCommon; + switch (format) { + case PixelFormat::R8_UNORM: + case PixelFormat::R8_SNORM: + case PixelFormat::R8_SINT: + case PixelFormat::R8_UINT: + case PixelFormat::BC4_UNORM: + case PixelFormat::BC4_SNORM: + case PixelFormat::BC5_UNORM: + case PixelFormat::BC5_SNORM: + case PixelFormat::R32G32_FLOAT: + case PixelFormat::R32G32_SINT: + case PixelFormat::R32_FLOAT: + case PixelFormat::R16_FLOAT: + case PixelFormat::R16_UNORM: + case PixelFormat::R16_SNORM: + case PixelFormat::R16_UINT: + case PixelFormat::R16_SINT: + case PixelFormat::R16G16_UNORM: + case PixelFormat::R16G16_FLOAT: + case PixelFormat::R16G16_UINT: + case PixelFormat::R16G16_SINT: + case PixelFormat::R16G16_SNORM: + case PixelFormat::R8G8_UNORM: + case PixelFormat::R8G8_SNORM: + case PixelFormat::R8G8_SINT: + case PixelFormat::R8G8_UINT: + case PixelFormat::R32G32_UINT: + case PixelFormat::R32_UINT: + case PixelFormat::R32_SINT: + case PixelFormat::G4R4_UNORM: + return false; + default: + break; + } + return range.extent.levels > 1; +} + } // namespace VideoCommon diff --git a/src/video_core/texture_cache/image_view_base.h b/src/video_core/texture_cache/image_view_base.h index a25ae1d4a..87549ffff 100644 --- a/src/video_core/texture_cache/image_view_base.h +++ b/src/video_core/texture_cache/image_view_base.h @@ -33,6 +33,8 @@ struct ImageViewBase { return type == ImageViewType::Buffer; } + [[nodiscard]] bool SupportsAnisotropy() const noexcept; + ImageId image_id{}; GPUVAddr gpu_addr = 0; PixelFormat format{}; -- cgit v1.2.3 From 745d16132b9662de5b8317bfba37fe89c11cea45 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 20:59:33 +0200 Subject: video_core: Disable AF for non-color image formats --- src/video_core/texture_cache/image_view_base.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 26fa6d63e..5ebe9b9bb 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -77,6 +77,15 @@ bool ImageViewBase::SupportsAnisotropy() const noexcept { case PixelFormat::R32_UINT: case PixelFormat::R32_SINT: case PixelFormat::G4R4_UNORM: + // Depth formats + case PixelFormat::D32_FLOAT: + case PixelFormat::D16_UNORM: + // Stencil formats + case PixelFormat::S8_UINT: + // DepthStencil formats + case PixelFormat::D24_UNORM_S8_UINT: + case PixelFormat::S8_UINT_D24_UNORM: + case PixelFormat::D32_FLOAT_S8_UINT: return false; default: break; -- cgit v1.2.3 From 2dc0ff79ece34286c7078922668fd9f0a19b47b7 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Fri, 16 Jun 2023 13:26:44 +0200 Subject: video_core: Use sampler IDs instead pointers in the pipeline config The previous approach of storing pointers returned by `GetGraphicsSampler`/`GetComputeSampler` caused UB, as these functions can cause reallocation of the sampler slot vector and therefore invalidate the pointers --- src/video_core/texture_cache/image_view_base.cpp | 1 - src/video_core/texture_cache/texture_cache.h | 30 +++++++++++++++++++---- src/video_core/texture_cache/texture_cache_base.h | 12 +++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 5ebe9b9bb..000eec869 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -46,7 +46,6 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} bool ImageViewBase::SupportsAnisotropy() const noexcept { - using namespace VideoCommon; switch (format) { case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c7f7448e9..4027d860b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -222,30 +222,50 @@ void TextureCache

::CheckFeedbackLoop(std::span views) { template typename P::Sampler* TextureCache

::GetGraphicsSampler(u32 index) { + return &slot_samplers[GetGraphicsSamplerId(index)]; +} + +template +typename P::Sampler* TextureCache

::GetComputeSampler(u32 index) { + return &slot_samplers[GetComputeSamplerId(index)]; +} + +template +SamplerId TextureCache

::GetGraphicsSamplerId(u32 index) { if (index > channel_state->graphics_sampler_table.Limit()) { LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); - return &slot_samplers[NULL_SAMPLER_ID]; + return NULL_SAMPLER_ID; } const auto [descriptor, is_new] = channel_state->graphics_sampler_table.Read(index); SamplerId& id = channel_state->graphics_sampler_ids[index]; if (is_new) { id = FindSampler(descriptor); } - return &slot_samplers[id]; + return id; } template -typename P::Sampler* TextureCache

::GetComputeSampler(u32 index) { +SamplerId TextureCache

::GetComputeSamplerId(u32 index) { if (index > channel_state->compute_sampler_table.Limit()) { LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); - return &slot_samplers[NULL_SAMPLER_ID]; + return NULL_SAMPLER_ID; } const auto [descriptor, is_new] = channel_state->compute_sampler_table.Read(index); SamplerId& id = channel_state->compute_sampler_ids[index]; if (is_new) { id = FindSampler(descriptor); } - return &slot_samplers[id]; + return id; +} + +template +const typename P::Sampler& TextureCache

::GetSampler(SamplerId id) const noexcept { + return slot_samplers[id]; +} + +template +typename P::Sampler& TextureCache

::GetSampler(SamplerId id) noexcept { + return slot_samplers[id]; } template diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 3bfa92154..d96ddea9d 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -159,6 +159,18 @@ public: /// Get the sampler from the compute descriptor table in the specified index Sampler* GetComputeSampler(u32 index); + /// Get the sampler id from the graphics descriptor table in the specified index + SamplerId GetGraphicsSamplerId(u32 index); + + /// Get the sampler id from the compute descriptor table in the specified index + SamplerId GetComputeSamplerId(u32 index); + + /// Return a constant reference to the given sampler id + [[nodiscard]] const Sampler& GetSampler(SamplerId id) const noexcept; + + /// Return a reference to the given sampler id + [[nodiscard]] Sampler& GetSampler(SamplerId id) noexcept; + /// Refresh the state for graphics image view and sampler descriptors void SynchronizeGraphicsDescriptors(); -- cgit v1.2.3 From 3e47ebe2e90d0272ed516b09a0f527489daaf047 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Sat, 17 Jun 2023 14:20:44 +0200 Subject: video_core: Only apply AF to 2D (array) image types --- src/video_core/texture_cache/image_view_base.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 000eec869..0c5f4450d 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -46,6 +46,12 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} bool ImageViewBase::SupportsAnisotropy() const noexcept { + const bool has_mips = range.extent.levels > 1; + const bool is_2d = type == ImageViewType::e2D || type == ImageViewType::e2DArray; + if (!has_mips || !is_2d) { + return false; + } + switch (format) { case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: @@ -87,9 +93,8 @@ bool ImageViewBase::SupportsAnisotropy() const noexcept { case PixelFormat::D32_FLOAT_S8_UINT: return false; default: - break; + return true; } - return range.extent.levels > 1; } } // namespace VideoCommon -- cgit v1.2.3