diff options
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 58 |
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 { | |||
| 1514 | template <class P> | 1544 | template <class P> |
| 1515 | void TextureCache<P>::SynchronizeAliases(ImageId image_id) { | 1545 | void 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 | } |