diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 41 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 7 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 12 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 6 |
8 files changed, 75 insertions, 41 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 90e35e307..2de533584 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -1299,7 +1299,7 @@ bool AccelerateDMA::DmaBufferImageCopy(const Tegra::DMA::ImageCopy& copy_info, | |||
| 1299 | if constexpr (IS_IMAGE_UPLOAD) { | 1299 | if constexpr (IS_IMAGE_UPLOAD) { |
| 1300 | image->UploadMemory(buffer->Handle(), offset, copy_span); | 1300 | image->UploadMemory(buffer->Handle(), offset, copy_span); |
| 1301 | } else { | 1301 | } else { |
| 1302 | image->DownloadMemory(buffer->Handle(), offset, copy_span); | 1302 | texture_cache.DownloadImageIntoBuffer(image, buffer->Handle(), offset, copy_span); |
| 1303 | } | 1303 | } |
| 1304 | return true; | 1304 | return true; |
| 1305 | } | 1305 | } |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 0b9c4a904..670d8cafd 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -801,32 +801,34 @@ void Image::UploadMemory(const ImageBufferMap& map, | |||
| 801 | UploadMemory(map.buffer, map.offset, copies); | 801 | UploadMemory(map.buffer, map.offset, copies); |
| 802 | } | 802 | } |
| 803 | 803 | ||
| 804 | void Image::DownloadMemory(GLuint buffer_handle, size_t buffer_offset, | 804 | void Image::DownloadMemory(std::span<GLuint> buffer_handles, size_t buffer_offset, |
| 805 | std::span<const VideoCommon::BufferImageCopy> copies) { | 805 | std::span<const VideoCommon::BufferImageCopy> copies) { |
| 806 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 806 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 807 | if (is_rescaled) { | 807 | if (is_rescaled) { |
| 808 | ScaleDown(); | 808 | ScaleDown(); |
| 809 | } | 809 | } |
| 810 | glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API | 810 | glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API |
| 811 | glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer_handle); | 811 | for (auto buffer_handle : buffer_handles) { |
| 812 | glPixelStorei(GL_PACK_ALIGNMENT, 1); | 812 | glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer_handle); |
| 813 | glPixelStorei(GL_PACK_ALIGNMENT, 1); | ||
| 813 | 814 | ||
| 814 | u32 current_row_length = std::numeric_limits<u32>::max(); | 815 | u32 current_row_length = std::numeric_limits<u32>::max(); |
| 815 | u32 current_image_height = std::numeric_limits<u32>::max(); | 816 | u32 current_image_height = std::numeric_limits<u32>::max(); |
| 816 | 817 | ||
| 817 | for (const VideoCommon::BufferImageCopy& copy : copies) { | 818 | for (const VideoCommon::BufferImageCopy& copy : copies) { |
| 818 | if (copy.image_subresource.base_level >= gl_num_levels) { | 819 | if (copy.image_subresource.base_level >= gl_num_levels) { |
| 819 | continue; | 820 | continue; |
| 820 | } | 821 | } |
| 821 | if (current_row_length != copy.buffer_row_length) { | 822 | if (current_row_length != copy.buffer_row_length) { |
| 822 | current_row_length = copy.buffer_row_length; | 823 | current_row_length = copy.buffer_row_length; |
| 823 | glPixelStorei(GL_PACK_ROW_LENGTH, current_row_length); | 824 | glPixelStorei(GL_PACK_ROW_LENGTH, current_row_length); |
| 824 | } | 825 | } |
| 825 | if (current_image_height != copy.buffer_image_height) { | 826 | if (current_image_height != copy.buffer_image_height) { |
| 826 | current_image_height = copy.buffer_image_height; | 827 | current_image_height = copy.buffer_image_height; |
| 827 | glPixelStorei(GL_PACK_IMAGE_HEIGHT, current_image_height); | 828 | glPixelStorei(GL_PACK_IMAGE_HEIGHT, current_image_height); |
| 829 | } | ||
| 830 | CopyImageToBuffer(copy, buffer_offset); | ||
| 828 | } | 831 | } |
| 829 | CopyImageToBuffer(copy, buffer_offset); | ||
| 830 | } | 832 | } |
| 831 | if (is_rescaled) { | 833 | if (is_rescaled) { |
| 832 | ScaleUp(true); | 834 | ScaleUp(true); |
| @@ -835,7 +837,10 @@ void Image::DownloadMemory(GLuint buffer_handle, size_t buffer_offset, | |||
| 835 | 837 | ||
| 836 | void Image::DownloadMemory(ImageBufferMap& map, | 838 | void Image::DownloadMemory(ImageBufferMap& map, |
| 837 | std::span<const VideoCommon::BufferImageCopy> copies) { | 839 | std::span<const VideoCommon::BufferImageCopy> copies) { |
| 838 | DownloadMemory(map.buffer, map.offset, copies); | 840 | std::array buffers{ |
| 841 | map.buffer, | ||
| 842 | }; | ||
| 843 | DownloadMemory(buffers, map.offset, copies); | ||
| 839 | } | 844 | } |
| 840 | 845 | ||
| 841 | GLuint Image::StorageHandle() noexcept { | 846 | GLuint Image::StorageHandle() noexcept { |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 911e4607a..67d6910b4 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -212,7 +212,7 @@ public: | |||
| 212 | void UploadMemory(const ImageBufferMap& map, | 212 | void UploadMemory(const ImageBufferMap& map, |
| 213 | std::span<const VideoCommon::BufferImageCopy> copies); | 213 | std::span<const VideoCommon::BufferImageCopy> copies); |
| 214 | 214 | ||
| 215 | void DownloadMemory(GLuint buffer_handle, size_t buffer_offset, | 215 | void DownloadMemory(std::span<GLuint> buffer_handle, size_t buffer_offset, |
| 216 | std::span<const VideoCommon::BufferImageCopy> copies); | 216 | std::span<const VideoCommon::BufferImageCopy> copies); |
| 217 | 217 | ||
| 218 | void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies); | 218 | void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies); |
| @@ -376,6 +376,7 @@ struct TextureCacheParams { | |||
| 376 | using Sampler = OpenGL::Sampler; | 376 | using Sampler = OpenGL::Sampler; |
| 377 | using Framebuffer = OpenGL::Framebuffer; | 377 | using Framebuffer = OpenGL::Framebuffer; |
| 378 | using AsyncBuffer = u32; | 378 | using AsyncBuffer = u32; |
| 379 | using BufferType = GLuint; | ||
| 379 | }; | 380 | }; |
| 380 | 381 | ||
| 381 | using TextureCache = VideoCommon::TextureCache<TextureCacheParams>; | 382 | using TextureCache = VideoCommon::TextureCache<TextureCacheParams>; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 673ab478e..8fc783cc0 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -793,7 +793,7 @@ bool AccelerateDMA::DmaBufferImageCopy(const Tegra::DMA::ImageCopy& copy_info, | |||
| 793 | if constexpr (IS_IMAGE_UPLOAD) { | 793 | if constexpr (IS_IMAGE_UPLOAD) { |
| 794 | image->UploadMemory(buffer->Handle(), offset, copy_span); | 794 | image->UploadMemory(buffer->Handle(), offset, copy_span); |
| 795 | } else { | 795 | } else { |
| 796 | image->DownloadMemory(buffer->Handle(), offset, copy_span); | 796 | texture_cache.DownloadImageIntoBuffer(image, buffer->Handle(), offset, copy_span); |
| 797 | } | 797 | } |
| 798 | return true; | 798 | return true; |
| 799 | } | 799 | } |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index ae15f6976..e4d077e63 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | 4 | #include <algorithm> |
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <span> | 6 | #include <span> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include <boost/container/small_vector.hpp> | ||
| 8 | 9 | ||
| 9 | #include "common/bit_cast.h" | 10 | #include "common/bit_cast.h" |
| 10 | #include "common/bit_util.h" | 11 | #include "common/bit_util.h" |
| @@ -1341,16 +1342,20 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag | |||
| 1341 | UploadMemory(map.buffer, map.offset, copies); | 1342 | UploadMemory(map.buffer, map.offset, copies); |
| 1342 | } | 1343 | } |
| 1343 | 1344 | ||
| 1344 | void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, | 1345 | void Image::DownloadMemory(std::span<VkBuffer> buffers_span, VkDeviceSize offset, |
| 1345 | std::span<const VideoCommon::BufferImageCopy> copies) { | 1346 | std::span<const VideoCommon::BufferImageCopy> copies) { |
| 1346 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 1347 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 1347 | if (is_rescaled) { | 1348 | if (is_rescaled) { |
| 1348 | ScaleDown(); | 1349 | ScaleDown(); |
| 1349 | } | 1350 | } |
| 1351 | boost::container::small_vector<VkBuffer, 1> buffers_vector{}; | ||
| 1352 | for (auto& buffer : buffers_span) { | ||
| 1353 | buffers_vector.push_back(buffer); | ||
| 1354 | } | ||
| 1350 | std::vector vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); | 1355 | std::vector vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); |
| 1351 | scheduler->RequestOutsideRenderPassOperationContext(); | 1356 | scheduler->RequestOutsideRenderPassOperationContext(); |
| 1352 | scheduler->Record([buffer, image = *original_image, aspect_mask = aspect_mask, | 1357 | scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, |
| 1353 | vk_copies](vk::CommandBuffer cmdbuf) { | 1358 | aspect_mask = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { |
| 1354 | const VkImageMemoryBarrier read_barrier{ | 1359 | const VkImageMemoryBarrier read_barrier{ |
| 1355 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | 1360 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
| 1356 | .pNext = nullptr, | 1361 | .pNext = nullptr, |
| @@ -1369,6 +1374,20 @@ void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, | |||
| 1369 | .layerCount = VK_REMAINING_ARRAY_LAYERS, | 1374 | .layerCount = VK_REMAINING_ARRAY_LAYERS, |
| 1370 | }, | 1375 | }, |
| 1371 | }; | 1376 | }; |
| 1377 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, | ||
| 1378 | 0, read_barrier); | ||
| 1379 | |||
| 1380 | for (auto buffer : buffers) { | ||
| 1381 | cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, | ||
| 1382 | vk_copies); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | const VkMemoryBarrier memory_write_barrier{ | ||
| 1386 | .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | ||
| 1387 | .pNext = nullptr, | ||
| 1388 | .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, | ||
| 1389 | .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, | ||
| 1390 | }; | ||
| 1372 | const VkImageMemoryBarrier image_write_barrier{ | 1391 | const VkImageMemoryBarrier image_write_barrier{ |
| 1373 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | 1392 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
| 1374 | .pNext = nullptr, | 1393 | .pNext = nullptr, |
| @@ -1387,15 +1406,6 @@ void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, | |||
| 1387 | .layerCount = VK_REMAINING_ARRAY_LAYERS, | 1406 | .layerCount = VK_REMAINING_ARRAY_LAYERS, |
| 1388 | }, | 1407 | }, |
| 1389 | }; | 1408 | }; |
| 1390 | const VkMemoryBarrier memory_write_barrier{ | ||
| 1391 | .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | ||
| 1392 | .pNext = nullptr, | ||
| 1393 | .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, | ||
| 1394 | .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, | ||
| 1395 | }; | ||
| 1396 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, | ||
| 1397 | 0, read_barrier); | ||
| 1398 | cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, vk_copies); | ||
| 1399 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 1409 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
| 1400 | 0, memory_write_barrier, nullptr, image_write_barrier); | 1410 | 0, memory_write_barrier, nullptr, image_write_barrier); |
| 1401 | }); | 1411 | }); |
| @@ -1405,7 +1415,10 @@ void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, | |||
| 1405 | } | 1415 | } |
| 1406 | 1416 | ||
| 1407 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { | 1417 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { |
| 1408 | DownloadMemory(map.buffer, map.offset, copies); | 1418 | std::array buffers{ |
| 1419 | map.buffer, | ||
| 1420 | }; | ||
| 1421 | DownloadMemory(buffers, map.offset, copies); | ||
| 1409 | } | 1422 | } |
| 1410 | 1423 | ||
| 1411 | bool Image::IsRescaled() const noexcept { | 1424 | bool Image::IsRescaled() const noexcept { |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index d5ee23f8d..422476188 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| @@ -138,7 +138,7 @@ public: | |||
| 138 | void UploadMemory(const StagingBufferRef& map, | 138 | void UploadMemory(const StagingBufferRef& map, |
| 139 | std::span<const VideoCommon::BufferImageCopy> copies); | 139 | std::span<const VideoCommon::BufferImageCopy> copies); |
| 140 | 140 | ||
| 141 | void DownloadMemory(VkBuffer buffer, VkDeviceSize offset, | 141 | void DownloadMemory(std::span<VkBuffer> buffers, VkDeviceSize offset, |
| 142 | std::span<const VideoCommon::BufferImageCopy> copies); | 142 | std::span<const VideoCommon::BufferImageCopy> copies); |
| 143 | 143 | ||
| 144 | void DownloadMemory(const StagingBufferRef& map, | 144 | void DownloadMemory(const StagingBufferRef& map, |
| @@ -371,6 +371,7 @@ struct TextureCacheParams { | |||
| 371 | using Sampler = Vulkan::Sampler; | 371 | using Sampler = Vulkan::Sampler; |
| 372 | using Framebuffer = Vulkan::Framebuffer; | 372 | using Framebuffer = Vulkan::Framebuffer; |
| 373 | using AsyncBuffer = Vulkan::StagingBufferRef; | 373 | using AsyncBuffer = Vulkan::StagingBufferRef; |
| 374 | using BufferType = VkBuffer; | ||
| 374 | }; | 375 | }; |
| 375 | 376 | ||
| 376 | using TextureCache = VideoCommon::TextureCache<TextureCacheParams>; | 377 | using TextureCache = VideoCommon::TextureCache<TextureCacheParams>; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index ed5c768d8..2cd5aa31e 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| @@ -834,6 +834,16 @@ std::pair<typename TextureCache<P>::Image*, BufferImageCopy> TextureCache<P>::Dm | |||
| 834 | } | 834 | } |
| 835 | 835 | ||
| 836 | template <class P> | 836 | template <class P> |
| 837 | void TextureCache<P>::DownloadImageIntoBuffer( | ||
| 838 | typename TextureCache<P>::Image* image, typename TextureCache<P>::BufferType buffer, | ||
| 839 | size_t buffer_offset, std::span<const VideoCommon::BufferImageCopy> copies) { | ||
| 840 | std::array buffers{ | ||
| 841 | buffer, | ||
| 842 | }; | ||
| 843 | image->DownloadMemory(buffers, buffer_offset, copies); | ||
| 844 | } | ||
| 845 | |||
| 846 | template <class P> | ||
| 837 | void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) { | 847 | void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) { |
| 838 | if (False(image.flags & ImageFlagBits::CpuModified)) { | 848 | if (False(image.flags & ImageFlagBits::CpuModified)) { |
| 839 | // Only upload modified images | 849 | // Only upload modified images |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 5a5b4179c..51f44aed5 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| @@ -119,6 +119,7 @@ class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelI | |||
| 119 | using Sampler = typename P::Sampler; | 119 | using Sampler = typename P::Sampler; |
| 120 | using Framebuffer = typename P::Framebuffer; | 120 | using Framebuffer = typename P::Framebuffer; |
| 121 | using AsyncBuffer = typename P::AsyncBuffer; | 121 | using AsyncBuffer = typename P::AsyncBuffer; |
| 122 | using BufferType = typename P::BufferType; | ||
| 122 | 123 | ||
| 123 | struct BlitImages { | 124 | struct BlitImages { |
| 124 | ImageId dst_id; | 125 | ImageId dst_id; |
| @@ -215,6 +216,9 @@ public: | |||
| 215 | const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand, | 216 | const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand, |
| 216 | const Tegra::DMA::ImageOperand& image_operand, ImageId image_id, bool modifies_image); | 217 | const Tegra::DMA::ImageOperand& image_operand, ImageId image_id, bool modifies_image); |
| 217 | 218 | ||
| 219 | void DownloadImageIntoBuffer(Image* image, BufferType buffer, size_t buffer_offset, | ||
| 220 | std::span<const VideoCommon::BufferImageCopy> copies); | ||
| 221 | |||
| 218 | /// Return true when a CPU region is modified from the GPU | 222 | /// Return true when a CPU region is modified from the GPU |
| 219 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); | 223 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); |
| 220 | 224 | ||