::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, Runtime& runtime_) : runtime{runtime_}, device_memory{device_memory_}, memory_tracker{device_memory} { @@ -633,6 +672,7 @@ void BufferCache
::PopAsyncBuffers() {
u8* base = async_buffer->mapped_span.data();
const size_t base_offset = async_buffer->offset;
for (const auto& copy : downloads) {
+ StagingInvalidateRange(*async_buffer, copy.dst_offset, copy.size);
const DAddr device_addr = static_cast ::BindHostIndexBuffer() {
{BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}};
std::memcpy(upload_staging.mapped_span.data(),
draw_state.inline_index_draw_indexes.data(), size);
+ StagingFlushRange(upload_staging, upload_staging.offset, size);
runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true);
} else {
buffer.ImmediateUpload(0, draw_state.inline_index_draw_indexes);
@@ -1519,7 +1560,7 @@ template ::MappedUploadMemory([[maybe_unused]] Buffer& buffer,
[[maybe_unused]] u64 total_size_bytes,
[[maybe_unused]] std::span ::MappedUploadMemory([[maybe_unused]] Buffer& buffer,
// Apply the staging offset
copy.src_offset += upload_staging.offset;
}
+ StagingFlushRange(upload_staging, upload_staging.offset, total_size_bytes);
const bool can_reorder = runtime.CanReorderUpload(buffer, copies);
runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder);
}
@@ -1572,6 +1614,7 @@ void BufferCache ::InlineMemoryImplementation(DAddr dest_address, size_t copy_
}};
u8* const src_pointer = upload_staging.mapped_span.data();
std::memcpy(src_pointer, inlined_buffer.data(), copy_size);
+ StagingFlushRange(upload_staging, upload_staging.offset, copy_size);
const bool can_reorder = runtime.CanReorderUpload(buffer, copies);
runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder);
} else {
@@ -1626,6 +1669,7 @@ void BufferCache ::DownloadBufferMemory(Buffer& buffer, DAddr device_addr, u64
}
runtime.CopyBuffer(download_staging.buffer, buffer, copies_span, true);
runtime.Finish();
+ StagingInvalidateRange(download_staging, download_staging.offset, total_size_bytes);
for (const BufferCopy& copy : copies) {
const DAddr copy_device_addr = buffer.CpuAddr() + copy.src_offset;
// Undo the modified offset
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 2c807b9c69..45033ba6d4 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -194,6 +194,7 @@ public:
}
if (!host_visible) {
+ staging.FlushRange(staging.offset, static_cast ::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManager& device_memory_)
: runtime{runtime_}, device_memory{device_memory_} {
@@ -111,6 +149,7 @@ void TextureCache ::RunGarbageCollector() {
const auto copies = FullDownloadCopies(image.info);
image.DownloadMemory(map, copies);
runtime.Finish();
+ StagingInvalidateRange(map, map.offset, image.unswizzled_size_bytes);
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span,
swizzle_data_buffer);
}
@@ -567,6 +606,7 @@ void TextureCache ::DownloadMemory(DAddr cpu_addr, size_t size) {
const auto copies = FullDownloadCopies(image.info);
image.DownloadMemory(map, copies);
runtime.Finish();
+ StagingInvalidateRange(map, map.offset, image.unswizzled_size_bytes);
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span,
swizzle_data_buffer);
}
@@ -863,13 +903,17 @@ void TextureCache ::PopAsyncFlushes() {
if (download_info.is_swizzle) {
const ImageBase& image = slot_images[download_info.object_id];
const auto copies = FullDownloadCopies(image.info);
- download_buffer.offset -= Common::AlignUp(image.unswizzled_size_bytes, 64);
+ const size_t aligned_size =
+ Common::AlignUp(image.unswizzled_size_bytes, static_cast ::PopAsyncFlushes() {
}
// Wait for downloads to finish
runtime.Finish();
+ StagingInvalidateRange(download_map, original_offset, total_size_bytes);
download_map.offset = original_offset;
std::span ::UploadImageContents(Image& image, StagingBuffer& staging)
if (True(image.flags & ImageFlagBits::AcceleratedUpload)) {
gpu_memory->ReadBlock(gpu_addr, mapped_span.data(), mapped_span.size_bytes(),
VideoCommon::CacheType::NoTextureCache);
+ StagingFlushRange(staging, staging.offset, mapped_span.size_bytes());
const auto uploads = FullUploadSwizzles(image.info);
runtime.AccelerateImageUpload(image, staging, uploads);
return;
@@ -1094,10 +1140,12 @@ void TextureCache ::UploadImageContents(Image& image, StagingBuffer& staging)
auto copies =
UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data, unswizzle_data_buffer);
ConvertImage(unswizzle_data_buffer, image.info, mapped_span, copies);
+ StagingFlushRange(staging, staging.offset, mapped_span.size_bytes());
image.UploadMemory(staging, copies);
} else {
const auto copies =
UnswizzleImage(*gpu_memory, gpu_addr, image.info, swizzle_data, mapped_span);
+ StagingFlushRange(staging, staging.offset, mapped_span.size_bytes());
image.UploadMemory(staging, copies);
}
}
@@ -1329,6 +1377,7 @@ void TextureCache ::TickAsyncDecode() {
auto staging = runtime.UploadStagingBuffer(MapSizeBytes(image));
std::memcpy(staging.mapped_span.data(), async_decode->decoded_data.data(),
async_decode->decoded_data.size());
+ StagingFlushRange(staging, staging.offset, async_decode->decoded_data.size());
image.UploadMemory(staging, async_decode->copies);
image.flags &= ~ImageFlagBits::IsDecoding;
has_uploads = true;
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index f8fbc0c206..77534776cf 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -509,8 +509,12 @@ void Buffer::FlushRange(VkDeviceSize offset, VkDeviceSize size) const {
}
void Buffer::Invalidate() const {
+ InvalidateRange(0, VK_WHOLE_SIZE);
+}
+
+void Buffer::InvalidateRange(VkDeviceSize offset, VkDeviceSize size) const {
if (!is_coherent) {
- vmaInvalidateAllocation(allocator, allocation, 0, VK_WHOLE_SIZE);
+ vmaInvalidateAllocation(allocator, allocation, offset, size);
}
}
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 625dc32fa8..7541a08e7f 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -783,6 +783,8 @@ public:
void Invalidate() const;
+ void InvalidateRange(VkDeviceSize offset, VkDeviceSize size) const;
+
void SetObjectNameEXT(const char* name) const;
private: