diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 2d3934468a..51aedac099 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2078,17 +2078,25 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, return; } - scheduler->RequestOutsideRenderPassOperationContext(); auto vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); const VkBuffer src_buffer = buffer; const VkImage vk_image = *original_image; const VkImageAspectFlags vk_aspect_mask = aspect_mask; const bool was_initialized = std::exchange(initialized, true); - scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized, - vk_copies](vk::CommandBuffer cmdbuf) { + auto copy = [src_buffer, vk_image, vk_aspect_mask, was_initialized, + vk_copies](vk::CommandBuffer cmdbuf) { CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, VideoCommon::FixSmallVectorADL(vk_copies)); - }); + }; + if (True(flags & ImageFlagBits::ReorderableUpload)) { + scheduler->RecordWithUploadBuffer( + [copy = std::move(copy)](vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) { + copy(upload_cmdbuf); + }); + } else { + scheduler->RequestOutsideRenderPassOperationContext(); + scheduler->Record(std::move(copy)); + } if (is_rescaled) { ScaleUp(); diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 9e0a293962..3c597a7f1d 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -45,6 +45,7 @@ enum class ImageFlagBits : u32 { AsynchronousDecode = 1 << 16, IsDecoding = 1 << 17, ///< Is currently being decoded asynchronously. + ReorderableUpload = 1 << 18, }; DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 46cead4c35..a38fbd4dbc 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1471,8 +1471,9 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA DeleteImage(overlap_id); } - // TODO: Only upload what we need + new_image.flags |= ImageFlagBits::ReorderableUpload; RefreshContents(new_image, new_image_id); + new_image.flags &= ~ImageFlagBits::ReorderableUpload; if (can_rescale) { ScaleUp(new_image);