summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-04 18:47:26 -0500
committerGravatar GitHub2018-11-04 18:47:26 -0500
commit38c1c500ab733208d86972f61c29d6679c502c31 (patch)
treecfe859b9c8f92bada0c6902953470e627769d9ec
parentMerge pull request #1645 from dharmin/master (diff)
parentFix ASTC Decompressor to support depth parameter (diff)
downloadyuzu-38c1c500ab733208d86972f61c29d6679c502c31.tar.gz
yuzu-38c1c500ab733208d86972f61c29d6679c502c31.tar.xz
yuzu-38c1c500ab733208d86972f61c29d6679c502c31.zip
Merge pull request #1625 from FernandoS27/astc
Implement ASTC Textures 5x5 and fix a bunch of ASTC texture problems
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp38
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h2
-rw-r--r--src/video_core/surface.cpp26
-rw-r--r--src/video_core/surface.h107
-rw-r--r--src/video_core/textures/astc.cpp32
-rw-r--r--src/video_core/textures/astc.h2
-rw-r--r--src/video_core/textures/decoders.cpp12
-rw-r--r--src/video_core/textures/decoders.h4
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp6
9 files changed, 154 insertions, 75 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index f194a7687..0e11557c4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -58,16 +58,14 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
58 58
59std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, bool layer_only, 59std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, bool layer_only,
60 bool uncompressed) const { 60 bool uncompressed) const {
61 const u32 compression_factor{GetCompressionFactor(pixel_format)}; 61 const u32 tile_x{GetDefaultBlockWidth(pixel_format)};
62 const u32 tile_y{GetDefaultBlockHeight(pixel_format)};
62 const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; 63 const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)};
63 u32 m_depth = (layer_only ? 1U : depth); 64 u32 m_depth = (layer_only ? 1U : depth);
64 u32 m_width = MipWidth(mip_level); 65 u32 m_width = MipWidth(mip_level);
65 u32 m_height = MipHeight(mip_level); 66 u32 m_height = MipHeight(mip_level);
66 m_width = uncompressed ? m_width 67 m_width = uncompressed ? m_width : std::max(1U, (m_width + tile_x - 1) / tile_x);
67 : std::max(1U, (m_width + compression_factor - 1) / compression_factor); 68 m_height = uncompressed ? m_height : std::max(1U, (m_height + tile_y - 1) / tile_y);
68 m_height = uncompressed
69 ? m_height
70 : std::max(1U, (m_height + compression_factor - 1) / compression_factor);
71 m_depth = std::max(1U, m_depth >> mip_level); 69 m_depth = std::max(1U, m_depth >> mip_level);
72 u32 m_block_height = MipBlockHeight(mip_level); 70 u32 m_block_height = MipBlockHeight(mip_level);
73 u32 m_block_depth = MipBlockDepth(mip_level); 71 u32 m_block_depth = MipBlockDepth(mip_level);
@@ -305,6 +303,8 @@ static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex
305 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8_SRGB 303 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8_SRGB
306 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5_SRGB 304 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5_SRGB
307 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4_SRGB 305 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4_SRGB
306 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X5
307 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X5_SRGB
308 308
309 // Depth formats 309 // Depth formats
310 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F 310 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F
@@ -364,15 +364,18 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d
364 364
365 // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual 365 // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
366 // pixel values. 366 // pixel values.
367 const u32 tile_size{IsFormatBCn(format) ? 4U : 1U}; 367 const u32 tile_size_x{GetDefaultBlockWidth(format)};
368 const u32 tile_size_y{GetDefaultBlockHeight(format)};
368 369
369 if (morton_to_gl) { 370 if (morton_to_gl) {
370 const std::vector<u8> data = Tegra::Texture::UnswizzleTexture( 371 const std::vector<u8> data =
371 addr, tile_size, bytes_per_pixel, stride, height, depth, block_height, block_depth); 372 Tegra::Texture::UnswizzleTexture(addr, tile_size_x, tile_size_y, bytes_per_pixel,
373 stride, height, depth, block_height, block_depth);
372 const std::size_t size_to_copy{std::min(gl_buffer_size, data.size())}; 374 const std::size_t size_to_copy{std::min(gl_buffer_size, data.size())};
373 memcpy(gl_buffer, data.data(), size_to_copy); 375 memcpy(gl_buffer, data.data(), size_to_copy);
374 } else { 376 } else {
375 Tegra::Texture::CopySwizzledData(stride / tile_size, height / tile_size, depth, 377 Tegra::Texture::CopySwizzledData((stride + tile_size_x - 1) / tile_size_x,
378 (height + tile_size_y - 1) / tile_size_y, depth,
376 bytes_per_pixel, bytes_per_pixel, Memory::GetPointer(addr), 379 bytes_per_pixel, bytes_per_pixel, Memory::GetPointer(addr),
377 gl_buffer, false, block_height, block_depth); 380 gl_buffer, false, block_height, block_depth);
378 } 381 }
@@ -440,6 +443,8 @@ static constexpr GLConversionArray morton_to_gl_fns = {
440 MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>, 443 MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>,
441 MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>, 444 MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>,
442 MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>, 445 MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>,
446 MortonCopy<true, PixelFormat::ASTC_2D_5X5>,
447 MortonCopy<true, PixelFormat::ASTC_2D_5X5_SRGB>,
443 MortonCopy<true, PixelFormat::Z32F>, 448 MortonCopy<true, PixelFormat::Z32F>,
444 MortonCopy<true, PixelFormat::Z16>, 449 MortonCopy<true, PixelFormat::Z16>,
445 MortonCopy<true, PixelFormat::Z24S8>, 450 MortonCopy<true, PixelFormat::Z24S8>,
@@ -508,6 +513,8 @@ static constexpr GLConversionArray gl_to_morton_fns = {
508 nullptr, 513 nullptr,
509 nullptr, 514 nullptr,
510 nullptr, 515 nullptr,
516 nullptr,
517 nullptr,
511 MortonCopy<false, PixelFormat::Z32F>, 518 MortonCopy<false, PixelFormat::Z32F>,
512 MortonCopy<false, PixelFormat::Z16>, 519 MortonCopy<false, PixelFormat::Z16>,
513 MortonCopy<false, PixelFormat::Z24S8>, 520 MortonCopy<false, PixelFormat::Z24S8>,
@@ -897,21 +904,24 @@ static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
897 * typical desktop GPUs. 904 * typical desktop GPUs.
898 */ 905 */
899static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format, 906static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format,
900 u32 width, u32 height) { 907 u32 width, u32 height, u32 depth) {
901 switch (pixel_format) { 908 switch (pixel_format) {
902 case PixelFormat::ASTC_2D_4X4: 909 case PixelFormat::ASTC_2D_4X4:
903 case PixelFormat::ASTC_2D_8X8: 910 case PixelFormat::ASTC_2D_8X8:
904 case PixelFormat::ASTC_2D_8X5: 911 case PixelFormat::ASTC_2D_8X5:
905 case PixelFormat::ASTC_2D_5X4: 912 case PixelFormat::ASTC_2D_5X4:
913 case PixelFormat::ASTC_2D_5X5:
906 case PixelFormat::ASTC_2D_4X4_SRGB: 914 case PixelFormat::ASTC_2D_4X4_SRGB:
907 case PixelFormat::ASTC_2D_8X8_SRGB: 915 case PixelFormat::ASTC_2D_8X8_SRGB:
908 case PixelFormat::ASTC_2D_8X5_SRGB: 916 case PixelFormat::ASTC_2D_8X5_SRGB:
909 case PixelFormat::ASTC_2D_5X4_SRGB: { 917 case PixelFormat::ASTC_2D_5X4_SRGB:
918 case PixelFormat::ASTC_2D_5X5_SRGB: {
910 // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. 919 // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC.
911 u32 block_width{}; 920 u32 block_width{};
912 u32 block_height{}; 921 u32 block_height{};
913 std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); 922 std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format);
914 data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); 923 data =
924 Tegra::Texture::ASTC::Decompress(data, width, height, depth, block_width, block_height);
915 break; 925 break;
916 } 926 }
917 case PixelFormat::S8Z24: 927 case PixelFormat::S8Z24:
@@ -971,7 +981,7 @@ void CachedSurface::LoadGLBuffer() {
971 } 981 }
972 for (u32 i = 0; i < params.max_mip_level; i++) 982 for (u32 i = 0; i < params.max_mip_level; i++)
973 ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i), 983 ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i),
974 params.MipHeight(i)); 984 params.MipHeight(i), params.MipDepth(i));
975} 985}
976 986
977MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); 987MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64));
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index f255f4419..46ad37897 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -139,7 +139,7 @@ struct SurfaceParams {
139 } 139 }
140 140
141 u32 MipDepth(u32 mip_level) const { 141 u32 MipDepth(u32 mip_level) const {
142 return std::max(1U, depth >> mip_level); 142 return is_layered ? depth : std::max(1U, depth >> mip_level);
143 } 143 }
144 144
145 // Auto block resizing algorithm from: 145 // Auto block resizing algorithm from:
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index d9a97e30b..e284a4604 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -297,6 +297,8 @@ PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
297 return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; 297 return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4;
298 case Tegra::Texture::TextureFormat::ASTC_2D_5X4: 298 case Tegra::Texture::TextureFormat::ASTC_2D_5X4:
299 return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; 299 return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4;
300 case Tegra::Texture::TextureFormat::ASTC_2D_5X5:
301 return is_srgb ? PixelFormat::ASTC_2D_5X5_SRGB : PixelFormat::ASTC_2D_5X5;
300 case Tegra::Texture::TextureFormat::ASTC_2D_8X8: 302 case Tegra::Texture::TextureFormat::ASTC_2D_8X8:
301 return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; 303 return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8;
302 case Tegra::Texture::TextureFormat::ASTC_2D_8X5: 304 case Tegra::Texture::TextureFormat::ASTC_2D_8X5:
@@ -440,10 +442,12 @@ bool IsPixelFormatASTC(PixelFormat format) {
440 switch (format) { 442 switch (format) {
441 case PixelFormat::ASTC_2D_4X4: 443 case PixelFormat::ASTC_2D_4X4:
442 case PixelFormat::ASTC_2D_5X4: 444 case PixelFormat::ASTC_2D_5X4:
445 case PixelFormat::ASTC_2D_5X5:
443 case PixelFormat::ASTC_2D_8X8: 446 case PixelFormat::ASTC_2D_8X8:
444 case PixelFormat::ASTC_2D_8X5: 447 case PixelFormat::ASTC_2D_8X5:
445 case PixelFormat::ASTC_2D_4X4_SRGB: 448 case PixelFormat::ASTC_2D_4X4_SRGB:
446 case PixelFormat::ASTC_2D_5X4_SRGB: 449 case PixelFormat::ASTC_2D_5X4_SRGB:
450 case PixelFormat::ASTC_2D_5X5_SRGB:
447 case PixelFormat::ASTC_2D_8X8_SRGB: 451 case PixelFormat::ASTC_2D_8X8_SRGB:
448 case PixelFormat::ASTC_2D_8X5_SRGB: 452 case PixelFormat::ASTC_2D_8X5_SRGB:
449 return true; 453 return true;
@@ -453,27 +457,7 @@ bool IsPixelFormatASTC(PixelFormat format) {
453} 457}
454 458
455std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { 459std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
456 switch (format) { 460 return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)};
457 case PixelFormat::ASTC_2D_4X4:
458 return {4, 4};
459 case PixelFormat::ASTC_2D_5X4:
460 return {5, 4};
461 case PixelFormat::ASTC_2D_8X8:
462 return {8, 8};
463 case PixelFormat::ASTC_2D_8X5:
464 return {8, 5};
465 case PixelFormat::ASTC_2D_4X4_SRGB:
466 return {4, 4};
467 case PixelFormat::ASTC_2D_5X4_SRGB:
468 return {5, 4};
469 case PixelFormat::ASTC_2D_8X8_SRGB:
470 return {8, 8};
471 case PixelFormat::ASTC_2D_8X5_SRGB:
472 return {8, 5};
473 default:
474 LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
475 UNREACHABLE();
476 }
477} 461}
478 462
479bool IsFormatBCn(PixelFormat format) { 463bool IsFormatBCn(PixelFormat format) {
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 3232e437f..0ef7849a4 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -72,19 +72,21 @@ enum class PixelFormat {
72 ASTC_2D_8X8_SRGB = 54, 72 ASTC_2D_8X8_SRGB = 54,
73 ASTC_2D_8X5_SRGB = 55, 73 ASTC_2D_8X5_SRGB = 55,
74 ASTC_2D_5X4_SRGB = 56, 74 ASTC_2D_5X4_SRGB = 56,
75 ASTC_2D_5X5 = 57,
76 ASTC_2D_5X5_SRGB = 58,
75 77
76 MaxColorFormat, 78 MaxColorFormat,
77 79
78 // Depth formats 80 // Depth formats
79 Z32F = 57, 81 Z32F = 59,
80 Z16 = 58, 82 Z16 = 60,
81 83
82 MaxDepthFormat, 84 MaxDepthFormat,
83 85
84 // DepthStencil formats 86 // DepthStencil formats
85 Z24S8 = 59, 87 Z24S8 = 61,
86 S8Z24 = 60, 88 S8Z24 = 62,
87 Z32FS8 = 61, 89 Z32FS8 = 63,
88 90
89 MaxDepthStencilFormat, 91 MaxDepthStencilFormat,
90 92
@@ -188,6 +190,8 @@ static constexpr u32 GetCompressionFactor(PixelFormat format) {
188 4, // ASTC_2D_8X8_SRGB 190 4, // ASTC_2D_8X8_SRGB
189 4, // ASTC_2D_8X5_SRGB 191 4, // ASTC_2D_8X5_SRGB
190 4, // ASTC_2D_5X4_SRGB 192 4, // ASTC_2D_5X4_SRGB
193 4, // ASTC_2D_5X5
194 4, // ASTC_2D_5X5_SRGB
191 1, // Z32F 195 1, // Z32F
192 1, // Z16 196 1, // Z16
193 1, // Z24S8 197 1, // Z24S8
@@ -199,6 +203,79 @@ static constexpr u32 GetCompressionFactor(PixelFormat format) {
199 return compression_factor_table[static_cast<std::size_t>(format)]; 203 return compression_factor_table[static_cast<std::size_t>(format)];
200} 204}
201 205
206static constexpr u32 GetDefaultBlockWidth(PixelFormat format) {
207 if (format == PixelFormat::Invalid)
208 return 0;
209 constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
210 1, // ABGR8U
211 1, // ABGR8S
212 1, // ABGR8UI
213 1, // B5G6R5U
214 1, // A2B10G10R10U
215 1, // A1B5G5R5U
216 1, // R8U
217 1, // R8UI
218 1, // RGBA16F
219 1, // RGBA16U
220 1, // RGBA16UI
221 1, // R11FG11FB10F
222 1, // RGBA32UI
223 4, // DXT1
224 4, // DXT23
225 4, // DXT45
226 4, // DXN1
227 4, // DXN2UNORM
228 4, // DXN2SNORM
229 4, // BC7U
230 4, // BC6H_UF16
231 4, // BC6H_SF16
232 4, // ASTC_2D_4X4
233 1, // G8R8U
234 1, // G8R8S
235 1, // BGRA8
236 1, // RGBA32F
237 1, // RG32F
238 1, // R32F
239 1, // R16F
240 1, // R16U
241 1, // R16S
242 1, // R16UI
243 1, // R16I
244 1, // RG16
245 1, // RG16F
246 1, // RG16UI
247 1, // RG16I
248 1, // RG16S
249 1, // RGB32F
250 1, // RGBA8_SRGB
251 1, // RG8U
252 1, // RG8S
253 1, // RG32UI
254 1, // R32UI
255 8, // ASTC_2D_8X8
256 8, // ASTC_2D_8X5
257 5, // ASTC_2D_5X4
258 1, // BGRA8_SRGB
259 4, // DXT1_SRGB
260 4, // DXT23_SRGB
261 4, // DXT45_SRGB
262 4, // BC7U_SRGB
263 4, // ASTC_2D_4X4_SRGB
264 8, // ASTC_2D_8X8_SRGB
265 8, // ASTC_2D_8X5_SRGB
266 5, // ASTC_2D_5X4_SRGB
267 5, // ASTC_2D_5X5
268 5, // ASTC_2D_5X5_SRGB
269 1, // Z32F
270 1, // Z16
271 1, // Z24S8
272 1, // S8Z24
273 1, // Z32FS8
274 }};
275 ASSERT(static_cast<std::size_t>(format) < block_width_table.size());
276 return block_width_table[static_cast<std::size_t>(format)];
277}
278
202static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { 279static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
203 if (format == PixelFormat::Invalid) 280 if (format == PixelFormat::Invalid)
204 return 0; 281 return 0;
@@ -261,6 +338,8 @@ static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
261 8, // ASTC_2D_8X8_SRGB 338 8, // ASTC_2D_8X8_SRGB
262 5, // ASTC_2D_8X5_SRGB 339 5, // ASTC_2D_8X5_SRGB
263 4, // ASTC_2D_5X4_SRGB 340 4, // ASTC_2D_5X4_SRGB
341 5, // ASTC_2D_5X5
342 5, // ASTC_2D_5X5_SRGB
264 1, // Z32F 343 1, // Z32F
265 1, // Z16 344 1, // Z16
266 1, // Z24S8 345 1, // Z24S8
@@ -299,7 +378,7 @@ static constexpr u32 GetFormatBpp(PixelFormat format) {
299 128, // BC7U 378 128, // BC7U
300 128, // BC6H_UF16 379 128, // BC6H_UF16
301 128, // BC6H_SF16 380 128, // BC6H_SF16
302 32, // ASTC_2D_4X4 381 128, // ASTC_2D_4X4
303 16, // G8R8U 382 16, // G8R8U
304 16, // G8R8S 383 16, // G8R8S
305 32, // BGRA8 384 32, // BGRA8
@@ -322,18 +401,20 @@ static constexpr u32 GetFormatBpp(PixelFormat format) {
322 16, // RG8S 401 16, // RG8S
323 64, // RG32UI 402 64, // RG32UI
324 32, // R32UI 403 32, // R32UI
325 16, // ASTC_2D_8X8 404 128, // ASTC_2D_8X8
326 16, // ASTC_2D_8X5 405 128, // ASTC_2D_8X5
327 32, // ASTC_2D_5X4 406 128, // ASTC_2D_5X4
328 32, // BGRA8_SRGB 407 32, // BGRA8_SRGB
329 64, // DXT1_SRGB 408 64, // DXT1_SRGB
330 128, // DXT23_SRGB 409 128, // DXT23_SRGB
331 128, // DXT45_SRGB 410 128, // DXT45_SRGB
332 128, // BC7U 411 128, // BC7U
333 32, // ASTC_2D_4X4_SRGB 412 128, // ASTC_2D_4X4_SRGB
334 16, // ASTC_2D_8X8_SRGB 413 128, // ASTC_2D_8X8_SRGB
335 16, // ASTC_2D_8X5_SRGB 414 128, // ASTC_2D_8X5_SRGB
336 32, // ASTC_2D_5X4_SRGB 415 128, // ASTC_2D_5X4_SRGB
416 128, // ASTC_2D_5X5
417 128, // ASTC_2D_5X5_SRGB
337 32, // Z32F 418 32, // Z32F
338 16, // Z16 419 16, // Z16
339 32, // Z24S8 420 32, // Z24S8
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp
index b1feacae9..bc50a4876 100644
--- a/src/video_core/textures/astc.cpp
+++ b/src/video_core/textures/astc.cpp
@@ -1598,27 +1598,29 @@ static void DecompressBlock(uint8_t inBuf[16], const uint32_t blockWidth,
1598namespace Tegra::Texture::ASTC { 1598namespace Tegra::Texture::ASTC {
1599 1599
1600std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, 1600std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height,
1601 uint32_t block_width, uint32_t block_height) { 1601 uint32_t depth, uint32_t block_width, uint32_t block_height) {
1602 uint32_t blockIdx = 0; 1602 uint32_t blockIdx = 0;
1603 std::vector<uint8_t> outData(height * width * 4); 1603 std::vector<uint8_t> outData(height * width * depth * 4);
1604 for (uint32_t j = 0; j < height; j += block_height) { 1604 for (uint32_t k = 0; k < depth; k++) {
1605 for (uint32_t i = 0; i < width; i += block_width) { 1605 for (uint32_t j = 0; j < height; j += block_height) {
1606 for (uint32_t i = 0; i < width; i += block_width) {
1606 1607
1607 uint8_t* blockPtr = data.data() + blockIdx * 16; 1608 uint8_t* blockPtr = data.data() + blockIdx * 16;
1608 1609
1609 // Blocks can be at most 12x12 1610 // Blocks can be at most 12x12
1610 uint32_t uncompData[144]; 1611 uint32_t uncompData[144];
1611 ASTCC::DecompressBlock(blockPtr, block_width, block_height, uncompData); 1612 ASTCC::DecompressBlock(blockPtr, block_width, block_height, uncompData);
1612 1613
1613 uint32_t decompWidth = std::min(block_width, width - i); 1614 uint32_t decompWidth = std::min(block_width, width - i);
1614 uint32_t decompHeight = std::min(block_height, height - j); 1615 uint32_t decompHeight = std::min(block_height, height - j);
1615 1616
1616 uint8_t* outRow = outData.data() + (j * width + i) * 4; 1617 uint8_t* outRow = outData.data() + (j * width + i) * 4;
1617 for (uint32_t jj = 0; jj < decompHeight; jj++) { 1618 for (uint32_t jj = 0; jj < decompHeight; jj++) {
1618 memcpy(outRow + jj * width * 4, uncompData + jj * block_width, decompWidth * 4); 1619 memcpy(outRow + jj * width * 4, uncompData + jj * block_width, decompWidth * 4);
1619 } 1620 }
1620 1621
1621 blockIdx++; 1622 blockIdx++;
1623 }
1622 } 1624 }
1623 } 1625 }
1624 1626
diff --git a/src/video_core/textures/astc.h b/src/video_core/textures/astc.h
index f0d7c0e56..d419dd025 100644
--- a/src/video_core/textures/astc.h
+++ b/src/video_core/textures/astc.h
@@ -10,6 +10,6 @@
10namespace Tegra::Texture::ASTC { 10namespace Tegra::Texture::ASTC {
11 11
12std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, 12std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height,
13 uint32_t block_width, uint32_t block_height); 13 uint32_t depth, uint32_t block_width, uint32_t block_height);
14 14
15} // namespace Tegra::Texture::ASTC 15} // namespace Tegra::Texture::ASTC
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 550ca856c..3066abf61 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -227,12 +227,14 @@ u32 BytesPerPixel(TextureFormat format) {
227 } 227 }
228} 228}
229 229
230std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, 230std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y,
231 u32 height, u32 depth, u32 block_height, u32 block_depth) { 231 u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
232 u32 block_height, u32 block_depth) {
232 std::vector<u8> unswizzled_data(width * height * depth * bytes_per_pixel); 233 std::vector<u8> unswizzled_data(width * height * depth * bytes_per_pixel);
233 CopySwizzledData(width / tile_size, height / tile_size, depth, bytes_per_pixel, bytes_per_pixel, 234 CopySwizzledData((width + tile_size_x - 1) / tile_size_x,
234 Memory::GetPointer(address), unswizzled_data.data(), true, block_height, 235 (height + tile_size_y - 1) / tile_size_y, depth, bytes_per_pixel,
235 block_depth); 236 bytes_per_pixel, Memory::GetPointer(address), unswizzled_data.data(), true,
237 block_height, block_depth);
236 return unswizzled_data; 238 return unswizzled_data;
237} 239}
238 240
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index b390219e4..ba065510b 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -19,8 +19,8 @@ inline std::size_t GetGOBSize() {
19/** 19/**
20 * Unswizzles a swizzled texture without changing its format. 20 * Unswizzles a swizzled texture without changing its format.
21 */ 21 */
22std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, 22std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y,
23 u32 height, u32 depth, 23 u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
24 u32 block_height = TICEntry::DefaultBlockHeight, 24 u32 block_height = TICEntry::DefaultBlockHeight,
25 u32 block_depth = TICEntry::DefaultBlockHeight); 25 u32 block_depth = TICEntry::DefaultBlockHeight);
26 26
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index 0adbab27d..707747422 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -386,9 +386,9 @@ void GraphicsSurfaceWidget::OnUpdate() {
386 386
387 // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. 387 // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles.
388 // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. 388 // Needs to be fixed if we plan to use this feature more, otherwise we may remove it.
389 auto unswizzled_data = 389 auto unswizzled_data = Tegra::Texture::UnswizzleTexture(
390 Tegra::Texture::UnswizzleTexture(*address, 1, Tegra::Texture::BytesPerPixel(surface_format), 390 *address, 1, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width,
391 surface_width, surface_height, 1U); 391 surface_height, 1U);
392 392
393 auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, 393 auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
394 surface_width, surface_height); 394 surface_width, surface_height);