diff options
| author | 2015-02-26 22:40:27 -0500 | |
|---|---|---|
| committer | 2015-02-26 22:40:27 -0500 | |
| commit | c9ef377afaa038797de6c08da9f204acf67ed1fc (patch) | |
| tree | ab2c741325e2e81e4352b4934972151fceae8d5e /src/video_core/debug_utils | |
| parent | Merge pull request #614 from lioncash/mcr (diff) | |
| parent | GPU: Implemented bits 3 and 1 from the display transfer flags. (diff) | |
| download | yuzu-c9ef377afaa038797de6c08da9f204acf67ed1fc.tar.gz yuzu-c9ef377afaa038797de6c08da9f204acf67ed1fc.tar.xz yuzu-c9ef377afaa038797de6c08da9f204acf67ed1fc.zip | |
Merge pull request #599 from Subv/morton
GPU: Implemented bits 3 and 1 from the display transfer flags.
Diffstat (limited to 'src/video_core/debug_utils')
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 56 |
1 files changed, 14 insertions, 42 deletions
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index f436aa541..27c246a99 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "video_core/color.h" | 23 | #include "video_core/color.h" |
| 24 | #include "video_core/math.h" | 24 | #include "video_core/math.h" |
| 25 | #include "video_core/pica.h" | 25 | #include "video_core/pica.h" |
| 26 | #include "video_core/utils.h" | ||
| 26 | 27 | ||
| 27 | #include "debug_utils.h" | 28 | #include "debug_utils.h" |
| 28 | 29 | ||
| @@ -306,63 +307,33 @@ std::unique_ptr<PicaTrace> FinishPicaTracing() | |||
| 306 | } | 307 | } |
| 307 | 308 | ||
| 308 | const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { | 309 | const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { |
| 309 | // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each | ||
| 310 | // of which is composed of four 2x2 subtiles each of which is composed of four texels. | ||
| 311 | // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. | ||
| 312 | // texels are laid out in a 2x2 subtile like this: | ||
| 313 | // 2 3 | ||
| 314 | // 0 1 | ||
| 315 | // | ||
| 316 | // The full 8x8 tile has the texels arranged like this: | ||
| 317 | // | ||
| 318 | // 42 43 46 47 58 59 62 63 | ||
| 319 | // 40 41 44 45 56 57 60 61 | ||
| 320 | // 34 35 38 39 50 51 54 55 | ||
| 321 | // 32 33 36 37 48 49 52 53 | ||
| 322 | // 10 11 14 15 26 27 30 31 | ||
| 323 | // 08 09 12 13 24 25 28 29 | ||
| 324 | // 02 03 06 07 18 19 22 23 | ||
| 325 | // 00 01 04 05 16 17 20 21 | ||
| 326 | |||
| 327 | const unsigned int block_width = 8; | ||
| 328 | const unsigned int block_height = 8; | ||
| 329 | |||
| 330 | const unsigned int coarse_x = x & ~7; | 310 | const unsigned int coarse_x = x & ~7; |
| 331 | const unsigned int coarse_y = y & ~7; | 311 | const unsigned int coarse_y = y & ~7; |
| 332 | 312 | ||
| 333 | // Interleave the lower 3 bits of each coordinate to get the intra-block offsets, which are | ||
| 334 | // arranged in a Z-order curve. More details on the bit manipulation at: | ||
| 335 | // https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ | ||
| 336 | unsigned int i = (x & 7) | ((y & 7) << 8); // ---- -210 | ||
| 337 | i = (i ^ (i << 2)) & 0x1313; // ---2 --10 | ||
| 338 | i = (i ^ (i << 1)) & 0x1515; // ---2 -1-0 | ||
| 339 | i = (i | (i >> 7)) & 0x3F; | ||
| 340 | |||
| 341 | if (info.format != Regs::TextureFormat::ETC1 && | 313 | if (info.format != Regs::TextureFormat::ETC1 && |
| 342 | info.format != Regs::TextureFormat::ETC1A4) { | 314 | info.format != Regs::TextureFormat::ETC1A4) { |
| 343 | // TODO(neobrain): Fix code design to unify vertical block offsets! | 315 | // TODO(neobrain): Fix code design to unify vertical block offsets! |
| 344 | source += coarse_y * info.stride; | 316 | source += coarse_y * info.stride; |
| 345 | } | 317 | } |
| 346 | const unsigned int offset = coarse_x * block_height; | 318 | |
| 347 | |||
| 348 | // TODO: Assert that width/height are multiples of block dimensions | 319 | // TODO: Assert that width/height are multiples of block dimensions |
| 349 | 320 | ||
| 350 | switch (info.format) { | 321 | switch (info.format) { |
| 351 | case Regs::TextureFormat::RGBA8: | 322 | case Regs::TextureFormat::RGBA8: |
| 352 | { | 323 | { |
| 353 | const u8* source_ptr = source + offset * 4 + i * 4; | 324 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 4); |
| 354 | return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? (u8)255 : source_ptr[0] }; | 325 | return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? (u8)255 : source_ptr[0] }; |
| 355 | } | 326 | } |
| 356 | 327 | ||
| 357 | case Regs::TextureFormat::RGB8: | 328 | case Regs::TextureFormat::RGB8: |
| 358 | { | 329 | { |
| 359 | const u8* source_ptr = source + offset * 3 + i * 3; | 330 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 3); |
| 360 | return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; | 331 | return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; |
| 361 | } | 332 | } |
| 362 | 333 | ||
| 363 | case Regs::TextureFormat::RGBA5551: | 334 | case Regs::TextureFormat::RGBA5551: |
| 364 | { | 335 | { |
| 365 | const u16 source_ptr = *(const u16*)(source + offset * 2 + i * 2); | 336 | const u16 source_ptr = *(const u16*)(source + VideoCore::GetMortonOffset(x, y, 2)); |
| 366 | u8 r = (source_ptr >> 11) & 0x1F; | 337 | u8 r = (source_ptr >> 11) & 0x1F; |
| 367 | u8 g = ((source_ptr) >> 6) & 0x1F; | 338 | u8 g = ((source_ptr) >> 6) & 0x1F; |
| 368 | u8 b = (source_ptr >> 1) & 0x1F; | 339 | u8 b = (source_ptr >> 1) & 0x1F; |
| @@ -373,7 +344,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 373 | 344 | ||
| 374 | case Regs::TextureFormat::RGB565: | 345 | case Regs::TextureFormat::RGB565: |
| 375 | { | 346 | { |
| 376 | const u16 source_ptr = *(const u16*)(source + offset * 2 + i * 2); | 347 | const u16 source_ptr = *(const u16*)(source + VideoCore::GetMortonOffset(x, y, 2)); |
| 377 | u8 r = Color::Convert5To8((source_ptr >> 11) & 0x1F); | 348 | u8 r = Color::Convert5To8((source_ptr >> 11) & 0x1F); |
| 378 | u8 g = Color::Convert6To8(((source_ptr) >> 5) & 0x3F); | 349 | u8 g = Color::Convert6To8(((source_ptr) >> 5) & 0x3F); |
| 379 | u8 b = Color::Convert5To8((source_ptr) & 0x1F); | 350 | u8 b = Color::Convert5To8((source_ptr) & 0x1F); |
| @@ -382,7 +353,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 382 | 353 | ||
| 383 | case Regs::TextureFormat::RGBA4: | 354 | case Regs::TextureFormat::RGBA4: |
| 384 | { | 355 | { |
| 385 | const u8* source_ptr = source + offset * 2 + i * 2; | 356 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 2); |
| 386 | u8 r = Color::Convert4To8(source_ptr[1] >> 4); | 357 | u8 r = Color::Convert4To8(source_ptr[1] >> 4); |
| 387 | u8 g = Color::Convert4To8(source_ptr[1] & 0xF); | 358 | u8 g = Color::Convert4To8(source_ptr[1] & 0xF); |
| 388 | u8 b = Color::Convert4To8(source_ptr[0] >> 4); | 359 | u8 b = Color::Convert4To8(source_ptr[0] >> 4); |
| @@ -392,7 +363,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 392 | 363 | ||
| 393 | case Regs::TextureFormat::IA8: | 364 | case Regs::TextureFormat::IA8: |
| 394 | { | 365 | { |
| 395 | const u8* source_ptr = source + offset * 2 + i * 2; | 366 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 2); |
| 396 | 367 | ||
| 397 | if (disable_alpha) { | 368 | if (disable_alpha) { |
| 398 | // Show intensity as red, alpha as green | 369 | // Show intensity as red, alpha as green |
| @@ -404,13 +375,13 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 404 | 375 | ||
| 405 | case Regs::TextureFormat::I8: | 376 | case Regs::TextureFormat::I8: |
| 406 | { | 377 | { |
| 407 | const u8* source_ptr = source + offset + i; | 378 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); |
| 408 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; | 379 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; |
| 409 | } | 380 | } |
| 410 | 381 | ||
| 411 | case Regs::TextureFormat::A8: | 382 | case Regs::TextureFormat::A8: |
| 412 | { | 383 | { |
| 413 | const u8* source_ptr = source + offset + i; | 384 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); |
| 414 | 385 | ||
| 415 | if (disable_alpha) { | 386 | if (disable_alpha) { |
| 416 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; | 387 | return { *source_ptr, *source_ptr, *source_ptr, 255 }; |
| @@ -421,7 +392,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 421 | 392 | ||
| 422 | case Regs::TextureFormat::IA4: | 393 | case Regs::TextureFormat::IA4: |
| 423 | { | 394 | { |
| 424 | const u8* source_ptr = source + offset + i; | 395 | const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); |
| 425 | 396 | ||
| 426 | u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4); | 397 | u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4); |
| 427 | u8 a = Color::Convert4To8((*source_ptr) & 0xF); | 398 | u8 a = Color::Convert4To8((*source_ptr) & 0xF); |
| @@ -436,9 +407,10 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 436 | 407 | ||
| 437 | case Regs::TextureFormat::A4: | 408 | case Regs::TextureFormat::A4: |
| 438 | { | 409 | { |
| 439 | const u8* source_ptr = source + (offset + i) / 2; | 410 | u32 morton_offset = VideoCore::GetMortonOffset(x, y, 1); |
| 411 | const u8* source_ptr = source + morton_offset / 2; | ||
| 440 | 412 | ||
| 441 | u8 a = (i % 2) ? ((*source_ptr & 0xF0) >> 4) : (*source_ptr & 0xF); | 413 | u8 a = (morton_offset % 2) ? ((*source_ptr & 0xF0) >> 4) : (*source_ptr & 0xF); |
| 442 | a = Color::Convert4To8(a); | 414 | a = Color::Convert4To8(a); |
| 443 | 415 | ||
| 444 | if (disable_alpha) { | 416 | if (disable_alpha) { |