diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_info.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_info.h | 1 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 42 |
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 { | |||
| 60 | ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_) | 60 | ImageBase::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 | ||
| 104 | ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept { | 108 | ImageInfo::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 { | |||
| 164 | ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept { | 172 | ImageInfo::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) { |