Last active
March 6, 2019 20:52
-
-
Save Triang3l/28bcb9889b2821bdd91e89c4d45d5d4f to your computer and use it in GitHub Desktop.
3D texture tiling for Xenia, reversed from XGAddress(Volume?)TiledOffset from XGRAPHICS::TileVolume
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static uint32_t TiledOffset3D(uint32_t x, uint32_t y, uint32_t z, | |
uint32_t pitch_h, uint32_t pitch_v, | |
uint32_t log2_bpp) { | |
// Reconstructed from disassembly of XGRAPHICS::TileVolume. | |
uint32_t macro_outer = | |
((y >> 4) + (z >> 2) * (pitch_v >> 4)) * (pitch_h >> 5); | |
uint32_t macro = | |
((((x >> 5) + macro_outer) << (log2_bpp + 6)) & 0xFFFFFFF) << 1; | |
uint32_t micro = (((x & 7) + ((y & 6) << 2)) << (log2_bpp + 6)) >> 6; | |
uint32_t offset_outer = ((y >> 3) + (z >> 2)) & 1; | |
uint32_t offset1 = | |
offset_outer + ((((x >> 3) + (offset_outer << 1)) & 3) << 1); | |
uint32_t offset2 = | |
((macro + (micro & ~15)) << 1) + (micro & 15) + | |
((z & 3) << (log2_bpp + 6)) + ((y & 1) << 4); | |
uint32_t address = (offset1 & 1) << 3; | |
address += (int32_t(offset2) >> 6) & 7; | |
address <<= 3; | |
address += offset1 & ~1; | |
address <<= 2; | |
address += offset2 & ~511; | |
address <<= 3; | |
address += offset2 & 63; | |
return address; | |
} | |
// Usage in Xenia: | |
if (untile_info->volume) { | |
uint32_t output_slice_pitch = untile_info->output_pitch_v * output_pitch; | |
uint32_t output_slice_offset = 0; | |
for (uint32_t z = 0; z < untile_info->depth; z++) { | |
uint32_t output_row_offset = output_slice_offset; | |
for (uint32_t y = 0; y < untile_info->height; y++) { | |
uint32_t output_offset = output_row_offset; | |
for (uint32_t x = 0; x < untile_info->width; x++) { | |
auto input_offset = TiledOffset3D(untile_info->offset_x + x, | |
untile_info->offset_y + y, | |
untile_info->offset_z + z, | |
untile_info->input_pitch_h, | |
untile_info->input_pitch_v, log2_bpp); | |
untile_info->copy_callback(&output_buffer[output_offset], | |
&input_buffer[input_offset], | |
output_bytes_per_block); | |
output_offset += output_bytes_per_block; | |
} | |
output_row_offset += output_pitch; | |
} | |
output_slice_offset += output_slice_pitch; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment