diff options
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 328386b7e..5921185a6 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -304,7 +304,6 @@ std::unique_ptr<PicaTrace> FinishPicaTracing() | |||
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { | 306 | const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { |
| 307 | |||
| 308 | // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each | 307 | // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each |
| 309 | // of which is composed of four 2x2 subtiles each of which is composed of four texels. | 308 | // of which is composed of four 2x2 subtiles each of which is composed of four texels. |
| 310 | // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. | 309 | // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. |
| @@ -323,41 +322,39 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 323 | // 02 03 06 07 18 19 22 23 | 322 | // 02 03 06 07 18 19 22 23 |
| 324 | // 00 01 04 05 16 17 20 21 | 323 | // 00 01 04 05 16 17 20 21 |
| 325 | 324 | ||
| 326 | // TODO(neobrain): Not sure if this swizzling pattern is used for all textures. | 325 | const unsigned int block_width = 8; |
| 327 | // To be flexible in case different but similar patterns are used, we keep this | 326 | const unsigned int block_height = 8; |
| 328 | // somewhat inefficient code around for now. | 327 | |
| 329 | int texel_index_within_tile = 0; | 328 | const unsigned int coarse_x = x & ~7; |
| 330 | for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { | 329 | const unsigned int coarse_y = y & ~7; |
| 331 | int sub_tile_width = 1 << block_size_index; | ||
| 332 | int sub_tile_height = 1 << block_size_index; | ||
| 333 | |||
| 334 | int sub_tile_index = (x & sub_tile_width) << block_size_index; | ||
| 335 | sub_tile_index += 2 * ((y & sub_tile_height) << block_size_index); | ||
| 336 | texel_index_within_tile += sub_tile_index; | ||
| 337 | } | ||
| 338 | 330 | ||
| 339 | const int block_width = 8; | 331 | // Interleave the lower 3 bits of each coordinate to get the intra-block offsets, which are |
| 340 | const int block_height = 8; | 332 | // arranged in a Z-order curve. More details on the bit manipulation at: |
| 333 | // https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ | ||
| 334 | unsigned int i = (x | (y << 8)) & 0x0707; // ---- -210 | ||
| 335 | i = (i ^ (i << 2)) & 0x1313; // ---2 --10 | ||
| 336 | i = (i ^ (i << 1)) & 0x1515; // ---2 -1-0 | ||
| 337 | i = (i | (i >> 7)) & 0x3F; | ||
| 341 | 338 | ||
| 342 | int coarse_x = (x / block_width) * block_width; | 339 | source += coarse_y * info.stride; |
| 343 | int coarse_y = (y / block_height) * block_height; | 340 | const unsigned int offset = coarse_x * block_height + i; |
| 344 | 341 | ||
| 345 | switch (info.format) { | 342 | switch (info.format) { |
| 346 | case Regs::TextureFormat::RGBA8: | 343 | case Regs::TextureFormat::RGBA8: |
| 347 | { | 344 | { |
| 348 | const u8* source_ptr = source + coarse_x * block_height * 4 + coarse_y * info.stride + texel_index_within_tile * 4; | 345 | const u8* source_ptr = source + offset * 4; |
| 349 | return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? (u8)255 : source_ptr[0] }; | 346 | return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? (u8)255 : source_ptr[0] }; |
| 350 | } | 347 | } |
| 351 | 348 | ||
| 352 | case Regs::TextureFormat::RGB8: | 349 | case Regs::TextureFormat::RGB8: |
| 353 | { | 350 | { |
| 354 | const u8* source_ptr = source + coarse_x * block_height * 3 + coarse_y * info.stride + texel_index_within_tile * 3; | 351 | const u8* source_ptr = source + offset * 3; |
| 355 | return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; | 352 | return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; |
| 356 | } | 353 | } |
| 357 | 354 | ||
| 358 | case Regs::TextureFormat::RGBA5551: | 355 | case Regs::TextureFormat::RGBA5551: |
| 359 | { | 356 | { |
| 360 | const u16 source_ptr = *(const u16*)(source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2); | 357 | const u16 source_ptr = *(const u16*)(source + offset * 2); |
| 361 | u8 r = (source_ptr >> 11) & 0x1F; | 358 | u8 r = (source_ptr >> 11) & 0x1F; |
| 362 | u8 g = ((source_ptr) >> 6) & 0x1F; | 359 | u8 g = ((source_ptr) >> 6) & 0x1F; |
| 363 | u8 b = (source_ptr >> 1) & 0x1F; | 360 | u8 b = (source_ptr >> 1) & 0x1F; |
| @@ -367,7 +364,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 367 | 364 | ||
| 368 | case Regs::TextureFormat::RGB565: | 365 | case Regs::TextureFormat::RGB565: |
| 369 | { | 366 | { |
| 370 | const u16 source_ptr = *(const u16*)(source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2); | 367 | const u16 source_ptr = *(const u16*)(source + offset * 2); |
| 371 | u8 r = (source_ptr >> 11) & 0x1F; | 368 | u8 r = (source_ptr >> 11) & 0x1F; |
| 372 | u8 g = ((source_ptr) >> 5) & 0x3F; | 369 | u8 g = ((source_ptr) >> 5) & 0x3F; |
| 373 | u8 b = (source_ptr) & 0x1F; | 370 | u8 b = (source_ptr) & 0x1F; |
| @@ -376,7 +373,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 376 | 373 | ||
| 377 | case Regs::TextureFormat::RGBA4: | 374 | case Regs::TextureFormat::RGBA4: |
| 378 | { | 375 | { |
| 379 | const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; | 376 | const u8* source_ptr = source + offset * 2; |
| 380 | u8 r = source_ptr[1] >> 4; | 377 | u8 r = source_ptr[1] >> 4; |
| 381 | u8 g = source_ptr[1] & 0xFF; | 378 | u8 g = source_ptr[1] & 0xFF; |
| 382 | u8 b = source_ptr[0] >> 4; | 379 | u8 b = source_ptr[0] >> 4; |
| @@ -390,7 +387,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 390 | 387 | ||
| 391 | case Regs::TextureFormat::IA8: | 388 | case Regs::TextureFormat::IA8: |
| 392 | { | 389 | { |
| 393 | const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; | 390 | const u8* source_ptr = source + offset * 2; |
| 394 | 391 | ||
| 395 | // TODO: component order not verified | 392 | // TODO: component order not verified |
| 396 | 393 | ||
| @@ -404,13 +401,13 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 404 | 401 | ||
| 405 | case Regs::TextureFormat::I8: | 402 | case Regs::TextureFormat::I8: |
| 406 | { | 403 | { |
| 407 | const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; | 404 | const u8* source_ptr = source + offset; |
| 408 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; | 405 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; |
| 409 | } | 406 | } |
| 410 | 407 | ||
| 411 | case Regs::TextureFormat::A8: | 408 | case Regs::TextureFormat::A8: |
| 412 | { | 409 | { |
| 413 | const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; | 410 | const u8* source_ptr = source + offset; |
| 414 | 411 | ||
| 415 | if (disable_alpha) { | 412 | if (disable_alpha) { |
| 416 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; | 413 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; |
| @@ -421,7 +418,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 421 | 418 | ||
| 422 | case Regs::TextureFormat::IA4: | 419 | case Regs::TextureFormat::IA4: |
| 423 | { | 420 | { |
| 424 | const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; | 421 | const u8* source_ptr = source + offset / 2; |
| 425 | 422 | ||
| 426 | // TODO: component order not verified | 423 | // TODO: component order not verified |
| 427 | 424 | ||
| @@ -440,7 +437,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 440 | 437 | ||
| 441 | case Regs::TextureFormat::A4: | 438 | case Regs::TextureFormat::A4: |
| 442 | { | 439 | { |
| 443 | const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; | 440 | const u8* source_ptr = source + offset / 2; |
| 444 | 441 | ||
| 445 | // TODO: component order not verified | 442 | // TODO: component order not verified |
| 446 | 443 | ||