mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	Fix image update/download error when width too small
This commit is contained in:
		
							parent
							
								
									71313509f7
								
							
						
					
					
						commit
						894cc9d876
					
				| @ -317,13 +317,12 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_format) { | ||||
| OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_format, | ||||
|                      GLsizei gl_num_levels) { | ||||
|     const GLenum target = ImageTarget(info); | ||||
|     const GLsizei width = info.size.width; | ||||
|     const GLsizei height = info.size.height; | ||||
|     const GLsizei depth = info.size.depth; | ||||
|     const int max_host_mip_levels = std::bit_width(info.size.width); | ||||
|     const GLsizei num_levels = std::min(info.resources.levels, max_host_mip_levels); | ||||
|     const GLsizei num_layers = info.resources.layers; | ||||
|     const GLsizei num_samples = info.num_samples; | ||||
| 
 | ||||
| @ -335,10 +334,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form | ||||
|     } | ||||
|     switch (target) { | ||||
|     case GL_TEXTURE_1D_ARRAY: | ||||
|         glTextureStorage2D(handle, num_levels, gl_internal_format, width, num_layers); | ||||
|         glTextureStorage2D(handle, gl_num_levels, gl_internal_format, width, num_layers); | ||||
|         break; | ||||
|     case GL_TEXTURE_2D_ARRAY: | ||||
|         glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, num_layers); | ||||
|         glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, num_layers); | ||||
|         break; | ||||
|     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { | ||||
|         // TODO: Where should 'fixedsamplelocations' come from?
 | ||||
| @ -348,10 +347,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form | ||||
|         break; | ||||
|     } | ||||
|     case GL_TEXTURE_RECTANGLE: | ||||
|         glTextureStorage2D(handle, num_levels, gl_internal_format, width, height); | ||||
|         glTextureStorage2D(handle, gl_num_levels, gl_internal_format, width, height); | ||||
|         break; | ||||
|     case GL_TEXTURE_3D: | ||||
|         glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, depth); | ||||
|         glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth); | ||||
|         break; | ||||
|     case GL_TEXTURE_BUFFER: | ||||
|         UNREACHABLE(); | ||||
| @ -686,7 +685,9 @@ Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, | ||||
|         gl_format = tuple.format; | ||||
|         gl_type = tuple.type; | ||||
|     } | ||||
|     texture = MakeImage(info, gl_internal_format); | ||||
|     const int max_host_mip_levels = std::bit_width(info.size.width); | ||||
|     gl_num_levels = std::min(info.resources.levels, max_host_mip_levels); | ||||
|     texture = MakeImage(info, gl_internal_format, gl_num_levels); | ||||
|     current_texture = texture.handle; | ||||
|     if (runtime->device.HasDebuggingToolAttached()) { | ||||
|         const std::string name = VideoCommon::Name(*this); | ||||
| @ -714,6 +715,9 @@ void Image::UploadMemory(const ImageBufferMap& map, | ||||
|     u32 current_image_height = std::numeric_limits<u32>::max(); | ||||
| 
 | ||||
|     for (const VideoCommon::BufferImageCopy& copy : copies) { | ||||
|         if (copy.image_subresource.base_level >= gl_num_levels) { | ||||
|             continue; | ||||
|         } | ||||
|         if (current_row_length != copy.buffer_row_length) { | ||||
|             current_row_length = copy.buffer_row_length; | ||||
|             glPixelStorei(GL_UNPACK_ROW_LENGTH, current_row_length); | ||||
| @ -743,6 +747,9 @@ void Image::DownloadMemory(ImageBufferMap& map, | ||||
|     u32 current_image_height = std::numeric_limits<u32>::max(); | ||||
| 
 | ||||
|     for (const VideoCommon::BufferImageCopy& copy : copies) { | ||||
|         if (copy.image_subresource.base_level >= gl_num_levels) { | ||||
|             continue; | ||||
|         } | ||||
|         if (current_row_length != copy.buffer_row_length) { | ||||
|             current_row_length = copy.buffer_row_length; | ||||
|             glPixelStorei(GL_PACK_ROW_LENGTH, current_row_length); | ||||
| @ -782,7 +789,7 @@ GLuint Image::StorageHandle() noexcept { | ||||
|         } | ||||
|         store_view.Create(); | ||||
|         glTextureView(store_view.handle, ImageTarget(info), current_texture, GL_RGBA8, 0, | ||||
|                       info.resources.levels, 0, info.resources.layers); | ||||
|                       gl_num_levels, 0, info.resources.layers); | ||||
|         return store_view.handle; | ||||
|     default: | ||||
|         return current_texture; | ||||
| @ -946,7 +953,7 @@ void Image::Scale(bool up_scale) { | ||||
|         auto dst_info = info; | ||||
|         dst_info.size.width = scaled_width; | ||||
|         dst_info.size.height = scaled_height; | ||||
|         upscaled_backup = MakeImage(dst_info, gl_internal_format); | ||||
|         upscaled_backup = MakeImage(dst_info, gl_internal_format, gl_num_levels); | ||||
|     } | ||||
|     const u32 src_width = up_scale ? original_width : scaled_width; | ||||
|     const u32 src_height = up_scale ? original_height : scaled_height; | ||||
|  | ||||
| @ -219,6 +219,7 @@ private: | ||||
|     GLenum gl_internal_format = GL_NONE; | ||||
|     GLenum gl_format = GL_NONE; | ||||
|     GLenum gl_type = GL_NONE; | ||||
|     GLsizei gl_num_levels{}; | ||||
|     TextureCacheRuntime* runtime{}; | ||||
|     GLuint current_texture{}; | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user