mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	gl_rasterizer_cache: Handle compressed texture sizes.
This commit is contained in:
		
							parent
							
								
									4415e00181
								
							
						
					
					
						commit
						bc0f1896fc
					
				| @ -41,18 +41,15 @@ struct FormatTuple { | |||||||
|     GLenum format; |     GLenum format; | ||||||
|     GLenum type; |     GLenum type; | ||||||
|     bool compressed; |     bool compressed; | ||||||
|     // How many pixels in the original texture are equivalent to one pixel in the compressed
 |  | ||||||
|     // texture.
 |  | ||||||
|     u32 compression_factor; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | ||||||
|     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1},                     // ABGR8
 |     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false},                    // ABGR8
 | ||||||
|     {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1},                        // B5G6R5
 |     {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false},                       // B5G6R5
 | ||||||
|     {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1},               // A2B10G10R10
 |     {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false},              // A2B10G10R10
 | ||||||
|     {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16},   // DXT1
 |     {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true},   // DXT1
 | ||||||
|     {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23
 |     {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23
 | ||||||
|     {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45
 |     {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45
 | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
| static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | ||||||
| @ -476,7 +473,7 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa | |||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     if (gl_buffer == nullptr) { |     if (gl_buffer == nullptr) { | ||||||
|         gl_buffer_size = width * height * GetGLBytesPerPixel(pixel_format); |         gl_buffer_size = GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format); | ||||||
|         gl_buffer.reset(new u8[gl_buffer_size]); |         gl_buffer.reset(new u8[gl_buffer_size]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -491,8 +488,9 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa | |||||||
|         std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, |         std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, | ||||||
|                     bytes_per_pixel * width * height); |                     bytes_per_pixel * width * height); | ||||||
|     } else { |     } else { | ||||||
|         morton_to_gl_fns[static_cast<size_t>(pixel_format)]( |         morton_to_gl_fns[static_cast<size_t>(pixel_format)](GetActualWidth(), block_height, | ||||||
|             stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); |                                                             GetActualHeight(), &gl_buffer[0], addr, | ||||||
|  |                                                             load_start, load_end); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -548,7 +546,8 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||||||
| 
 | 
 | ||||||
|     MICROPROFILE_SCOPE(OpenGL_TextureUL); |     MICROPROFILE_SCOPE(OpenGL_TextureUL); | ||||||
| 
 | 
 | ||||||
|     ASSERT(gl_buffer_size == width * height * GetGLBytesPerPixel(pixel_format)); |     ASSERT(gl_buffer_size == | ||||||
|  |            GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format)); | ||||||
| 
 | 
 | ||||||
|     // Load data from memory to the surface
 |     // Load data from memory to the surface
 | ||||||
|     GLint x0 = static_cast<GLint>(rect.left); |     GLint x0 = static_cast<GLint>(rect.left); | ||||||
| @ -583,11 +582,9 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||||||
|     glActiveTexture(GL_TEXTURE0); |     glActiveTexture(GL_TEXTURE0); | ||||||
|     if (tuple.compressed) { |     if (tuple.compressed) { | ||||||
|         glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, |         glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, | ||||||
|                                static_cast<GLsizei>(rect.GetWidth()), |                                static_cast<GLsizei>(rect.GetWidth() * GetCompresssionFactor()), | ||||||
|                                static_cast<GLsizei>(rect.GetHeight()), 0, |                                static_cast<GLsizei>(rect.GetHeight() * GetCompresssionFactor()), 0, | ||||||
|                                rect.GetWidth() * rect.GetHeight() * |                                size, &gl_buffer[buffer_offset]); | ||||||
|                                    GetGLBytesPerPixel(pixel_format) / tuple.compression_factor, |  | ||||||
|                                &gl_buffer[buffer_offset]); |  | ||||||
|     } else { |     } else { | ||||||
|         glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), |         glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), | ||||||
|                         static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, |                         static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | ||||||
| @ -1041,10 +1038,10 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||||||
| 
 | 
 | ||||||
|     SurfaceParams params; |     SurfaceParams params; | ||||||
|     params.addr = config.tic.Address(); |     params.addr = config.tic.Address(); | ||||||
|     params.width = config.tic.Width(); |  | ||||||
|     params.height = config.tic.Height(); |  | ||||||
|     params.is_tiled = config.tic.IsTiled(); |     params.is_tiled = config.tic.IsTiled(); | ||||||
|     params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); |     params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); | ||||||
|  |     params.width = config.tic.Width() / params.GetCompresssionFactor(); | ||||||
|  |     params.height = config.tic.Height() / params.GetCompresssionFactor(); | ||||||
| 
 | 
 | ||||||
