diff options
| author | 2021-07-20 22:51:25 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:27 +0100 | |
| commit | 8704c939136e88876d65fc670bce98d8250a6588 (patch) | |
| tree | ed72be40d7eab387067678e32b285e9e5902f516 /src/video_core/texture_cache | |
| parent | TextureCache: Modify Viewports/Scissors according to Rescale. (diff) | |
| download | yuzu-8704c939136e88876d65fc670bce98d8250a6588.tar.gz yuzu-8704c939136e88876d65fc670bce98d8250a6588.tar.xz yuzu-8704c939136e88876d65fc670bce98d8250a6588.zip | |
TextureCache: Fix rescaling of ImageCopies
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 43 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
2 files changed, 40 insertions, 5 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 4e5031acc..df697cdeb 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -929,8 +929,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 929 | LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented"); | 929 | LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented"); |
| 930 | } else { | 930 | } else { |
| 931 | const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); | 931 | const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); |
| 932 | const auto copies = MakeShrinkImageCopies(new_info, overlap.info, base); | 932 | auto copies = MakeShrinkImageCopies(new_info, overlap.info, base); |
| 933 | runtime.CopyImage(new_image, overlap, copies); | 933 | runtime.CopyImage(new_image, overlap, std::move(copies)); |
| 934 | } | 934 | } |
| 935 | if (True(overlap.flags & ImageFlagBits::Tracked)) { | 935 | if (True(overlap.flags & ImageFlagBits::Tracked)) { |
| 936 | UntrackImage(overlap, overlap_id); | 936 | UntrackImage(overlap, overlap_id); |
| @@ -1569,9 +1569,33 @@ void TextureCache<P>::PrepareImageView(ImageViewId image_view_id, bool is_modifi | |||
| 1569 | } | 1569 | } |
| 1570 | 1570 | ||
| 1571 | template <class P> | 1571 | template <class P> |
| 1572 | void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies) { | 1572 | void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<ImageCopy> copies) { |
| 1573 | Image& dst = slot_images[dst_id]; | 1573 | Image& dst = slot_images[dst_id]; |
| 1574 | Image& src = slot_images[src_id]; | 1574 | Image& src = slot_images[src_id]; |
| 1575 | const bool is_rescaled = True(src.flags & ImageFlagBits::Rescaled); | ||
| 1576 | if (is_rescaled) { | ||
| 1577 | ASSERT(True(dst.flags & ImageFlagBits::Rescaled)); | ||
| 1578 | const bool both_2d{src.info.type == ImageType::e2D && dst.info.type == ImageType::e2D}; | ||
| 1579 | const auto& resolution = Settings::values.resolution_info; | ||
| 1580 | const auto scale_up = [&](u32 value) -> u32 { | ||
| 1581 | if (value == 0) { | ||
| 1582 | return 0U; | ||
| 1583 | } | ||
| 1584 | return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U); | ||
| 1585 | }; | ||
| 1586 | for (auto& copy : copies) { | ||
| 1587 | copy.src_offset.x = scale_up(copy.src_offset.x); | ||
| 1588 | |||
| 1589 | copy.dst_offset.x = scale_up(copy.dst_offset.x); | ||
| 1590 | |||
| 1591 | copy.extent.width = scale_up(copy.extent.width); | ||
| 1592 | if (both_2d) { | ||
| 1593 | copy.src_offset.y = scale_up(copy.src_offset.y); | ||
| 1594 | copy.dst_offset.y = scale_up(copy.dst_offset.y); | ||
| 1595 | copy.extent.height = scale_up(copy.extent.height); | ||
| 1596 | } | ||
| 1597 | } | ||
| 1598 | } | ||
| 1575 | const auto dst_format_type = GetFormatType(dst.info.format); | 1599 | const auto dst_format_type = GetFormatType(dst.info.format); |
| 1576 | const auto src_format_type = GetFormatType(src.info.format); | 1600 | const auto src_format_type = GetFormatType(src.info.format); |
| 1577 | if (src_format_type == dst_format_type) { | 1601 | if (src_format_type == dst_format_type) { |
| @@ -1639,10 +1663,21 @@ std::pair<FramebufferId, ImageViewId> TextureCache<P>::RenderTargetFromImage( | |||
| 1639 | ImageId image_id, const ImageViewInfo& view_info) { | 1663 | ImageId image_id, const ImageViewInfo& view_info) { |
| 1640 | const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info); | 1664 | const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info); |
| 1641 | const ImageBase& image = slot_images[image_id]; | 1665 | const ImageBase& image = slot_images[image_id]; |
| 1666 | const bool is_rescaled = True(image.flags & ImageFlagBits::Rescaled); | ||
| 1642 | const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture; | 1667 | const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture; |
| 1643 | const ImageViewId color_view_id = is_color ? view_id : ImageViewId{}; | 1668 | const ImageViewId color_view_id = is_color ? view_id : ImageViewId{}; |
| 1644 | const ImageViewId depth_view_id = is_color ? ImageViewId{} : view_id; | 1669 | const ImageViewId depth_view_id = is_color ? ImageViewId{} : view_id; |
| 1645 | const Extent3D extent = MipSize(image.info.size, view_info.range.base.level); | 1670 | Extent3D extent = MipSize(image.info.size, view_info.range.base.level); |
| 1671 | if (is_rescaled) { | ||
| 1672 | const auto& resolution = Settings::values.resolution_info; | ||
| 1673 | const auto scale_up = [&](u32 value) { | ||
| 1674 | return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U); | ||
| 1675 | }; | ||
| 1676 | extent.width = scale_up(extent.width); | ||
| 1677 | if (image.info.type == ImageType::e2D) { | ||
| 1678 | extent.height = scale_up(extent.height); | ||
| 1679 | } | ||
| 1680 | } | ||
| 1646 | const u32 num_samples = image.info.num_samples; | 1681 | const u32 num_samples = image.info.num_samples; |
| 1647 | const auto [samples_x, samples_y] = SamplesLog2(num_samples); | 1682 | const auto [samples_x, samples_y] = SamplesLog2(num_samples); |
| 1648 | const FramebufferId framebuffer_id = GetFramebufferId(RenderTargets{ | 1683 | const FramebufferId framebuffer_id = GetFramebufferId(RenderTargets{ |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 1f51fcee8..deddf0d30 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -316,7 +316,7 @@ private: | |||
| 316 | void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate); | 316 | void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate); |
| 317 | 317 | ||
| 318 | /// Execute copies from one image to the other, even if they are incompatible | 318 | /// Execute copies from one image to the other, even if they are incompatible |
| 319 | void CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies); | 319 | void CopyImage(ImageId dst_id, ImageId src_id, std::vector<ImageCopy> copies); |
| 320 | 320 | ||
| 321 | /// Bind an image view as render target, downloading resources preemtively if needed | 321 | /// Bind an image view as render target, downloading resources preemtively if needed |
| 322 | void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id); | 322 | void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id); |