summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-07-18 00:44:32 -0300
committerGravatar ReinUsesLisp2021-07-18 01:15:48 -0300
commit6d9f347e22d3b198ff8f623d1efafcf7dae27321 (patch)
tree8ccc2e8e07c73300cba5828c78b61052a8ba47b6
parentMerge pull request #6647 from lat9nq/specify-system-path (diff)
downloadyuzu-6d9f347e22d3b198ff8f623d1efafcf7dae27321.tar.gz
yuzu-6d9f347e22d3b198ff8f623d1efafcf7dae27321.tar.xz
yuzu-6d9f347e22d3b198ff8f623d1efafcf7dae27321.zip
texture_cache/util: Fix size calculations of multisampled images
On the texture cache we handle multisampled images by keeping their real size in samples (e.g. 1920x1080 with 4 samples is 3840x2160). This works nicely with size matches and other comparisons, but the calculation for guest sizes was not having this in mind, and the size was being multiplied (again) by the number of samples per dimension. For example a 3840x2160 texture cache image had its width and height multiplied by 2, resulting in a much larger texture. Fix this issue. - Fixes performance regression on cooking related titles when an unrelated bug was fixed.
Diffstat (limited to '')
-rw-r--r--src/video_core/texture_cache/util.cpp86
1 files changed, 33 insertions, 53 deletions
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index c872517b8..59cf2f561 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -169,23 +169,6 @@ template <u32 GOB_EXTENT>
169 return Common::DivCeil(AdjustMipSize(size, level), block_size); 169 return Common::DivCeil(AdjustMipSize(size, level), block_size);
170} 170}
171 171
172[[nodiscard]] constexpr std::pair<int, int> Samples(int num_samples) {
173 switch (num_samples) {
174 case 1:
175 return {1, 1};
176 case 2:
177 return {2, 1};
178 case 4:
179 return {2, 2};
180 case 8:
181 return {4, 2};
182 case 16:
183 return {4, 4};
184 }
185 UNREACHABLE_MSG("Invalid number of samples={}", num_samples);
186 return {1, 1};
187}
188
189[[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) { 172[[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) {
190 return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; 173 return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
191} 174}
@@ -283,14 +266,13 @@ template <u32 GOB_EXTENT>
283} 266}
284 267
285[[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, 268[[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block,
286 u32 num_samples, u32 tile_width_spacing) { 269 u32 tile_width_spacing) {
287 const auto [samples_x, samples_y] = Samples(num_samples);
288 const u32 bytes_per_block = BytesPerBlock(format); 270 const u32 bytes_per_block = BytesPerBlock(format);
289 return { 271 return {
290 .size = 272 .size =
291 { 273 {
292 .width = size.width * samples_x, 274 .width = size.width,
293 .height = size.height * samples_y, 275 .height = size.height,
294 .depth = size.depth, 276 .depth = size.depth,
295 }, 277 },
296 .block = block, 278 .block = block,
@@ -301,14 +283,12 @@ template <u32 GOB_EXTENT>
301} 283}
302 284
303[[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) { 285[[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) {
304 return MakeLevelInfo(info.format, info.size, info.block, info.num_samples, 286 return MakeLevelInfo(info.format, info.size, info.block, info.tile_width_spacing);
305 info.tile_width_spacing);
306} 287}
307 288
308[[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block, 289[[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block,
309 u32 num_samples, u32 tile_width_spacing, 290 u32 tile_width_spacing, u32 level) {
310 u32 level) { 291 const LevelInfo info = MakeLevelInfo(format, size, block, tile_width_spacing);
311 const LevelInfo info = MakeLevelInfo(format, size, block, num_samples, tile_width_spacing);
312 u32 offset = 0; 292 u32 offset = 0;
313 for (u32 current_level = 0; current_level < level; ++current_level) { 293 for (u32 current_level = 0; current_level < level; ++current_level) {
314 offset += CalculateLevelSize(info, current_level); 294 offset += CalculateLevelSize(info, current_level);
@@ -645,8 +625,8 @@ u32 CalculateLayerStride(const ImageInfo& info) noexcept {
645 625
646u32 CalculateLayerSize(const ImageInfo& info) noexcept { 626u32 CalculateLayerSize(const ImageInfo& info) noexcept {
647 ASSERT(info.type != ImageType::Linear); 627 ASSERT(info.type != ImageType::Linear);
648 return CalculateLevelOffset(info.format, info.size, info.block, info.num_samples, 628 return CalculateLevelOffset(info.format, info.size, info.block, info.tile_width_spacing,
649 info.tile_width_spacing, info.resources.levels); 629 info.resources.levels);
650} 630}
651 631
652LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept { 632LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept {
@@ -1195,37 +1175,37 @@ static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2
1195 0x7f8000); 1175 0x7f8000);
1196static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000); 1176static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000);
1197 1177
1198static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 1, 0, 7) == 1178static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 0, 7) ==
1199 0x2afc00); 1179 0x2afc00);
1200static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 1, 1180static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 0,
1201 0, 12) == 0x50d200); 1181 12) == 0x50d200);
1202 1182
1203static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1183static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 0) ==
1204 0) == 0); 1184 0);
1205static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1185static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 1) ==
1206 1) == 0x400000); 1186 0x400000);
1207static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1187static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 2) ==
1208 2) == 0x500000); 1188 0x500000);
1209static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1189static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 3) ==
1210 3) == 0x540000); 1190 0x540000);
1211static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1191static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 4) ==
1212 4) == 0x550000); 1192 0x550000);
1213static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1193static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 5) ==
1214 5) == 0x554000); 1194 0x554000);
1215static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1195static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 6) ==
1216 6) == 0x555000); 1196 0x555000);
1217static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1197static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 7) ==
1218 7) == 0x555400); 1198 0x555400);
1219static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1199static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 8) ==
1220 8) == 0x555600); 1200 0x555600);
1221static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1201static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 9) ==
1222 9) == 0x555800); 1202 0x555800);
1223 1203
1224constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height, 1204constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height,
1225 u32 tile_width_spacing, u32 level) { 1205 u32 tile_width_spacing, u32 level) {
1226 const Extent3D size{width, height, 1}; 1206 const Extent3D size{width, height, 1};
1227 const Extent3D block{0, block_height, 0}; 1207 const Extent3D block{0, block_height, 0};
1228 const u32 offset = CalculateLevelOffset(format, size, block, 1, tile_width_spacing, level); 1208 const u32 offset = CalculateLevelOffset(format, size, block, tile_width_spacing, level);
1229 return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing); 1209 return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing);
1230} 1210}
1231 1211