summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-07-21 10:15:09 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:27 +0100
commitdfc65cd0a3b259588b47db1d32c827e7fc071aeb (patch)
treefa25b28557bca987764b4eb9672812b8748a8670
parentFix blits with mips (diff)
downloadyuzu-dfc65cd0a3b259588b47db1d32c827e7fc071aeb.tar.gz
yuzu-dfc65cd0a3b259588b47db1d32c827e7fc071aeb.tar.xz
yuzu-dfc65cd0a3b259588b47db1d32c827e7fc071aeb.zip
Texture Cache: Implement Rescaling on Aliases and Blits.
Diffstat (limited to '')
-rw-r--r--src/video_core/texture_cache/texture_cache.h58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index df697cdeb..25fea8240 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -437,8 +437,32 @@ void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
437 PrepareImage(src_id, false, false); 437 PrepareImage(src_id, false, false);
438 PrepareImage(dst_id, true, false); 438 PrepareImage(dst_id, true, false);
439 439
440 ImageBase& dst_image = slot_images[dst_id]; 440 Image& dst_image = slot_images[dst_id];
441 const ImageBase& src_image = slot_images[src_id]; 441 const Image& src_image = slot_images[src_id];
442
443 const bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
444 bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
445
446 if (is_src_rescaled && !is_dst_rescaled) {
447 if (ImageCanRescale(dst_image)) {
448 is_dst_rescaled = dst_image.ScaleUp();
449 }
450 }
451
452 const auto& resolution = Settings::values.resolution_info;
453 const auto scale_up = [&](u32 value) -> u32 {
454 if (value == 0) {
455 return 0U;
456 }
457 return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
458 };
459
460 const auto scale_region = [&](Region2D& region) {
461 region.start.x = scale_up(region.start.x);
462 region.start.y = scale_up(region.start.y);
463 region.end.x = scale_up(region.end.x);
464 region.end.y = scale_up(region.end.y);
465 };
442 466
443 // TODO: Deduplicate 467 // TODO: Deduplicate
444 const std::optional src_base = src_image.TryFindBase(src.Address()); 468 const std::optional src_base = src_image.TryFindBase(src.Address());
@@ -446,20 +470,26 @@ void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
446 const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range); 470 const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range);
447 const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info); 471 const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info);
448 const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples); 472 const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples);
449 const Region2D src_region{ 473 Region2D src_region{
450 Offset2D{.x = copy.src_x0 >> src_samples_x, .y = copy.src_y0 >> src_samples_y}, 474 Offset2D{.x = copy.src_x0 >> src_samples_x, .y = copy.src_y0 >> src_samples_y},
451 Offset2D{.x = copy.src_x1 >> src_samples_x, .y = copy.src_y1 >> src_samples_y}, 475 Offset2D{.x = copy.src_x1 >> src_samples_x, .y = copy.src_y1 >> src_samples_y},
452 }; 476 };
477 if (is_src_rescaled) {
478 scale_region(src_region);
479 }
453 480
454 const std::optional dst_base = dst_image.TryFindBase(dst.Address()); 481 const std::optional dst_base = dst_image.TryFindBase(dst.Address());
455 const SubresourceRange dst_range{.base = dst_base.value(), .extent = {1, 1}}; 482 const SubresourceRange dst_range{.base = dst_base.value(), .extent = {1, 1}};
456 const ImageViewInfo dst_view_info(ImageViewType::e2D, images.dst_format, dst_range); 483 const ImageViewInfo dst_view_info(ImageViewType::e2D, images.dst_format, dst_range);
457 const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info); 484 const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info);
458 const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples); 485 const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples);
459 const Region2D dst_region{ 486 Region2D dst_region{
460 Offset2D{.x = copy.dst_x0 >> dst_samples_x, .y = copy.dst_y0 >> dst_samples_y}, 487 Offset2D{.x = copy.dst_x0 >> dst_samples_x, .y = copy.dst_y0 >> dst_samples_y},
461 Offset2D{.x = copy.dst_x1 >> dst_samples_x, .y = copy.dst_y1 >> dst_samples_y}, 488 Offset2D{.x = copy.dst_x1 >> dst_samples_x, .y = copy.dst_y1 >> dst_samples_y},
462 }; 489 };
490 if (is_dst_rescaled) {
491 scale_region(dst_region);
492 }
463 493
464 // Always call this after src_framebuffer_id was queried, as the address might be invalidated. 494 // Always call this after src_framebuffer_id was queried, as the address might be invalidated.
465 Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id]; 495 Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id];
@@ -1514,18 +1544,28 @@ void TextureCache<P>::MarkModification(ImageBase& image) noexcept {
1514template <class P> 1544template <class P>
1515void TextureCache<P>::SynchronizeAliases(ImageId image_id) { 1545void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
1516 boost::container::small_vector<const AliasedImage*, 1> aliased_images; 1546 boost::container::small_vector<const AliasedImage*, 1> aliased_images;
1517 ImageBase& image = slot_images[image_id]; 1547 Image& image = slot_images[image_id];
1548 bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled);
1518 u64 most_recent_tick = image.modification_tick; 1549 u64 most_recent_tick = image.modification_tick;
1519 for (const AliasedImage& aliased : image.aliased_images) { 1550 for (const AliasedImage& aliased : image.aliased_images) {
1520 ImageBase& aliased_image = slot_images[aliased.id]; 1551 ImageBase& aliased_image = slot_images[aliased.id];
1521 if (image.modification_tick < aliased_image.modification_tick) { 1552 if (image.modification_tick < aliased_image.modification_tick) {
1522 most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick); 1553 most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick);
1523 aliased_images.push_back(&aliased); 1554 aliased_images.push_back(&aliased);
1555 any_rescaled |= True(image.flags & ImageFlagBits::Rescaled);
1524 } 1556 }
1525 } 1557 }
1526 if (aliased_images.empty()) { 1558 if (aliased_images.empty()) {
1527 return; 1559 return;
1528 } 1560 }
1561 const bool can_rescale = ImageCanRescale(image);
1562 if (any_rescaled) {
1563 if (can_rescale) {
1564 ScaleUp(image);
1565 } else {
1566 ScaleDown(image);
1567 }
1568 }
1529 image.modification_tick = most_recent_tick; 1569 image.modification_tick = most_recent_tick;
1530 std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) { 1570 std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) {
1531 const ImageBase& lhs_image = slot_images[lhs->id]; 1571 const ImageBase& lhs_image = slot_images[lhs->id];
@@ -1533,6 +1573,14 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
1533 return lhs_image.modification_tick < rhs_image.modification_tick; 1573 return lhs_image.modification_tick < rhs_image.modification_tick;
1534 }); 1574 });
1535 for (const AliasedImage* const aliased : aliased_images) { 1575 for (const AliasedImage* const aliased : aliased_images) {
1576 if (any_rescaled) {
1577 Image& aliased_image = slot_images[aliased->id];
1578 if (can_rescale) {
1579 ScaleUp(aliased_image);
1580 } else {
1581 ScaleDown(aliased_image);
1582 }
1583 }
1536 CopyImage(image_id, aliased->id, aliased->copies); 1584 CopyImage(image_id, aliased->id, aliased->copies);
1537 } 1585 }
1538} 1586}