diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 1 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 34 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
5 files changed, 90 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index bda75788c..5c591e345 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -111,6 +111,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 111 | std::array<ImageId, max_elements> image_view_ids; | 111 | std::array<ImageId, max_elements> image_view_ids; |
| 112 | boost::container::static_vector<u32, max_elements> image_view_indices; | 112 | boost::container::static_vector<u32, max_elements> image_view_indices; |
| 113 | boost::container::static_vector<VkSampler, max_elements> samplers; | 113 | boost::container::static_vector<VkSampler, max_elements> samplers; |
| 114 | boost::container::static_vector<bool, max_elements> image_view_blacklist; | ||
| 114 | 115 | ||
| 115 | const auto& qmd{kepler_compute.launch_description}; | 116 | const auto& qmd{kepler_compute.launch_description}; |
| 116 | const auto& cbufs{qmd.const_buffer_config}; | 117 | const auto& cbufs{qmd.const_buffer_config}; |
| @@ -151,10 +152,34 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 151 | samplers.push_back(sampler->Handle()); | 152 | samplers.push_back(sampler->Handle()); |
| 152 | } | 153 | } |
| 153 | } | 154 | } |
| 154 | std::ranges::for_each(info.image_descriptors, add_image); | 155 | const u32 black_list_base = image_view_indices.size(); |
| 156 | bool atleast_one_blacklisted = false; | ||
| 157 | for (const auto& desc : info.image_descriptors) { | ||
| 158 | const bool is_black_listed = | ||
| 159 | desc.is_written && (desc.type == Shader::TextureType::Color2D || | ||
| 160 | desc.type == Shader::TextureType::ColorArray2D); | ||
| 161 | for (u32 index = 0; index < desc.count; ++index) { | ||
| 162 | image_view_blacklist.push_back(is_black_listed); | ||
| 163 | } | ||
| 164 | atleast_one_blacklisted |= is_black_listed; | ||
| 165 | add_image(desc); | ||
| 166 | } | ||
| 155 | 167 | ||
| 156 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 168 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); |
| 157 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | 169 | bool has_listed_stuffs; |
| 170 | do { | ||
| 171 | has_listed_stuffs = false; | ||
| 172 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | ||
| 173 | if (atleast_one_blacklisted) { | ||
| 174 | for (u32 index = 0; index < image_view_blacklist.size(); index++) { | ||
| 175 | if (image_view_blacklist[index]) { | ||
| 176 | ImageView& image_view{ | ||
| 177 | texture_cache.GetImageView(image_view_ids[index + black_list_base])}; | ||
| 178 | has_listed_stuffs |= texture_cache.BlackListImage(image_view.image_id); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } while (has_listed_stuffs); | ||
| 158 | 183 | ||
| 159 | buffer_cache.UnbindComputeTextureBuffers(); | 184 | buffer_cache.UnbindComputeTextureBuffers(); |
| 160 | ImageId* texture_buffer_ids{image_view_ids.data()}; | 185 | ImageId* texture_buffer_ids{image_view_ids.data()}; |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 967762c37..4d966ee4b 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -280,6 +280,7 @@ template <typename Spec> | |||
| 280 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | 280 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { |
| 281 | std::array<ImageId, MAX_IMAGE_ELEMENTS> image_view_ids; | 281 | std::array<ImageId, MAX_IMAGE_ELEMENTS> image_view_ids; |
| 282 | std::array<u32, MAX_IMAGE_ELEMENTS> image_view_indices; | 282 | std::array<u32, MAX_IMAGE_ELEMENTS> image_view_indices; |
| 283 | std::array<bool, MAX_IMAGE_ELEMENTS> image_view_blacklist; | ||
| 283 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; | 284 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; |
| 284 | size_t sampler_index{}; | 285 | size_t sampler_index{}; |
| 285 | size_t image_index{}; | 286 | size_t image_index{}; |
| @@ -290,6 +291,8 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 290 | 291 | ||
| 291 | const auto& regs{maxwell3d.regs}; | 292 | const auto& regs{maxwell3d.regs}; |
| 292 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 293 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; |
| 294 | u32 start_black_list = std::numeric_limits<u32>::max(); | ||
| 295 | u32 end_black_list = 0; | ||
| 293 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 296 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 294 | const Shader::Info& info{stage_infos[stage]}; | 297 | const Shader::Info& info{stage_infos[stage]}; |
| 295 | buffer_cache.UnbindGraphicsStorageBuffers(stage); | 298 | buffer_cache.UnbindGraphicsStorageBuffers(stage); |
| @@ -350,6 +353,15 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 350 | } | 353 | } |
| 351 | if constexpr (Spec::has_images) { | 354 | if constexpr (Spec::has_images) { |
| 352 | for (const auto& desc : info.image_descriptors) { | 355 | for (const auto& desc : info.image_descriptors) { |
| 356 | if (desc.is_written && (desc.type == Shader::TextureType::Color2D || | ||
| 357 | desc.type == Shader::TextureType::ColorArray2D)) { | ||
| 358 | auto index_copy = image_index; | ||
| 359 | for (u32 index = 0; index < desc.count; ++index) { | ||
| 360 | start_black_list = std::min<u32>(start_black_list, index_copy); | ||
| 361 | image_view_blacklist[index_copy++] = true; | ||
| 362 | end_black_list = std::max<u32>(end_black_list, index_copy); | ||
| 363 | } | ||
| 364 | } | ||
| 353 | add_image(desc); | 365 | add_image(desc); |
| 354 | } | 366 | } |
| 355 | } | 367 | } |
| @@ -370,7 +382,21 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 370 | config_stage(4); | 382 | config_stage(4); |
| 371 | } | 383 | } |
| 372 | const std::span indices_span(image_view_indices.data(), image_index); | 384 | const std::span indices_span(image_view_indices.data(), image_index); |
| 373 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | 385 | bool has_listed_stuffs; |
| 386 | do { | ||
| 387 | has_listed_stuffs = false; | ||
| 388 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | ||
| 389 | if constexpr (Spec::has_images) { | ||
| 390 | if (start_black_list < end_black_list) { | ||
| 391 | for (u32 index = start_black_list; index < end_black_list; index++) { | ||
| 392 | if (image_view_blacklist[index]) { | ||
| 393 | ImageView& image_view{texture_cache.GetImageView(image_view_ids[index])}; | ||
| 394 | has_listed_stuffs |= texture_cache.BlackListImage(image_view.image_id); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | } while (has_listed_stuffs); | ||
| 374 | 400 | ||
| 375 | ImageId* texture_buffer_index{image_view_ids.data()}; | 401 | ImageId* texture_buffer_index{image_view_ids.data()}; |
| 376 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { | 402 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { |
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 1cd30fd37..10dd52e28 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h | |||
| @@ -37,6 +37,7 @@ enum class ImageFlagBits : u32 { | |||
| 37 | // Rescaler | 37 | // Rescaler |
| 38 | Rescaled = 1 << 12, | 38 | Rescaled = 1 << 12, |
| 39 | RescaleChecked = 1 << 13, | 39 | RescaleChecked = 1 << 13, |
| 40 | Blacklisted = 1 << 14, | ||
| 40 | }; | 41 | }; |
| 41 | DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) | 42 | DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) |
| 42 | 43 | ||
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index ae74a6ecf..ce5994d5f 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -227,6 +227,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 227 | flags[Dirty::RenderTargetControl] = false; | 227 | flags[Dirty::RenderTargetControl] = false; |
| 228 | 228 | ||
| 229 | bool can_rescale = true; | 229 | bool can_rescale = true; |
| 230 | bool any_blacklisted = false; | ||
| 230 | std::array<ImageId, NUM_RT> tmp_color_images{}; | 231 | std::array<ImageId, NUM_RT> tmp_color_images{}; |
| 231 | ImageId tmp_depth_image{}; | 232 | ImageId tmp_depth_image{}; |
| 232 | const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { | 233 | const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { |
| @@ -236,6 +237,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 236 | id_save = image_id; | 237 | id_save = image_id; |
| 237 | auto& image = slot_images[image_id]; | 238 | auto& image = slot_images[image_id]; |
| 238 | can_rescale &= ImageCanRescale(image); | 239 | can_rescale &= ImageCanRescale(image); |
| 240 | any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted); | ||
| 239 | } else { | 241 | } else { |
| 240 | id_save = CORRUPT_ID; | 242 | id_save = CORRUPT_ID; |
| 241 | } | 243 | } |
| @@ -268,10 +270,13 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 268 | scale_up(tmp_depth_image); | 270 | scale_up(tmp_depth_image); |
| 269 | } else { | 271 | } else { |
| 270 | rescaled = false; | 272 | rescaled = false; |
| 271 | const auto scale_down = [this](ImageId image_id) { | 273 | const auto scale_down = [this, any_blacklisted](ImageId image_id) { |
| 272 | if (image_id != CORRUPT_ID) { | 274 | if (image_id != CORRUPT_ID) { |
| 273 | Image& image = slot_images[image_id]; | 275 | Image& image = slot_images[image_id]; |
| 274 | ScaleDown(image); | 276 | ScaleDown(image); |
| 277 | if (any_blacklisted) { | ||
| 278 | image.flags |= ImageFlagBits::Blacklisted; | ||
| 279 | } | ||
| 275 | } | 280 | } |
| 276 | }; | 281 | }; |
| 277 | for (size_t index = 0; index < NUM_RT; ++index) { | 282 | for (size_t index = 0; index < NUM_RT; ++index) { |
| @@ -737,7 +742,21 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, | |||
| 737 | } | 742 | } |
| 738 | 743 | ||
| 739 | template <class P> | 744 | template <class P> |
| 745 | bool TextureCache<P>::BlackListImage(ImageId image_id) { | ||
| 746 | auto& image = slot_images[image_id]; | ||
| 747 | if (True(image.flags & ImageFlagBits::Blacklisted)) { | ||
| 748 | return false; | ||
| 749 | } | ||
| 750 | image.flags |= ImageFlagBits::Blacklisted; | ||
| 751 | ScaleDown(image); | ||
| 752 | return true; | ||
| 753 | } | ||
| 754 | |||
| 755 | template <class P> | ||
| 740 | bool TextureCache<P>::ImageCanRescale(Image& image) { | 756 | bool TextureCache<P>::ImageCanRescale(Image& image) { |
| 757 | if (True(image.flags & ImageFlagBits::Blacklisted)) { | ||
| 758 | return false; | ||
| 759 | } | ||
| 741 | if (True(image.flags & ImageFlagBits::Rescaled) || | 760 | if (True(image.flags & ImageFlagBits::Rescaled) || |
| 742 | True(image.flags & ImageFlagBits::RescaleChecked)) { | 761 | True(image.flags & ImageFlagBits::RescaleChecked)) { |
| 743 | return true; | 762 | return true; |
| @@ -912,6 +931,7 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 912 | bool can_rescale = | 931 | bool can_rescale = |
| 913 | (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0; | 932 | (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0; |
| 914 | bool any_rescaled = false; | 933 | bool any_rescaled = false; |
| 934 | bool any_blacklisted = false; | ||
| 915 | for (const ImageId sibling_id : all_siblings) { | 935 | for (const ImageId sibling_id : all_siblings) { |
| 916 | if (!can_rescale) { | 936 | if (!can_rescale) { |
| 917 | break; | 937 | break; |
| @@ -919,6 +939,7 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 919 | Image& sibling = slot_images[sibling_id]; | 939 | Image& sibling = slot_images[sibling_id]; |
| 920 | can_rescale &= ImageCanRescale(sibling); | 940 | can_rescale &= ImageCanRescale(sibling); |
| 921 | any_rescaled |= True(sibling.flags & ImageFlagBits::Rescaled); | 941 | any_rescaled |= True(sibling.flags & ImageFlagBits::Rescaled); |
| 942 | any_blacklisted |= True(sibling.flags & ImageFlagBits::Blacklisted); | ||
| 922 | } | 943 | } |
| 923 | 944 | ||
| 924 | can_rescale &= any_rescaled; | 945 | can_rescale &= any_rescaled; |
| @@ -932,6 +953,9 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 932 | for (const ImageId sibling_id : all_siblings) { | 953 | for (const ImageId sibling_id : all_siblings) { |
| 933 | Image& sibling = slot_images[sibling_id]; | 954 | Image& sibling = slot_images[sibling_id]; |
| 934 | ScaleDown(sibling); | 955 | ScaleDown(sibling); |
| 956 | if (any_blacklisted) { | ||
| 957 | sibling.flags |= ImageFlagBits::Blacklisted; | ||
| 958 | } | ||
| 935 | } | 959 | } |
| 936 | } | 960 | } |
| 937 | 961 | ||
| @@ -1556,6 +1580,7 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) { | |||
| 1556 | boost::container::small_vector<const AliasedImage*, 1> aliased_images; | 1580 | boost::container::small_vector<const AliasedImage*, 1> aliased_images; |
| 1557 | Image& image = slot_images[image_id]; | 1581 | Image& image = slot_images[image_id]; |
| 1558 | bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled); | 1582 | bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled); |
| 1583 | bool any_blacklisted = True(image.flags & ImageFlagBits::Blacklisted); | ||
| 1559 | u64 most_recent_tick = image.modification_tick; | 1584 | u64 most_recent_tick = image.modification_tick; |
| 1560 | for (const AliasedImage& aliased : image.aliased_images) { | 1585 | for (const AliasedImage& aliased : image.aliased_images) { |
| 1561 | ImageBase& aliased_image = slot_images[aliased.id]; | 1586 | ImageBase& aliased_image = slot_images[aliased.id]; |
| @@ -1563,6 +1588,7 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) { | |||
| 1563 | most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick); | 1588 | most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick); |
| 1564 | aliased_images.push_back(&aliased); | 1589 | aliased_images.push_back(&aliased); |
| 1565 | any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled); | 1590 | any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled); |
| 1591 | any_blacklisted |= True(aliased_image.flags & ImageFlagBits::Blacklisted); | ||
| 1566 | } | 1592 | } |
| 1567 | } | 1593 | } |
| 1568 | if (aliased_images.empty()) { | 1594 | if (aliased_images.empty()) { |
| @@ -1574,6 +1600,9 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) { | |||
| 1574 | ScaleUp(image); | 1600 | ScaleUp(image); |
| 1575 | } else { | 1601 | } else { |
| 1576 | ScaleDown(image); | 1602 | ScaleDown(image); |
| 1603 | if (any_blacklisted) { | ||
| 1604 | image.flags |= ImageFlagBits::Blacklisted; | ||
| 1605 | } | ||
| 1577 | } | 1606 | } |
| 1578 | } | 1607 | } |
| 1579 | image.modification_tick = most_recent_tick; | 1608 | image.modification_tick = most_recent_tick; |
| @@ -1589,6 +1618,9 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) { | |||
| 1589 | ScaleUp(aliased_image); | 1618 | ScaleUp(aliased_image); |
| 1590 | } else { | 1619 | } else { |
| 1591 | ScaleDown(aliased_image); | 1620 | ScaleDown(aliased_image); |
| 1621 | if (any_blacklisted) { | ||
| 1622 | aliased_image.flags |= ImageFlagBits::Blacklisted; | ||
| 1623 | } | ||
| 1592 | } | 1624 | } |
| 1593 | } | 1625 | } |
| 1594 | CopyImage(image_id, aliased->id, aliased->copies); | 1626 | CopyImage(image_id, aliased->id, aliased->copies); |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 0d2d9ec2e..35a29cd9b 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -176,6 +176,8 @@ public: | |||
| 176 | 176 | ||
| 177 | [[nodiscard]] bool IsRescaling(); | 177 | [[nodiscard]] bool IsRescaling(); |
| 178 | 178 | ||
| 179 | [[nodiscard]] bool BlackListImage(ImageId image_id); | ||
| 180 | |||
| 179 | std::mutex mutex; | 181 | std::mutex mutex; |
| 180 | 182 | ||
| 181 | private: | 183 | private: |