summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/texture_cache/image_base.cpp6
-rw-r--r--src/video_core/texture_cache/image_base.h2
-rw-r--r--src/video_core/texture_cache/image_info.cpp11
-rw-r--r--src/video_core/texture_cache/image_info.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.h42
5 files changed, 47 insertions, 15 deletions
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp
index 6052d148a..e9e725edf 100644
--- a/src/video_core/texture_cache/image_base.cpp
+++ b/src/video_core/texture_cache/image_base.cpp
@@ -60,9 +60,9 @@ namespace {
60ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_) 60ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_)
61 : info{info_}, guest_size_bytes{CalculateGuestSizeInBytes(info)}, 61 : info{info_}, guest_size_bytes{CalculateGuestSizeInBytes(info)},
62 unswizzled_size_bytes{CalculateUnswizzledSizeBytes(info)}, 62 unswizzled_size_bytes{CalculateUnswizzledSizeBytes(info)},
63 converted_size_bytes{CalculateConvertedSizeBytes(info)}, gpu_addr{gpu_addr_}, 63 converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{},
64 cpu_addr{cpu_addr_}, cpu_addr_end{cpu_addr + guest_size_bytes}, 64 scale_tick{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_},
65 mip_level_offsets{CalculateMipLevelOffsets(info)} { 65 cpu_addr_end{cpu_addr + guest_size_bytes}, mip_level_offsets{CalculateMipLevelOffsets(info)} {
66 if (info.type == ImageType::e3D) { 66 if (info.type == ImageType::e3D) {
67 slice_offsets = CalculateSliceOffsets(info); 67 slice_offsets = CalculateSliceOffsets(info);
68 slice_subresources = CalculateSliceSubresources(info); 68 slice_subresources = CalculateSliceSubresources(info);
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 10dd52e28..97f107b4d 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -78,6 +78,8 @@ struct ImageBase {
78 u32 guest_size_bytes = 0; 78 u32 guest_size_bytes = 0;
79 u32 unswizzled_size_bytes = 0; 79 u32 unswizzled_size_bytes = 0;
80 u32 converted_size_bytes = 0; 80 u32 converted_size_bytes = 0;
81 u32 scale_rating = 0;
82 u64 scale_tick = 0;
81 ImageFlagBits flags = ImageFlagBits::CpuModified; 83 ImageFlagBits flags = ImageFlagBits::CpuModified;
82 84
83 GPUVAddr gpu_addr = 0; 85 GPUVAddr gpu_addr = 0;
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 022ca9033..7fa8fd4fe 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -31,6 +31,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
31 .depth = config.block_depth, 31 .depth = config.block_depth,
32 }; 32 };
33 } 33 }
34 rescaleable = false;
34 tile_width_spacing = config.tile_width_spacing; 35 tile_width_spacing = config.tile_width_spacing;
35 if (config.texture_type != TextureType::Texture2D && 36 if (config.texture_type != TextureType::Texture2D &&
36 config.texture_type != TextureType::Texture2DNoMipmap) { 37 config.texture_type != TextureType::Texture2DNoMipmap) {
@@ -53,12 +54,14 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
53 case TextureType::Texture2DNoMipmap: 54 case TextureType::Texture2DNoMipmap:
54 ASSERT(config.Depth() == 1); 55 ASSERT(config.Depth() == 1);
55 type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D; 56 type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
57 rescaleable = !config.IsPitchLinear();
56 size.width = config.Width(); 58 size.width = config.Width();
57 size.height = config.Height(); 59 size.height = config.Height();
58 resources.layers = config.BaseLayer() + 1; 60 resources.layers = config.BaseLayer() + 1;
59 break; 61 break;
60 case TextureType::Texture2DArray: 62 case TextureType::Texture2DArray:
61 type = ImageType::e2D; 63 type = ImageType::e2D;
64 rescaleable = true;
62 size.width = config.Width(); 65 size.width = config.Width();
63 size.height = config.Height(); 66 size.height = config.Height();
64 resources.layers = config.BaseLayer() + config.Depth(); 67 resources.layers = config.BaseLayer() + config.Depth();
@@ -98,12 +101,14 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
98 // FIXME: Call this without passing *this 101 // FIXME: Call this without passing *this
99 layer_stride = CalculateLayerStride(*this); 102 layer_stride = CalculateLayerStride(*this);
100 maybe_unaligned_layer_stride = CalculateLayerSize(*this); 103 maybe_unaligned_layer_stride = CalculateLayerSize(*this);
104 rescaleable &= (block.depth == 0) && resources.levels == 1;
101 } 105 }
102} 106}
103 107
104ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept { 108ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept {
105 const auto& rt = regs.rt[index]; 109 const auto& rt = regs.rt[index];
106 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format); 110 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format);
111 rescaleable = false;
107 if (rt.tile_mode.is_pitch_linear) { 112 if (rt.tile_mode.is_pitch_linear) {
108 ASSERT(rt.tile_mode.is_3d == 0); 113 ASSERT(rt.tile_mode.is_3d == 0);
109 type = ImageType::Linear; 114 type = ImageType::Linear;
@@ -129,6 +134,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
129 type = ImageType::e3D; 134 type = ImageType::e3D;
130 size.depth = rt.depth; 135 size.depth = rt.depth;
131 } else { 136 } else {
137 rescaleable = block.depth == 0 && size.height > 256;
132 type = ImageType::e2D; 138 type = ImageType::e2D;
133 resources.layers = rt.depth; 139 resources.layers = rt.depth;
134 } 140 }
@@ -138,6 +144,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
138 format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format); 144 format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format);
139 size.width = regs.zeta_width; 145 size.width = regs.zeta_width;
140 size.height = regs.zeta_height; 146 size.height = regs.zeta_height;
147 rescaleable = false;
141 resources.levels = 1; 148 resources.levels = 1;
142 layer_stride = regs.zeta.layer_stride * 4; 149 layer_stride = regs.zeta.layer_stride * 4;
143 maybe_unaligned_layer_stride = layer_stride; 150 maybe_unaligned_layer_stride = layer_stride;
@@ -156,6 +163,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
156 type = ImageType::e3D; 163 type = ImageType::e3D;
157 size.depth = regs.zeta_depth; 164 size.depth = regs.zeta_depth;
158 } else { 165 } else {
166 rescaleable = block.depth == 0 && size.height > 256;
159 type = ImageType::e2D; 167 type = ImageType::e2D;
160 resources.layers = regs.zeta_depth; 168 resources.layers = regs.zeta_depth;
161 } 169 }
@@ -164,6 +172,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
164ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept { 172ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
165 UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero"); 173 UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero");
166 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format); 174 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format);
175 rescaleable = false;
167 if (config.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch) { 176 if (config.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch) {
168 type = ImageType::Linear; 177 type = ImageType::Linear;
169 size = Extent3D{ 178 size = Extent3D{
@@ -174,6 +183,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
174 pitch = config.pitch; 183 pitch = config.pitch;
175 } else { 184 } else {
176 type = config.block_depth > 0 ? ImageType::e3D : ImageType::e2D; 185 type = config.block_depth > 0 ? ImageType::e3D : ImageType::e2D;
186
177 block = Extent3D{ 187 block = Extent3D{
178 .width = config.block_width, 188 .width = config.block_width,
179 .height = config.block_height, 189 .height = config.block_height,
@@ -186,6 +196,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
186 .height = config.height, 196 .height = config.height,
187 .depth = 1, 197 .depth = 1,
188 }; 198 };
199 rescaleable = block.depth == 0 && size.height > 256;
189 } 200 }
190} 201}
191 202
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index 16d4cee37..e874d2870 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -33,6 +33,7 @@ struct ImageInfo {
33 u32 maybe_unaligned_layer_stride = 0; 33 u32 maybe_unaligned_layer_stride = 0;
34 u32 num_samples = 1; 34 u32 num_samples = 1;
35 u32 tile_width_spacing = 0; 35 u32 tile_width_spacing = 0;
36 bool rescaleable = false;
36}; 37};
37 38
38} // namespace VideoCommon 39} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index ce5994d5f..be40f6b88 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -216,7 +216,10 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
216 return; 216 return;
217 } 217 }
218 218
219 u32 scale_rating;
219 bool rescaled; 220 bool rescaled;
221 std::array<ImageId, NUM_RT> tmp_color_images{};
222 ImageId tmp_depth_image{};
220 do { 223 do {
221 flags[Dirty::RenderTargets] = false; 224 flags[Dirty::RenderTargets] = false;
222 225
@@ -226,10 +229,10 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
226 const bool force = flags[Dirty::RenderTargetControl]; 229 const bool force = flags[Dirty::RenderTargetControl];
227 flags[Dirty::RenderTargetControl] = false; 230 flags[Dirty::RenderTargetControl] = false;
228 231
232 scale_rating = 0;
233 bool any_rescaled = false;
229 bool can_rescale = true; 234 bool can_rescale = true;
230 bool any_blacklisted = false; 235 bool any_blacklisted = false;
231 std::array<ImageId, NUM_RT> tmp_color_images{};
232 ImageId tmp_depth_image{};
233 const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { 236 const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
234 if (view_id) { 237 if (view_id) {
235 const auto& view = slot_image_views[view_id]; 238 const auto& view = slot_image_views[view_id];
@@ -238,6 +241,10 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
238 auto& image = slot_images[image_id]; 241 auto& image = slot_images[image_id];
239 can_rescale &= ImageCanRescale(image); 242 can_rescale &= ImageCanRescale(image);
240 any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted); 243 any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted);
244 any_rescaled |= True(image.flags & ImageFlagBits::Rescaled);
245 scale_rating = std::max<u32>(scale_rating, image.scale_tick <= frame_tick
246 ? image.scale_rating + 1U
247 : image.scale_rating);
241 } else { 248 } else {
242 id_save = CORRUPT_ID; 249 id_save = CORRUPT_ID;
243 } 250 }
@@ -257,17 +264,19 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
257 check_rescale(render_targets.depth_buffer_id, tmp_depth_image); 264 check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
258 265
259 if (can_rescale) { 266 if (can_rescale) {
260 rescaled = true; 267 rescaled = any_rescaled || scale_rating >= 2;
261 const auto scale_up = [this](ImageId image_id) { 268 const auto scale_up = [this](ImageId image_id) {
262 if (image_id != CORRUPT_ID) { 269 if (image_id != CORRUPT_ID) {
263 Image& image = slot_images[image_id]; 270 Image& image = slot_images[image_id];
264 ScaleUp(image); 271 ScaleUp(image);
265 } 272 }
266 }; 273 };
267 for (size_t index = 0; index < NUM_RT; ++index) { 274 if (rescaled) {
268 scale_up(tmp_color_images[index]); 275 for (size_t index = 0; index < NUM_RT; ++index) {
276 scale_up(tmp_color_images[index]);
277 }
278 scale_up(tmp_depth_image);
269 } 279 }
270 scale_up(tmp_depth_image);
271 } else { 280 } else {
272 rescaled = false; 281 rescaled = false;
273 const auto scale_down = [this, any_blacklisted](ImageId image_id) { 282 const auto scale_down = [this, any_blacklisted](ImageId image_id) {
@@ -283,10 +292,23 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
283 scale_down(tmp_color_images[index]); 292 scale_down(tmp_color_images[index]);
284 } 293 }
285 scale_down(tmp_depth_image); 294 scale_down(tmp_depth_image);
295 scale_rating = 0;
286 } 296 }
287 } while (has_deleted_images); 297 } while (has_deleted_images);
288 // Rescale End 298 // Rescale End
289 299
300 const auto set_rating = [this, scale_rating](ImageId image_id) {
301 if (image_id != CORRUPT_ID) {
302 Image& image = slot_images[image_id];
303 image.scale_rating = scale_rating;
304 image.scale_tick = frame_tick + 1;
305 }
306 };
307 for (size_t index = 0; index < NUM_RT; ++index) {
308 set_rating(tmp_color_images[index]);
309 }
310 set_rating(tmp_depth_image);
311
290 if (is_rescaling != rescaled) { 312 if (is_rescaling != rescaled) {
291 flags[Dirty::RescaleViewports] = true; 313 flags[Dirty::RescaleViewports] = true;
292 flags[Dirty::RescaleScissors] = true; 314 flags[Dirty::RescaleScissors] = true;
@@ -761,10 +783,7 @@ bool TextureCache<P>::ImageCanRescale(Image& image) {
761 True(image.flags & ImageFlagBits::RescaleChecked)) { 783 True(image.flags & ImageFlagBits::RescaleChecked)) {
762 return true; 784 return true;
763 } 785 }
764 const auto& info = image.info; 786 if (!image.info.rescaleable) {
765 const bool can_this_rescale =
766 (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
767 if (!can_this_rescale) {
768 image.flags &= ~ImageFlagBits::RescaleChecked; 787 image.flags &= ~ImageFlagBits::RescaleChecked;
769 return false; 788 return false;
770 } 789 }
@@ -928,8 +947,7 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
928 }; 947 };
929 ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu); 948 ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
930 949
931 bool can_rescale = 950 bool can_rescale = info.rescaleable;
932 (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
933 bool any_rescaled = false; 951 bool any_rescaled = false;
934 bool any_blacklisted = false; 952 bool any_blacklisted = false;
935 for (const ImageId sibling_id : all_siblings) { 953 for (const ImageId sibling_id : all_siblings) {