From f0e902a7d6df72531fbd01d27756f9875dc3c65d Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 26 Oct 2018 19:18:03 -0400 Subject: [PATCH] Fixed mipmap block autosizing algorithm --- .../renderer_opengl/gl_rasterizer_cache.cpp | 8 +++---- .../renderer_opengl/gl_rasterizer_cache.h | 24 ++++++++++++------- src/video_core/textures/decoders.h | 6 +++++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 4d89d0f671..b2250e6bed 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -103,7 +103,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b ? m_height : std::max(1U, (m_height + compression_factor - 1) / compression_factor); 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); return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width, 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, 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; for (u32 i = 0; i < max_mip_level; i++) { size += InnerMipmapMemorySize(i, force_gl, layer_only, uncompressed); @@ -1043,8 +1043,8 @@ void CachedSurface::FlushGLBuffer() { glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(params.width)); ASSERT(!tuple.compressed); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, static_cast(gl_buffer[0].size()), - gl_buffer[0].data()); + glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, + static_cast(gl_buffer[0].size()), gl_buffer[0].data()); glPixelStorei(GL_PACK_ROW_LENGTH, 0); ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width, params.height); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 951e03ba60..15ac4a1b16 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -917,14 +917,14 @@ struct SurfaceParams { // Auto block resizing algorithm from: // 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) return block_height; - if (alt_height == 0) - alt_height = MipHeight(mip_level); - u32 blocks_in_y = (alt_height + 7) / 8; - u32 bh = 32; - while (bh > 1 && blocks_in_y <= bh * 2) { + u32 alt_height = MipHeight(mip_level); + u32 h = GetDefaultBlockHeight(pixel_format); + u32 blocks_in_y = (alt_height + h - 1) / h; + u32 bh = 16; + while (bh > 1 && blocks_in_y <= bh * 4) { bh >>= 1; } return bh; @@ -933,11 +933,17 @@ struct SurfaceParams { u32 MipBlockDepth(u32 mip_level) const { if (mip_level == 0) return block_depth; + if (is_layered) + return 1; u32 depth = MipDepth(mip_level); u32 bd = 32; - // Magical block resizing algorithm, needs more testing. - while (bd > 1 && depth / depth <= bd) { - bd = bd >> 1; + while (bd > 1 && depth * 2 <= bd) { + bd >>= 1; + } + if (bd == 32) { + u32 bh = MipBlockHeight(mip_level); + if (bh >= 4) + return 16; } return bd; } diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 4726f54a5e..b390219e4b 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -10,6 +10,12 @@ 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. */