forked from eden-emu/eden
		
	Fixed mipmap block autosizing algorithm
This commit is contained in:
		
							parent
							
								
									c9f347e156
								
							
						
					
					
						commit
						be78be20dc
					
				
					 3 changed files with 25 additions and 13 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 FernandoS27
						FernandoS27