|     // TODO(Subv): Different types per component are not supported.
 |     // TODO(Subv): Different types per component are not supported.
 | ||||||
|     ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && |     ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && | ||||||
|  | |||||||
| @ -84,23 +84,49 @@ struct SurfaceParams { | |||||||
|         Invalid = 4, |         Invalid = 4, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     static constexpr unsigned int GetFormatBpp(PixelFormat format) { |     /**
 | ||||||
|  |      * Gets the compression factor for the specified PixelFormat. This applies to just the | ||||||
|  |      * "compressed width" and "compressed height", not the overall compression factor of a | ||||||
|  |      * compressed image. This is used for maintaining proper surface sizes for compressed texture | ||||||
|  |      * formats. | ||||||
|  |      */ | ||||||
|  |     static constexpr u32 GetCompresssionFactor(PixelFormat format) { | ||||||
|         if (format == PixelFormat::Invalid) |         if (format == PixelFormat::Invalid) | ||||||
|             return 0; |             return 0; | ||||||
| 
 | 
 | ||||||
|         constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = { |         constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ | ||||||
|  |             1, // ABGR8
 | ||||||
|  |             1, // B5G6R5
 | ||||||
|  |             1, // A2B10G10R10
 | ||||||
|  |             4, // DXT1
 | ||||||
|  |             4, // DXT23
 | ||||||
|  |             4, // DXT45
 | ||||||
|  |         }}; | ||||||
|  | 
 | ||||||
|  |         ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); | ||||||
|  |         return compression_factor_table[static_cast<size_t>(format)]; | ||||||
|  |     } | ||||||
|  |     u32 GetCompresssionFactor() const { | ||||||
|  |         return GetCompresssionFactor(pixel_format); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static constexpr u32 GetFormatBpp(PixelFormat format) { | ||||||
|  |         if (format == PixelFormat::Invalid) | ||||||
|  |             return 0; | ||||||
|  | 
 | ||||||
|  |         constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ | ||||||
|             32,  // ABGR8
 |             32,  // ABGR8
 | ||||||
|             16,  // B5G6R5
 |             16,  // B5G6R5
 | ||||||
|             32,  // A2B10G10R10
 |             32,  // A2B10G10R10
 | ||||||
|             64,  // DXT1
 |             64,  // DXT1
 | ||||||
|             128, // DXT23
 |             128, // DXT23
 | ||||||
|             128, // DXT45
 |             128, // DXT45
 | ||||||
|         }; |         }}; | ||||||
| 
 | 
 | ||||||
|         ASSERT(static_cast<size_t>(format) < bpp_table.size()); |         ASSERT(static_cast<size_t>(format) < bpp_table.size()); | ||||||
|         return bpp_table[static_cast<size_t>(format)]; |         return bpp_table[static_cast<size_t>(format)]; | ||||||
|     } |     } | ||||||
|     unsigned int GetFormatBpp() const { |     u32 GetFormatBpp() const { | ||||||
|         return GetFormatBpp(pixel_format); |         return GetFormatBpp(pixel_format); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -255,6 +281,24 @@ struct SurfaceParams { | |||||||
|     // Returns the region of the biggest valid rectange within interval
 |     // Returns the region of the biggest valid rectange within interval
 | ||||||
|     SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; |     SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Gets the actual width (in pixels) of the surface. This is provided because `width` is used | ||||||
|  |      * for tracking the surface region in memory, which may be compressed for certain formats. In | ||||||
|  |      * this scenario, `width` is actually the compressed width. | ||||||
|  |      */ | ||||||
|  |     u32 GetActualWidth() const { | ||||||
|  |         return width * GetCompresssionFactor(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Gets the actual height (in pixels) of the surface. This is provided because `height` is used | ||||||
|  |      * for tracking the surface region in memory, which may be compressed for certain formats. In | ||||||
|  |      * this scenario, `height` is actually the compressed height. | ||||||
|  |      */ | ||||||
|  |     u32 GetActualHeight() const { | ||||||
|  |         return height * GetCompresssionFactor(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     u32 GetScaledWidth() const { |     u32 GetScaledWidth() const { | ||||||
|         return width * res_scale; |         return width * res_scale; | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei