summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp29
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp28
-rw-r--r--src/video_core/texture_cache/image_base.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.h34
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
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>
280void GraphicsPipeline::ConfigureImpl(bool is_indexed) { 280void 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};
41DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) 42DECLARE_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
739template <class P> 744template <class P>
745bool 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
755template <class P>
740bool TextureCache<P>::ImageCanRescale(Image& image) { 756bool 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
181private: 183private: