Skip to content

Instantly share code, notes, and snippets.

@Triang3l
Last active March 6, 2019 20:52
Show Gist options
  • Save Triang3l/28bcb9889b2821bdd91e89c4d45d5d4f to your computer and use it in GitHub Desktop.
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
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