|
@@ -646,7 +646,28 @@ bool TextureCache<P>::ShouldWaitAsyncFlushes() const noexcept {
|
|
|
template <class P>
|
|
template <class P>
|
|
|
void TextureCache<P>::CommitAsyncFlushes() {
|
|
void TextureCache<P>::CommitAsyncFlushes() {
|
|
|
// This is intentionally passing the value by copy
|
|
// This is intentionally passing the value by copy
|
|
|
- committed_downloads.push(uncommitted_downloads);
|
|
|
|
|
|
|
+ if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
|
|
|
|
|
+ const std::span<const ImageId> download_ids = uncommitted_downloads;
|
|
|
|
|
+ if (download_ids.empty()) {
|
|
|
|
|
+ committed_downloads.emplace_back(std::move(uncommitted_downloads));
|
|
|
|
|
+ uncommitted_downloads.clear();
|
|
|
|
|
+ async_buffers.emplace_back(std::optional<AsyncBuffer>{});
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ size_t total_size_bytes = 0;
|
|
|
|
|
+ for (const ImageId image_id : download_ids) {
|
|
|
|
|
+ total_size_bytes += slot_images[image_id].unswizzled_size_bytes;
|
|
|
|
|
+ }
|
|
|
|
|
+ auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true);
|
|
|
|
|
+ for (const ImageId image_id : download_ids) {
|
|
|
|
|
+ Image& image = slot_images[image_id];
|
|
|
|
|
+ const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
+ image.DownloadMemory(download_map, copies);
|
|
|
|
|
+ download_map.offset += Common::AlignUp(image.unswizzled_size_bytes, 64);
|
|
|
|
|
+ }
|
|
|
|
|
+ async_buffers.emplace_back(download_map);
|
|
|
|
|
+ }
|
|
|
|
|
+ committed_downloads.emplace_back(std::move(uncommitted_downloads));
|
|
|
uncommitted_downloads.clear();
|
|
uncommitted_downloads.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -655,37 +676,58 @@ void TextureCache<P>::PopAsyncFlushes() {
|
|
|
if (committed_downloads.empty()) {
|
|
if (committed_downloads.empty()) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- const std::span<const ImageId> download_ids = committed_downloads.front();
|
|
|
|
|
- if (download_ids.empty()) {
|
|
|
|
|
- committed_downloads.pop();
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- size_t total_size_bytes = 0;
|
|
|
|
|
- for (const ImageId image_id : download_ids) {
|
|
|
|
|
- total_size_bytes += slot_images[image_id].unswizzled_size_bytes;
|
|
|
|
|
- }
|
|
|
|
|
- auto download_map = runtime.DownloadStagingBuffer(total_size_bytes);
|
|
|
|
|
- const size_t original_offset = download_map.offset;
|
|
|
|
|
- for (const ImageId image_id : download_ids) {
|
|
|
|
|
- Image& image = slot_images[image_id];
|
|
|
|
|
- const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
- image.DownloadMemory(download_map, copies);
|
|
|
|
|
- download_map.offset += image.unswizzled_size_bytes;
|
|
|
|
|
- }
|
|
|
|
|
- // Wait for downloads to finish
|
|
|
|
|
- runtime.Finish();
|
|
|
|
|
-
|
|
|
|
|
- download_map.offset = original_offset;
|
|
|
|
|
- std::span<u8> download_span = download_map.mapped_span;
|
|
|
|
|
- for (const ImageId image_id : download_ids) {
|
|
|
|
|
- const ImageBase& image = slot_images[image_id];
|
|
|
|
|
- const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
- SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span,
|
|
|
|
|
- swizzle_data_buffer);
|
|
|
|
|
- download_map.offset += image.unswizzled_size_bytes;
|
|
|
|
|
- download_span = download_span.subspan(image.unswizzled_size_bytes);
|
|
|
|
|
|
|
+ if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
|
|
|
|
|
+ const std::span<const ImageId> download_ids = committed_downloads.front();
|
|
|
|
|
+ if (download_ids.empty()) {
|
|
|
|
|
+ committed_downloads.pop_front();
|
|
|
|
|
+ async_buffers.pop_front();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ auto download_map = *async_buffers.front();
|
|
|
|
|
+ std::span<u8> download_span = download_map.mapped_span;
|
|
|
|
|
+ for (size_t i = download_ids.size(); i > 0; i--) {
|
|
|
|
|
+ const ImageBase& image = slot_images[download_ids[i - 1]];
|
|
|
|
|
+ const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
+ download_map.offset -= Common::AlignUp(image.unswizzled_size_bytes, 64);
|
|
|
|
|
+ std::span<u8> download_span_alt = download_span.subspan(download_map.offset);
|
|
|
|
|
+ SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span_alt,
|
|
|
|
|
+ swizzle_data_buffer);
|
|
|
|
|
+ }
|
|
|
|
|
+ runtime.FreeDeferredStagingBuffer(download_map);
|
|
|
|
|
+ committed_downloads.pop_front();
|
|
|
|
|
+ async_buffers.pop_front();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const std::span<const ImageId> download_ids = committed_downloads.front();
|
|
|
|
|
+ if (download_ids.empty()) {
|
|
|
|
|
+ committed_downloads.pop_front();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ size_t total_size_bytes = 0;
|
|
|
|
|
+ for (const ImageId image_id : download_ids) {
|
|
|
|
|
+ total_size_bytes += slot_images[image_id].unswizzled_size_bytes;
|
|
|
|
|
+ }
|
|
|
|
|
+ auto download_map = runtime.DownloadStagingBuffer(total_size_bytes);
|
|
|
|
|
+ const size_t original_offset = download_map.offset;
|
|
|
|
|
+ for (const ImageId image_id : download_ids) {
|
|
|
|
|
+ Image& image = slot_images[image_id];
|
|
|
|
|
+ const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
+ image.DownloadMemory(download_map, copies);
|
|
|
|
|
+ download_map.offset += image.unswizzled_size_bytes;
|
|
|
|
|
+ }
|
|
|
|
|
+ // Wait for downloads to finish
|
|
|
|
|
+ runtime.Finish();
|
|
|
|
|
+ download_map.offset = original_offset;
|
|
|
|
|
+ std::span<u8> download_span = download_map.mapped_span;
|
|
|
|
|
+ for (const ImageId image_id : download_ids) {
|
|
|
|
|
+ const ImageBase& image = slot_images[image_id];
|
|
|
|
|
+ const auto copies = FullDownloadCopies(image.info);
|
|
|
|
|
+ SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span,
|
|
|
|
|
+ swizzle_data_buffer);
|
|
|
|
|
+ download_map.offset += image.unswizzled_size_bytes;
|
|
|
|
|
+ download_span = download_span.subspan(image.unswizzled_size_bytes);
|
|
|
|
|
+ }
|
|
|
|
|
+ committed_downloads.pop_front();
|
|
|
}
|
|
}
|
|
|
- committed_downloads.pop();
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template <class P>
|
|
template <class P>
|