summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar ameerj2023-03-06 21:16:17 -0500
committerGravatar ameerj2023-03-06 22:57:45 -0500
commit6b9cc0ed23b15a1b96b322b03feff2153e44a4a9 (patch)
tree6949cedbe90b6d34e2092c8eba57b243defb21dc /src/video_core/texture_cache
parentMerge pull request #9890 from Kelebek1/reverb_fix (diff)
downloadyuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.gz
yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.xz
yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.zip
Refactor AccelerateDMA code
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/texture_cache.h86
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h10
2 files changed, 76 insertions, 20 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 335338434..8e8b9a5e6 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -745,6 +745,25 @@ void TextureCache<P>::PopAsyncFlushes() {
745} 745}
746 746
747template <class P> 747template <class P>
748ImageId TextureCache<P>::DmaImageId(const Tegra::DMA::ImageOperand& operand) {
749 const ImageInfo dst_info(operand);
750 const ImageId dst_id = FindDMAImage(dst_info, operand.address);
751 if (!dst_id) {
752 return NULL_IMAGE_ID;
753 }
754 const auto& image = slot_images[dst_id];
755 if (False(image.flags & ImageFlagBits::GpuModified)) {
756 // No need to waste time on an image that's synced with guest
757 return NULL_IMAGE_ID;
758 }
759 const auto base = image.TryFindBase(operand.address);
760 if (!base) {
761 return NULL_IMAGE_ID;
762 }
763 return dst_id;
764}
765
766template <class P>
748bool TextureCache<P>::IsRescaling() const noexcept { 767bool TextureCache<P>::IsRescaling() const noexcept {
749 return is_rescaling; 768 return is_rescaling;
750} 769}
@@ -772,6 +791,49 @@ bool TextureCache<P>::IsRegionGpuModified(VAddr addr, size_t size) {
772} 791}
773 792
774template <class P> 793template <class P>
794std::pair<typename TextureCache<P>::Image*, BufferImageCopy> TextureCache<P>::DmaBufferImageCopy(
795 const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand,
796 const Tegra::DMA::ImageOperand& image_operand, ImageId image_id, bool modifies_image) {
797 const auto [level, base] = PrepareDmaImage(image_id, image_operand.address, modifies_image);
798 auto* image = &slot_images[image_id];
799 const u32 buffer_size = static_cast<u32>(buffer_operand.pitch * buffer_operand.height);
800 const u32 bpp = VideoCore::Surface::BytesPerBlock(image->info.format);
801 const auto convert = [old_bpp = image_operand.bytes_per_pixel, bpp](u32 value) {
802 return (old_bpp * value) / bpp;
803 };
804 const u32 base_x = convert(image_operand.params.origin.x.Value());
805 const u32 base_y = image_operand.params.origin.y.Value();
806 const u32 length_x = convert(copy_info.length_x);
807 const u32 length_y = copy_info.length_y;
808
809 const BufferImageCopy copy{
810 .buffer_offset = 0,
811 .buffer_size = buffer_size,
812 .buffer_row_length = convert(buffer_operand.pitch),
813 .buffer_image_height = buffer_operand.height,
814 .image_subresource =
815 {
816 .base_level = static_cast<s32>(level),
817 .base_layer = static_cast<s32>(base),
818 .num_layers = 1,
819 },
820 .image_offset =
821 {
822 .x = static_cast<s32>(base_x),
823 .y = static_cast<s32>(base_y),
824 .z = 0,
825 },
826 .image_extent =
827 {
828 .width = length_x,
829 .height = length_y,
830 .depth = 1,
831 },
832 };
833 return {image, copy};
834}
835
836template <class P>
775void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) { 837void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
776 if (False(image.flags & ImageFlagBits::CpuModified)) { 838 if (False(image.flags & ImageFlagBits::CpuModified)) {
777 // Only upload modified images 839 // Only upload modified images
@@ -1405,26 +1467,14 @@ ImageId TextureCache<P>::FindDMAImage(const ImageInfo& info, GPUVAddr gpu_addr)
1405} 1467}
1406 1468
1407template <class P> 1469template <class P>
1408std::optional<std::pair<typename TextureCache<P>::Image*, std::pair<u32, u32>>> 1470std::pair<u32, u32> TextureCache<P>::PrepareDmaImage(ImageId dst_id, GPUVAddr base_addr,
1409TextureCache<P>::ObtainImage(const Tegra::DMA::ImageOperand& operand, bool mark_as_modified) { 1471 bool mark_as_modified) {
1410 ImageInfo dst_info(operand); 1472 const auto& image = slot_images[dst_id];
1411 ImageId dst_id = FindDMAImage(dst_info, operand.address); 1473 const auto base = image.TryFindBase(base_addr);
1412 if (!dst_id) {
1413 return std::nullopt;
1414 }
1415 auto& image = slot_images[dst_id];
1416 auto base = image.TryFindBase(operand.address);
1417 if (!base) {
1418 return std::nullopt;
1419 }
1420 if (False(image.flags & ImageFlagBits::GpuModified)) {
1421 // No need to waste time on an image that's synced with guest
1422 return std::nullopt;
1423 }
1424 PrepareImage(dst_id, mark_as_modified, false); 1474 PrepareImage(dst_id, mark_as_modified, false);
1425 auto& new_image = slot_images[dst_id]; 1475 const auto& new_image = slot_images[dst_id];
1426 lru_cache.Touch(new_image.lru_index, frame_tick); 1476 lru_cache.Touch(new_image.lru_index, frame_tick);
1427 return std::make_pair(&new_image, std::make_pair(base->level, base->layer)); 1477 return std::make_pair(base->level, base->layer);
1428} 1478}
1429 1479
1430template <class P> 1480template <class P>
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 848a5d9ea..5a5b4179c 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -209,8 +209,11 @@ public:
209 /// Pop asynchronous downloads 209 /// Pop asynchronous downloads
210 void PopAsyncFlushes(); 210 void PopAsyncFlushes();
211 211
212 [[nodiscard]] std::optional<std::pair<Image*, std::pair<u32, u32>>> ObtainImage( 212 [[nodiscard]] ImageId DmaImageId(const Tegra::DMA::ImageOperand& operand);
213 const Tegra::DMA::ImageOperand& operand, bool mark_as_modified); 213
214 [[nodiscard]] std::pair<Image*, BufferImageCopy> DmaBufferImageCopy(
215 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);
214 217
215 /// Return true when a CPU region is modified from the GPU 218 /// Return true when a CPU region is modified from the GPU
216 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); 219 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
@@ -386,6 +389,9 @@ private:
386 /// Returns true if the current clear parameters clear the whole image of a given image view 389 /// Returns true if the current clear parameters clear the whole image of a given image view
387 [[nodiscard]] bool IsFullClear(ImageViewId id); 390 [[nodiscard]] bool IsFullClear(ImageViewId id);
388 391
392 [[nodiscard]] std::pair<u32, u32> PrepareDmaImage(ImageId dst_id, GPUVAddr base_addr,
393 bool mark_as_modified);
394
389 bool ImageCanRescale(ImageBase& image); 395 bool ImageCanRescale(ImageBase& image);
390 void InvalidateScale(Image& image); 396 void InvalidateScale(Image& image);
391 bool ScaleUp(Image& image); 397 bool ScaleUp(Image& image);