mirror of https://git.suyu.dev/suyu/suyu
Fixed mipmap block autosizing algorithm
This commit is contained in:
parent
87f8181405
commit
f0e902a7d6
|
@ -103,7 +103,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b
|
||||||
? m_height
|
? m_height
|
||||||
: std::max(1U, (m_height + compression_factor - 1) / compression_factor);
|
: std::max(1U, (m_height + compression_factor - 1) / compression_factor);
|
||||||
m_depth = std::max(1U, m_depth >> mip_level);
|
m_depth = std::max(1U, m_depth >> mip_level);
|
||||||
u32 m_block_height = MipBlockHeight(mip_level, m_height);
|
u32 m_block_height = MipBlockHeight(mip_level);
|
||||||
u32 m_block_depth = MipBlockDepth(mip_level);
|
u32 m_block_depth = MipBlockDepth(mip_level);
|
||||||
return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width,
|
return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width,
|
||||||
m_height, m_depth, m_block_height, m_block_depth);
|
m_height, m_depth, m_block_height, m_block_depth);
|
||||||
|
@ -111,7 +111,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b
|
||||||
|
|
||||||
std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
|
std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
|
||||||
bool uncompressed) const {
|
bool uncompressed) const {
|
||||||
std::size_t block_size_bytes = 512 * block_height * block_depth; // 512 is GOB size
|
std::size_t block_size_bytes = Tegra::Texture::GetGOBSize() * block_height * block_depth;
|
||||||
std::size_t size = 0;
|
std::size_t size = 0;
|
||||||
for (u32 i = 0; i < max_mip_level; i++) {
|
for (u32 i = 0; i < max_mip_level; i++) {
|
||||||
size += InnerMipmapMemorySize(i, force_gl, layer_only, uncompressed);
|
size += InnerMipmapMemorySize(i, force_gl, layer_only, uncompressed);
|
||||||
|
@ -1043,8 +1043,8 @@ void CachedSurface::FlushGLBuffer() {
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width));
|
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width));
|
||||||
ASSERT(!tuple.compressed);
|
ASSERT(!tuple.compressed);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, static_cast<GLsizei>(gl_buffer[0].size()),
|
glGetTextureImage(texture.handle, 0, tuple.format, tuple.type,
|
||||||
gl_buffer[0].data());
|
static_cast<GLsizei>(gl_buffer[0].size()), gl_buffer[0].data());
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width,
|
ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width,
|
||||||
params.height);
|
params.height);
|
||||||
|
|
|
@ -917,14 +917,14 @@ struct SurfaceParams {
|
||||||
|
|
||||||
// Auto block resizing algorithm from:
|
// Auto block resizing algorithm from:
|
||||||
// https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
|
// https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
|
||||||
u32 MipBlockHeight(u32 mip_level, u32 alt_height = 0) const {
|
u32 MipBlockHeight(u32 mip_level) const {
|
||||||
if (mip_level == 0)
|
if (mip_level == 0)
|
||||||
return block_height;
|
return block_height;
|
||||||
if (alt_height == 0)
|
u32 alt_height = MipHeight(mip_level);
|
||||||
alt_height = MipHeight(mip_level);
|
u32 h = GetDefaultBlockHeight(pixel_format);
|
||||||
u32 blocks_in_y = (alt_height + 7) / 8;
|
u32 blocks_in_y = (alt_height + h - 1) / h;
|
||||||
u32 bh = 32;
|
u32 bh = 16;
|
||||||
while (bh > 1 && blocks_in_y <= bh * 2) {
|
while (bh > 1 && blocks_in_y <= bh * 4) {
|
||||||
bh >>= 1;
|
bh >>= 1;
|
||||||
}
|
}
|
||||||
return bh;
|
return bh;
|
||||||
|
@ -933,11 +933,17 @@ struct SurfaceParams {
|
||||||
u32 MipBlockDepth(u32 mip_level) const {
|
u32 MipBlockDepth(u32 mip_level) const {
|
||||||
if (mip_level == 0)
|
if (mip_level == 0)
|
||||||
return block_depth;
|
return block_depth;
|
||||||
|
if (is_layered)
|
||||||
|
return 1;
|
||||||
u32 depth = MipDepth(mip_level);
|
u32 depth = MipDepth(mip_level);
|
||||||
u32 bd = 32;
|
u32 bd = 32;
|
||||||
// Magical block resizing algorithm, needs more testing.
|
while (bd > 1 && depth * 2 <= bd) {
|
||||||
while (bd > 1 && depth / depth <= bd) {
|
bd >>= 1;
|
||||||
bd = bd >> 1;
|
}
|
||||||
|
if (bd == 32) {
|
||||||
|
u32 bh = MipBlockHeight(mip_level);
|
||||||
|
if (bh >= 4)
|
||||||
|
return 16;
|
||||||
}
|
}
|
||||||
return bd;
|
return bd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
|
|
||||||
namespace Tegra::Texture {
|
namespace Tegra::Texture {
|
||||||
|
|
||||||
|
// GOBSize constant. Calculated by 64 bytes in x multiplied by 8 y coords, represents
|
||||||
|
// an small rect of (64/bytes_per_pixel)X8.
|
||||||
|
inline std::size_t GetGOBSize() {
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unswizzles a swizzled texture without changing its format.
|
* Unswizzles a swizzled texture without changing its format.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue