From bbf3b2da0cee61ee99cdc42d08543881640990e4 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Wed, 24 Oct 2018 18:30:27 -0400 Subject: Implement Mipmaps --- .../renderer_opengl/gl_rasterizer_cache.h | 72 +++++++++++++++++++--- 1 file changed, 65 insertions(+), 7 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index be8c00e99..5bcd33156 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -834,7 +834,7 @@ struct SurfaceParams { } /// Returns the rectangle corresponding to this surface - MathUtil::Rectangle GetRect() const; + MathUtil::Rectangle GetRect(u32 mip_level = 0) const; /// Returns the total size of this surface in bytes, adjusted for compression std::size_t SizeInBytesRaw(bool ignore_tiled = false) const { @@ -865,7 +865,7 @@ struct SurfaceParams { /// Returns the exact size of memory occupied by the texture in VRAM, including mipmaps. std::size_t MemorySize() const { - std::size_t size = InnerMemorySize(is_layered); + std::size_t size = InnerMemorySize(false, is_layered); if (is_layered) return size * depth; return size; @@ -874,12 +874,65 @@ struct SurfaceParams { /// Returns the exact size of the memory occupied by a layer in a texture in VRAM, including /// mipmaps. std::size_t LayerMemorySize() const { - return InnerMemorySize(true); + return InnerMemorySize(false, true); } /// Returns the size of a layer of this surface in OpenGL. - std::size_t LayerSizeGL() const { - return SizeInBytesRaw(true) / depth; + std::size_t LayerSizeGL(u32 mip_level) const { + return InnerMipmapMemorySize(mip_level, true, is_layered, false); + } + + std::size_t GetMipmapSizeGL(u32 mip_level, bool ignore_compressed = true) const { + std::size_t size = InnerMipmapMemorySize(mip_level, true, is_layered, ignore_compressed); + if (is_layered) + return size * depth; + return size; + } + + std::size_t GetMipmapLevelOffset(u32 mip_level) const { + std::size_t offset = 0; + for (u32 i = 0; i < mip_level; i++) + offset += InnerMipmapMemorySize(i, false, is_layered); + return offset; + } + + std::size_t GetMipmapLevelOffsetGL(u32 mip_level) const { + std::size_t offset = 0; + for (u32 i = 0; i < mip_level; i++) + offset += InnerMipmapMemorySize(i, true, is_layered); + return offset; + } + + u32 MipWidth(u32 mip_level) const { + return std::max(1U, width >> mip_level); + } + + u32 MipHeight(u32 mip_level) const { + return std::max(1U, height >> mip_level); + } + + u32 MipDepth(u32 mip_level) const { + return std::max(1U, depth >> mip_level); + } + + u32 MipBlockHeight(u32 mip_level) const { + u32 height = MipHeight(mip_level); + u32 bh = block_height; + // Magical block resizing algorithm, needs more testing. + while (bh != 1 && height / bh <= 16) { + bh = bh >> 1; + } + return bh; + } + + u32 MipBlockDepth(u32 mip_level) const { + u32 depth = MipDepth(mip_level); + u32 bd = block_depth; + // Magical block resizing algorithm, needs more testing. + while (bd != 1 && depth / bd <= 16) { + bd = bd >> 1; + } + return bd; } /// Creates SurfaceParams from a texture configuration @@ -940,7 +993,10 @@ struct SurfaceParams { } rt; private: - std::size_t InnerMemorySize(bool layer_only = false) const; + std::size_t InnerMipmapMemorySize(u32 mip_level, bool force_gl = false, bool layer_only = false, + bool uncompressed = false) const; + std::size_t InnerMemorySize(bool force_gl = false, bool layer_only = false, + bool uncompressed = false) const; }; }; // namespace OpenGL @@ -1002,8 +1058,10 @@ public: void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle); private: + void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); + OGLTexture texture; - std::vector gl_buffer; + std::vector> gl_buffer; SurfaceParams params; GLenum gl_target; std::size_t cached_size_in_bytes; -- cgit v1.2.3 From 258f0f5c31decbb25eddde798b3a4bcc6a7cc6dd Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Wed, 24 Oct 2018 19:25:28 -0400 Subject: Implement Mip Filter --- src/video_core/renderer_opengl/gl_rasterizer_cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 5bcd33156..68479d55a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -919,7 +919,7 @@ struct SurfaceParams { u32 height = MipHeight(mip_level); u32 bh = block_height; // Magical block resizing algorithm, needs more testing. - while (bh != 1 && height / bh <= 16) { + while (bh > 1 && (height + bh - 1) / bh <= 16) { bh = bh >> 1; } return bh; @@ -929,7 +929,7 @@ struct SurfaceParams { u32 depth = MipDepth(mip_level); u32 bd = block_depth; // Magical block resizing algorithm, needs more testing. - while (bd != 1 && depth / bd <= 16) { + while (bd > 1 && depth / bd <= 16) { bd = bd >> 1; } return bd; -- cgit v1.2.3 From f4432b5d0cb0cb89ff4af8172720f7457514d981 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Thu, 25 Oct 2018 12:24:10 -0400 Subject: Fixed Block Resizing algorithm and Clang Format --- .../renderer_opengl/gl_rasterizer_cache.h | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 68479d55a..951e03ba6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -915,21 +915,28 @@ struct SurfaceParams { return std::max(1U, depth >> mip_level); } - u32 MipBlockHeight(u32 mip_level) const { - u32 height = MipHeight(mip_level); - u32 bh = block_height; - // Magical block resizing algorithm, needs more testing. - while (bh > 1 && (height + bh - 1) / bh <= 16) { - bh = bh >> 1; + // 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 { + 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) { + bh >>= 1; } return bh; } u32 MipBlockDepth(u32 mip_level) const { + if (mip_level == 0) + return block_depth; u32 depth = MipDepth(mip_level); - u32 bd = block_depth; + u32 bd = 32; // Magical block resizing algorithm, needs more testing. - while (bd > 1 && depth / bd <= 16) { + while (bd > 1 && depth / depth <= bd) { bd = bd >> 1; } return bd; -- cgit v1.2.3 From f0e902a7d6df72531fbd01d27756f9875dc3c65d Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 26 Oct 2018 19:18:03 -0400 Subject: Fixed mipmap block autosizing algorithm --- .../renderer_opengl/gl_rasterizer_cache.h | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 951e03ba6..15ac4a1b1 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; } -- cgit v1.2.3