[texture_cache] 1st phase optimizations

This commit is contained in:
wildcard 2026-04-07 21:13:48 +02:00
parent 19eab4d7aa
commit 64a4908ea6

View file

@ -264,6 +264,12 @@ template <class P>
typename P::ImageView& TextureCache<P>::GetImageView(u32 index) noexcept {
const auto image_view_id = VisitImageView(channel_state->graphics_image_table,
channel_state->graphics_image_view_ids, index);
if (image_view_id != NULL_IMAGE_VIEW_ID) {
const ImageViewBase& image_view = slot_image_views[image_view_id];
if (!image_view.IsBuffer()) {
PrepareImage(image_view.image_id, false, false);
}
}
return slot_image_views[image_view_id];
}
@ -619,20 +625,88 @@ template <bool has_blacklists>
void TextureCache<P>::FillImageViews(DescriptorTable<TICEntry>& table,
std::span<ImageViewId> cached_image_view_ids,
std::span<ImageViewInOut> views) {
if (views.empty()) {
return;
}
bool has_blacklisted = false;
do {
has_deleted_images = false;
if constexpr (has_blacklists) {
has_blacklisted = false;
}
// descriptors often reuse TIC indices in one bind pass
// use a tiny size cache to avoid expensive descriptor repeat reads
constexpr size_t RECENT_VIEW_CACHE_SIZE = 8;
std::array<std::pair<u32, ImageViewId>, RECENT_VIEW_CACHE_SIZE> recent_indices{};
std::array<bool, RECENT_VIEW_CACHE_SIZE> recent_valid{};
size_t recent_insert = 0;
boost::container::small_vector<ImageId, 16> prepared_image_ids;
[[maybe_unused]] boost::container::small_vector<ImageId, 16> blacklisted_image_ids;
for (ImageViewInOut& view : views) {
view.id = VisitImageView(table, cached_image_view_ids, view.index);
bool found_cached = false;
for (size_t cache_index = 0; cache_index < RECENT_VIEW_CACHE_SIZE; ++cache_index) {
if (recent_valid[cache_index] &&
recent_indices[cache_index].first == view.index) {
view.id = recent_indices[cache_index].second;
found_cached = true;
break;
}
}
if (!found_cached) {
view.id = VisitImageView(table, cached_image_view_ids, view.index);
recent_indices[recent_insert] = {view.index, view.id};
recent_valid[recent_insert] = true;
recent_insert = (recent_insert + 1) % RECENT_VIEW_CACHE_SIZE;
}
if (has_deleted_images) {
break;
}
if (view.id != NULL_IMAGE_VIEW_ID) {
const ImageViewBase& image_view{slot_image_views[view.id]};
if (!image_view.IsBuffer()) {
const ImageId image_id = image_view.image_id;
const bool already_queued =
std::ranges::find(prepared_image_ids, image_id) != prepared_image_ids.end();
if (!already_queued) {
prepared_image_ids.push_back(image_id);
}
}
}
if constexpr (has_blacklists) {
if (view.blacklist && view.id != NULL_IMAGE_VIEW_ID) {
const ImageViewBase& image_view{slot_image_views[view.id]};
auto& image = slot_images[image_view.image_id];
const ImageId image_id = image_view.image_id;
const bool already_queued =
std::ranges::find(blacklisted_image_ids, image_id) !=
blacklisted_image_ids.end();
if (!already_queued) {
blacklisted_image_ids.push_back(image_id);
}
}
}
}
if (!has_deleted_images) {
for (const ImageId image_id : prepared_image_ids) {
PrepareImage(image_id, false, false);
if (has_deleted_images) {
break;
}
}
}
if constexpr (has_blacklists) {
if (!has_deleted_images) {
for (const ImageId image_id : blacklisted_image_ids) {
auto& image = slot_images[image_id];
has_blacklisted |= ScaleDown(image);
image.scale_rating = 0;
if (has_deleted_images) {
break;
}
}
}
}
@ -652,9 +726,6 @@ ImageViewId TextureCache<P>::VisitImageView(DescriptorTable<TICEntry>& table,
if (is_new) {
image_view_id = FindImageView(descriptor);
}
if (image_view_id != NULL_IMAGE_VIEW_ID) {
PrepareImageView(image_view_id, false, false);
}
return image_view_id;
}