[Vulkan] Reworking packed mip offset calculation. Probably breaks everything.
This commit is contained in:
parent
2238ff9ff0
commit
170ab85049
|
@ -59,6 +59,7 @@ bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch,
|
||||||
info.texture_format = static_cast<TextureFormat>(fetch.format);
|
info.texture_format = static_cast<TextureFormat>(fetch.format);
|
||||||
info.endianness = static_cast<Endian>(fetch.endianness);
|
info.endianness = static_cast<Endian>(fetch.endianness);
|
||||||
info.is_tiled = fetch.tiled;
|
info.is_tiled = fetch.tiled;
|
||||||
|
info.has_packed_mips = fetch.packed_mips;
|
||||||
info.mip_address = fetch.mip_address << 12;
|
info.mip_address = fetch.mip_address << 12;
|
||||||
info.mip_levels = fetch.packed_mips ? fetch.mip_max_level + 1 : 1;
|
info.mip_levels = fetch.packed_mips ? fetch.mip_max_level + 1 : 1;
|
||||||
info.input_length = 0; // Populated below.
|
info.input_length = 0; // Populated below.
|
||||||
|
@ -397,12 +398,12 @@ uint32_t TextureInfo::GetMipLocation(const TextureInfo& src, uint32_t mip,
|
||||||
uint32_t* offset_x, uint32_t* offset_y) {
|
uint32_t* offset_x, uint32_t* offset_y) {
|
||||||
if (mip == 0) {
|
if (mip == 0) {
|
||||||
// Short-circuit. Mip 0 is always stored in guest_address.
|
// Short-circuit. Mip 0 is always stored in guest_address.
|
||||||
if (src.mip_levels <= 1) {
|
if (!src.has_packed_mips) {
|
||||||
// Only <= 1 mip level, it can't possibly be offset.
|
*offset_x = 0;
|
||||||
*offset_x = *offset_y = 0;
|
*offset_y = 0;
|
||||||
return src.guest_address;
|
} else {
|
||||||
|
GetPackedTileOffset(src, 0, offset_x, offset_y);
|
||||||
}
|
}
|
||||||
GetPackedTileOffset(src, offset_x, offset_y);
|
|
||||||
return src.guest_address;
|
return src.guest_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +414,18 @@ uint32_t TextureInfo::GetMipLocation(const TextureInfo& src, uint32_t mip,
|
||||||
: src.mip_address;
|
: src.mip_address;
|
||||||
uint32_t address_offset = 0;
|
uint32_t address_offset = 0;
|
||||||
|
|
||||||
|
if (!src.has_packed_mips) {
|
||||||
|
for (uint32_t i = 1; i < mip; i++) {
|
||||||
|
address_offset += GetMipByteSize(src, i);
|
||||||
|
}
|
||||||
|
*offset_x = 0;
|
||||||
|
*offset_y = 0;
|
||||||
|
return address_base + address_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Walk forward to find the address of the mip.
|
// Walk forward to find the address of the mip.
|
||||||
for (uint32_t i = 1; i < mip; i++) {
|
uint32_t packed_mip_base = 1;
|
||||||
|
for (uint32_t i = packed_mip_base; i < mip; i++, packed_mip_base++) {
|
||||||
uint32_t logical_width = std::max(xe::next_pow2(src.width + 1) >> i, 1u);
|
uint32_t logical_width = std::max(xe::next_pow2(src.width + 1) >> i, 1u);
|
||||||
uint32_t logical_height = std::max(xe::next_pow2(src.height + 1) >> i, 1u);
|
uint32_t logical_height = std::max(xe::next_pow2(src.height + 1) >> i, 1u);
|
||||||
if (std::min(logical_width, logical_height) <= 16) {
|
if (std::min(logical_width, logical_height) <= 16) {
|
||||||
|
@ -428,7 +439,7 @@ uint32_t TextureInfo::GetMipLocation(const TextureInfo& src, uint32_t mip,
|
||||||
// Now, check if the mip is packed at an offset.
|
// Now, check if the mip is packed at an offset.
|
||||||
GetPackedTileOffset(xe::next_pow2(src.width + 1) >> mip,
|
GetPackedTileOffset(xe::next_pow2(src.width + 1) >> mip,
|
||||||
xe::next_pow2(src.height + 1) >> mip, src.format_info(),
|
xe::next_pow2(src.height + 1) >> mip, src.format_info(),
|
||||||
offset_x, offset_y);
|
mip - packed_mip_base, offset_x, offset_y);
|
||||||
return address_base + address_offset;
|
return address_base + address_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +490,7 @@ uint32_t TextureInfo::GetMipLinearSize(const TextureInfo& src, uint32_t mip) {
|
||||||
|
|
||||||
bool TextureInfo::GetPackedTileOffset(uint32_t width, uint32_t height,
|
bool TextureInfo::GetPackedTileOffset(uint32_t width, uint32_t height,
|
||||||
const FormatInfo* format_info,
|
const FormatInfo* format_info,
|
||||||
uint32_t* out_offset_x,
|
int packed_tile, uint32_t* out_offset_x,
|
||||||
uint32_t* out_offset_y) {
|
uint32_t* out_offset_y) {
|
||||||
// Tile size is 32x32, and once textures go <=16 they are packed into a
|
// Tile size is 32x32, and once textures go <=16 they are packed into a
|
||||||
// single tile together. The math here is insane. Most sourced
|
// single tile together. The math here is insane. Most sourced
|
||||||
|
@ -526,14 +537,26 @@ bool TextureInfo::GetPackedTileOffset(uint32_t width, uint32_t height,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the block offset of the mip.
|
// Find the block offset of the mip.
|
||||||
if (log2_width > log2_height) {
|
if (packed_tile < 3) {
|
||||||
// Wider than tall. Laid out vertically.
|
if (log2_width > log2_height) {
|
||||||
*out_offset_y = log2_height > 0x1 ? 1 << log2_height : 0;
|
// Wider than tall. Laid out vertically.
|
||||||
*out_offset_x = log2_height <= 0x1 ? 1 << (log2_width + 2) : 0;
|
*out_offset_x = 0;
|
||||||
|
*out_offset_y = 16 >> packed_tile;
|
||||||
|
} else {
|
||||||
|
// Taller than wide. Laid out horizontally.
|
||||||
|
*out_offset_x = 16 >> packed_tile;
|
||||||
|
*out_offset_y = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Taller than wide. Laid out horizontally.
|
if (log2_width > log2_height) {
|
||||||
*out_offset_x = log2_width > 0x1 ? 1 << log2_width : 0;
|
// Wider than tall. Laid out vertically.
|
||||||
*out_offset_y = log2_width <= 0x1 ? 1 << (log2_height + 2) : 0;
|
*out_offset_x = 16 >> (packed_tile - 2);
|
||||||
|
*out_offset_y = 0;
|
||||||
|
} else {
|
||||||
|
// Taller than wide. Laid out horizontally.
|
||||||
|
*out_offset_x = 0;
|
||||||
|
*out_offset_y = 16 >> (packed_tile - 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_offset_x /= format_info->block_width;
|
*out_offset_x /= format_info->block_width;
|
||||||
|
@ -542,12 +565,17 @@ bool TextureInfo::GetPackedTileOffset(uint32_t width, uint32_t height,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureInfo::GetPackedTileOffset(const TextureInfo& texture_info,
|
bool TextureInfo::GetPackedTileOffset(const TextureInfo& texture_info,
|
||||||
uint32_t* out_offset_x,
|
int packed_tile, uint32_t* out_offset_x,
|
||||||
uint32_t* out_offset_y) {
|
uint32_t* out_offset_y) {
|
||||||
|
if (!texture_info.has_packed_mips) {
|
||||||
|
*out_offset_x = 0;
|
||||||
|
*out_offset_y = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return GetPackedTileOffset(xe::next_pow2(texture_info.size.logical_width),
|
return GetPackedTileOffset(xe::next_pow2(texture_info.size.logical_width),
|
||||||
xe::next_pow2(texture_info.size.logical_height),
|
xe::next_pow2(texture_info.size.logical_height),
|
||||||
texture_info.format_info(), out_offset_x,
|
texture_info.format_info(), packed_tile,
|
||||||
out_offset_y);
|
out_offset_x, out_offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/BinomialLLC/crunch/blob/ea9b8d8c00c8329791256adafa8cf11e4e7942a2/inc/crn_decomp.h#L4108
|
// https://github.com/BinomialLLC/crunch/blob/ea9b8d8c00c8329791256adafa8cf11e4e7942a2/inc/crn_decomp.h#L4108
|
||||||
|
|
|
@ -255,6 +255,7 @@ struct TextureInfo {
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
Endian endianness;
|
Endian endianness;
|
||||||
bool is_tiled;
|
bool is_tiled;
|
||||||
|
bool has_packed_mips;
|
||||||
uint32_t mip_address;
|
uint32_t mip_address;
|
||||||
uint32_t mip_levels;
|
uint32_t mip_levels;
|
||||||
uint32_t input_length;
|
uint32_t input_length;
|
||||||
|
@ -306,10 +307,10 @@ struct TextureInfo {
|
||||||
|
|
||||||
static bool GetPackedTileOffset(uint32_t width, uint32_t height,
|
static bool GetPackedTileOffset(uint32_t width, uint32_t height,
|
||||||
const FormatInfo* format_info,
|
const FormatInfo* format_info,
|
||||||
uint32_t* out_offset_x,
|
int packed_tile, uint32_t* out_offset_x,
|
||||||
uint32_t* out_offset_y);
|
uint32_t* out_offset_y);
|
||||||
static bool GetPackedTileOffset(const TextureInfo& texture_info,
|
static bool GetPackedTileOffset(const TextureInfo& texture_info,
|
||||||
uint32_t* out_offset_x,
|
int packed_tile, uint32_t* out_offset_x,
|
||||||
uint32_t* out_offset_y);
|
uint32_t* out_offset_y);
|
||||||
static uint32_t TiledOffset2DOuter(uint32_t y, uint32_t width,
|
static uint32_t TiledOffset2DOuter(uint32_t y, uint32_t width,
|
||||||
uint32_t log2_bpp);
|
uint32_t log2_bpp);
|
||||||
|
|
Loading…
Reference in New Issue