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 type; | ||||
|     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 = {{ | ||||
|     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1},                     // ABGR8
 | ||||
|     {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1},                        // B5G6R5
 | ||||
|     {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1},               // A2B10G10R10
 | ||||
|     {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16},   // DXT1
 | ||||
|     {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23
 | ||||
|     {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45
 | ||||
|     {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},                       // B5G6R5
 | ||||
|     {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},   // DXT1
 | ||||
|     {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}, // DXT45
 | ||||
| }}; | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|     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]); | ||||
|     } | ||||
| 
 | ||||
| @ -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, | ||||
|                     bytes_per_pixel * width * height); | ||||
|     } else { | ||||
|         morton_to_gl_fns[static_cast<size_t>(pixel_format)]( | ||||
|             stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); | ||||
|         morton_to_gl_fns[static_cast<size_t>(pixel_format)](GetActualWidth(), block_height, | ||||
|                                                             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); | ||||
| 
 | ||||
|     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
 | ||||
|     GLint x0 = static_cast<GLint>(rect.left); | ||||
| @ -583,11 +582,9 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | ||||
|     glActiveTexture(GL_TEXTURE0); | ||||
|     if (tuple.compressed) { | ||||
|         glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, | ||||
|                                static_cast<GLsizei>(rect.GetWidth()), | ||||
|                                static_cast<GLsizei>(rect.GetHeight()), 0, | ||||
|                                rect.GetWidth() * rect.GetHeight() * | ||||
|                                    GetGLBytesPerPixel(pixel_format) / tuple.compression_factor, | ||||
|                                &gl_buffer[buffer_offset]); | ||||
|                                static_cast<GLsizei>(rect.GetWidth() * GetCompresssionFactor()), | ||||
|                                static_cast<GLsizei>(rect.GetHeight() * GetCompresssionFactor()), 0, | ||||
|                                size, &gl_buffer[buffer_offset]); | ||||
|     } else { | ||||
|         glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), | ||||
|                         static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | ||||
| @ -1041,10 +1038,10 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | ||||
| 
 | ||||
|     SurfaceParams params; | ||||
|     params.addr = config.tic.Address(); | ||||
|     params.width = config.tic.Width(); | ||||
|     params.height = config.tic.Height(); | ||||
|     params.is_tiled = config.tic.IsTiled(); | ||||
|     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.
 | ||||
|     ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && | ||||
|  | ||||
| @ -84,23 +84,49 @@ struct SurfaceParams { | ||||
|         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) | ||||
|             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
 | ||||
|             16,  // B5G6R5
 | ||||
|             32,  // A2B10G10R10
 | ||||
|             64,  // DXT1
 | ||||
|             128, // DXT23
 | ||||
|             128, // DXT45
 | ||||
|         }; | ||||
|         }}; | ||||
| 
 | ||||
|         ASSERT(static_cast<size_t>(format) < bpp_table.size()); | ||||
|         return bpp_table[static_cast<size_t>(format)]; | ||||
|     } | ||||
|     unsigned int GetFormatBpp() const { | ||||
|     u32 GetFormatBpp() const { | ||||
|         return GetFormatBpp(pixel_format); | ||||
|     } | ||||
| 
 | ||||
| @ -255,6 +281,24 @@ struct SurfaceParams { | ||||
|     // Returns the region of the biggest valid rectange within interval
 | ||||
|     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 { | ||||
|         return width * res_scale; | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei