summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDr. Chat <arkolbed@gmail.com>2018-05-03 16:04:11 -0500
committerDr. Chat <arkolbed@gmail.com>2018-05-03 16:04:11 -0500
commit04748b4a0da431613823157e112017a5bdcd4c8e (patch)
treebca8d646490d0b23d3905f372fdb78aa54486120
parent5e4b696782aa4208ee4fff6b7a6fd56521f94b0e (diff)
[GPU] TextureInfo::GetMipLocation - calculate packed mip offset
-rw-r--r--src/xenia/gpu/texture_info.cc24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/xenia/gpu/texture_info.cc b/src/xenia/gpu/texture_info.cc
index 4f8926f50..9c93a7872 100644
--- a/src/xenia/gpu/texture_info.cc
+++ b/src/xenia/gpu/texture_info.cc
@@ -350,18 +350,34 @@ uint32_t TextureInfo::GetMipLocation(const TextureInfo& src, uint32_t mip,
: src.mip_address;
uint32_t address_offset = 0;
+ uint32_t logical_width = std::max((src.width + 1) >> mip, 1u);
+ uint32_t logical_height = std::max((src.height + 1) >> mip, 1u);
for (uint32_t i = 1; i < mip; i++) {
- uint32_t logical_width = std::max((src.width + 1) >> mip, 1u);
- uint32_t logical_height = std::max((src.height + 1) >> mip, 1u);
if (std::min(logical_width, logical_height) < 16) {
// We've reached the point where the mips are packed into a single tile.
- // TODO(DrChat): Figure out how to calculate the packed tile offset.
- continue;
+ break;
}
address_offset += std::max(src.input_length >> (i * 2), tile_size);
}
+ *offset_x = 0;
+ *offset_y = 0;
+ if (std::min(logical_width, logical_height) <= 16) {
+ // Find the block offset of the mip.
+ if (xe::log2_ceil(logical_width) > xe::log2_ceil(logical_height)) {
+ // Wider than tall. Laid out vertically.
+ *offset_y = logical_height & ~0x3;
+ *offset_x = (logical_height & 0x3) << 2;
+ } else {
+ // Taller than wide. Laid out horizontally.
+ *offset_x = logical_width & ~0x3;
+ *offset_y = (logical_width & 0x3) << 2;
+ }
+ }
+
+ *offset_x /= src.format_info()->block_width;
+ *offset_y /= src.format_info()->block_height;
return address_base + address_offset;
}