mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
Texture Cache: make sparse texture table per channel
This commit is contained in:
parent
ffe3984353
commit
a7c1306e2d
2 changed files with 51 additions and 40 deletions
|
@ -1431,7 +1431,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
|
ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes,
|
||||||
|
region_check_gpu);
|
||||||
|
|
||||||
bool can_rescale = info.rescaleable;
|
bool can_rescale = info.rescaleable;
|
||||||
bool any_rescaled = false;
|
bool any_rescaled = false;
|
||||||
|
@ -1842,7 +1843,7 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
|
||||||
if (!storage_id) {
|
if (!storage_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& gpu_page_table = gpu_page_table_storage[*storage_id];
|
auto& gpu_page_table = gpu_page_table_storage[*storage_id * 2];
|
||||||
ForEachGPUPage(gpu_addr, size,
|
ForEachGPUPage(gpu_addr, size,
|
||||||
[this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) {
|
[this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) {
|
||||||
const auto it = gpu_page_table.find(page);
|
const auto it = gpu_page_table.find(page);
|
||||||
|
@ -1882,41 +1883,48 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
void TextureCache<P>::ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func) {
|
void TextureCache<P>::ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size,
|
||||||
|
Func&& func) {
|
||||||
using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
|
using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
|
||||||
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
|
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
|
||||||
boost::container::small_vector<ImageId, 8> images;
|
boost::container::small_vector<ImageId, 8> images;
|
||||||
ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) {
|
auto storage_id = getStorageID(as_id);
|
||||||
const auto it = sparse_page_table.find(page);
|
if (!storage_id) {
|
||||||
if (it == sparse_page_table.end()) {
|
return;
|
||||||
if constexpr (BOOL_BREAK) {
|
}
|
||||||
return false;
|
auto& sparse_page_table = gpu_page_table_storage[*storage_id * 2 + 1];
|
||||||
} else {
|
ForEachGPUPage(gpu_addr, size,
|
||||||
return;
|
[this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) {
|
||||||
}
|
const auto it = sparse_page_table.find(page);
|
||||||
}
|
if (it == sparse_page_table.end()) {
|
||||||
for (const ImageId image_id : it->second) {
|
if constexpr (BOOL_BREAK) {
|
||||||
Image& image = slot_images[image_id];
|
return false;
|
||||||
if (True(image.flags & ImageFlagBits::Picked)) {
|
} else {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
if (!image.OverlapsGPU(gpu_addr, size)) {
|
}
|
||||||
continue;
|
for (const ImageId image_id : it->second) {
|
||||||
}
|
Image& image = slot_images[image_id];
|
||||||
image.flags |= ImageFlagBits::Picked;
|
if (True(image.flags & ImageFlagBits::Picked)) {
|
||||||
images.push_back(image_id);
|
continue;
|
||||||
if constexpr (BOOL_BREAK) {
|
}
|
||||||
if (func(image_id, image)) {
|
if (!image.OverlapsGPU(gpu_addr, size)) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
image.flags |= ImageFlagBits::Picked;
|
||||||
func(image_id, image);
|
images.push_back(image_id);
|
||||||
}
|
if constexpr (BOOL_BREAK) {
|
||||||
}
|
if (func(image_id, image)) {
|
||||||
if constexpr (BOOL_BREAK) {
|
return true;
|
||||||
return false;
|
}
|
||||||
}
|
} else {
|
||||||
});
|
func(image_id, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if constexpr (BOOL_BREAK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
for (const ImageId image_id : images) {
|
for (const ImageId image_id : images) {
|
||||||
slot_images[image_id].flags &= ~ImageFlagBits::Picked;
|
slot_images[image_id].flags &= ~ImageFlagBits::Picked;
|
||||||
}
|
}
|
||||||
|
@ -1988,8 +1996,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
|
||||||
sparse_maps.push_back(map_id);
|
sparse_maps.push_back(map_id);
|
||||||
});
|
});
|
||||||
sparse_views.emplace(image_id, std::move(sparse_maps));
|
sparse_views.emplace(image_id, std::move(sparse_maps));
|
||||||
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
|
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
|
||||||
[this, image_id](u64 page) { sparse_page_table[page].push_back(image_id); });
|
(*channel_state->sparse_page_table)[page].push_back(image_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -2042,7 +2051,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
|
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
|
||||||
clear_page_table(page, sparse_page_table);
|
clear_page_table(page, (*channel_state->sparse_page_table));
|
||||||
});
|
});
|
||||||
auto it = sparse_views.find(image_id);
|
auto it = sparse_views.find(image_id);
|
||||||
ASSERT(it != sparse_views.end());
|
ASSERT(it != sparse_views.end());
|
||||||
|
@ -2496,13 +2505,15 @@ void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel
|
||||||
const auto it = channel_map.find(channel.bind_id);
|
const auto it = channel_map.find(channel.bind_id);
|
||||||
auto* this_state = &channel_storage[it->second];
|
auto* this_state = &channel_storage[it->second];
|
||||||
const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
|
const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
|
||||||
this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id];
|
this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2];
|
||||||
|
this_state->sparse_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2 + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind a channel for execution.
|
/// Bind a channel for execution.
|
||||||
template <class P>
|
template <class P>
|
||||||
void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
|
void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
|
||||||
gpu_page_table_storage.emplace_back();
|
gpu_page_table_storage.emplace_back();
|
||||||
|
gpu_page_table_storage.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace VideoCommon
|
} // namespace VideoCommon
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
std::unordered_map<TSCEntry, SamplerId> samplers;
|
std::unordered_map<TSCEntry, SamplerId> samplers;
|
||||||
|
|
||||||
TextureCacheGPUMap* gpu_page_table;
|
TextureCacheGPUMap* gpu_page_table;
|
||||||
|
TextureCacheGPUMap* sparse_page_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -357,7 +358,7 @@ private:
|
||||||
void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
|
void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
|
void ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
|
||||||
|
|
||||||
/// Iterates over all the images in a region calling func
|
/// Iterates over all the images in a region calling func
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
|
@ -431,7 +432,6 @@ private:
|
||||||
std::unordered_map<RenderTargets, FramebufferId> framebuffers;
|
std::unordered_map<RenderTargets, FramebufferId> framebuffers;
|
||||||
|
|
||||||
std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
|
std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
|
||||||
std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table;
|
|
||||||
std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views;
|
std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views;
|
||||||
|
|
||||||
DAddr virtual_invalid_space{};
|
DAddr virtual_invalid_space{};
|
||||||
|
|
Loading…
Reference in a new issue