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
::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
PrepareImage(src_id, false, false);
PrepareImage(dst_id, true, false);
- ImageBase& dst_image = slot_images[dst_id];
- const ImageBase& src_image = slot_images[src_id];
+ Image& dst_image = slot_images[dst_id];
+ const Image& src_image = slot_images[src_id];
+
+ const bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
+
+ if (is_src_rescaled && !is_dst_rescaled) {
+ if (ImageCanRescale(dst_image)) {
+ is_dst_rescaled = dst_image.ScaleUp();
+ }
+ }
+
+ const auto& resolution = Settings::values.resolution_info;
+ const auto scale_up = [&](u32 value) -> u32 {
+ if (value == 0) {
+ return 0U;
+ }
+ return std::max ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range);
const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info);
const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples);
- const Region2D src_region{
+ Region2D src_region{
Offset2D{.x = copy.src_x0 >> src_samples_x, .y = copy.src_y0 >> src_samples_y},
Offset2D{.x = copy.src_x1 >> src_samples_x, .y = copy.src_y1 >> src_samples_y},
};
+ if (is_src_rescaled) {
+ scale_region(src_region);
+ }
const std::optional dst_base = dst_image.TryFindBase(dst.Address());
const SubresourceRange dst_range{.base = dst_base.value(), .extent = {1, 1}};
const ImageViewInfo dst_view_info(ImageViewType::e2D, images.dst_format, dst_range);
const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info);
const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples);
- const Region2D dst_region{
+ Region2D dst_region{
Offset2D{.x = copy.dst_x0 >> dst_samples_x, .y = copy.dst_y0 >> dst_samples_y},
Offset2D{.x = copy.dst_x1 >> dst_samples_x, .y = copy.dst_y1 >> dst_samples_y},
};
+ if (is_dst_rescaled) {
+ scale_region(dst_region);
+ }
// Always call this after src_framebuffer_id was queried, as the address might be invalidated.
Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id];
@@ -1514,18 +1544,28 @@ void TextureCache ::MarkModification(ImageBase& image) noexcept {
template ::SynchronizeAliases(ImageId image_id) {
boost::container::small_vector ::SynchronizeAliases(ImageId image_id) {
return lhs_image.modification_tick < rhs_image.modification_tick;
});
for (const AliasedImage* const aliased : aliased_images) {
+ if (any_rescaled) {
+ Image& aliased_image = slot_images[aliased->id];
+ if (can_rescale) {
+ ScaleUp(aliased_image);
+ } else {
+ ScaleDown(aliased_image);
+ }
+ }
CopyImage(image_id, aliased->id, aliased->copies);
}
}