mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	GPU: Implement blended downscaling for display transfers.
This commit is contained in:
		
							parent
							
								
									8ee814ec27
								
							
						
					
					
						commit
						641e78bccf
					
				| @ -53,6 +53,29 @@ inline void Read(T &var, const u32 raw_addr) { | ||||
|     var = g_regs[addr / 4]; | ||||
| } | ||||
| 
 | ||||
| static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) { | ||||
|     switch (input_format) { | ||||
|     case Regs::PixelFormat::RGBA8: | ||||
|         return Color::DecodeRGBA8(src_pixel); | ||||
| 
 | ||||
|     case Regs::PixelFormat::RGB8: | ||||
|         return Color::DecodeRGB8(src_pixel); | ||||
| 
 | ||||
|     case Regs::PixelFormat::RGB565: | ||||
|         return Color::DecodeRGB565(src_pixel); | ||||
| 
 | ||||
|     case Regs::PixelFormat::RGB5A1: | ||||
|         return Color::DecodeRGB5A1(src_pixel); | ||||
| 
 | ||||
|     case Regs::PixelFormat::RGBA4: | ||||
|         return Color::DecodeRGBA4(src_pixel); | ||||
| 
 | ||||
|     default: | ||||
|         LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", input_format); | ||||
|         return {0, 0, 0, 0}; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
| inline void Write(u32 addr, const T data) { | ||||
|     addr -= HW::VADDR_GPU; | ||||
| @ -125,6 +148,13 @@ inline void Write(u32 addr, const T data) { | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             if (config.output_tiled && | ||||
|                     (config.scaling == config.ScaleXY || config.scaling == config.ScaleX)) { | ||||
|                 LOG_CRITICAL(HW_GPU, "Scaling is only implemented on tiled input"); | ||||
|                 UNIMPLEMENTED(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             bool horizontal_scale = config.scaling != config.NoScale; | ||||
|             bool vertical_scale = config.scaling == config.ScaleXY; | ||||
| 
 | ||||
| @ -153,11 +183,9 @@ inline void Write(u32 addr, const T data) { | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             // TODO(Subv): Implement the box filter when scaling is enabled
 | ||||
|             // right now we're just skipping the extra pixels.
 | ||||
|             for (u32 y = 0; y < output_height; ++y) { | ||||
|                 for (u32 x = 0; x < output_width; ++x) { | ||||
|                     Math::Vec4<u8> src_color = { 0, 0, 0, 0 }; | ||||
|                     Math::Vec4<u8> src_color; | ||||
| 
 | ||||
|                     // Calculate the [x,y] position of the input image
 | ||||
|                     // based on the current output position and the scale
 | ||||
| @ -193,30 +221,15 @@ inline void Write(u32 addr, const T data) { | ||||
|                     } | ||||
| 
 | ||||
|                     const u8* src_pixel = src_pointer + src_offset; | ||||
|                     switch (config.input_format) { | ||||
|                     case Regs::PixelFormat::RGBA8: | ||||
|                         src_color = Color::DecodeRGBA8(src_pixel); | ||||
|                         break; | ||||
| 
 | ||||
|                     case Regs::PixelFormat::RGB8: | ||||
|                         src_color = Color::DecodeRGB8(src_pixel); | ||||
|                         break; | ||||
| 
 | ||||
|                     case Regs::PixelFormat::RGB565: | ||||
|                         src_color = Color::DecodeRGB565(src_pixel); | ||||
|                         break; | ||||
| 
 | ||||
|                     case Regs::PixelFormat::RGB5A1: | ||||
|                         src_color = Color::DecodeRGB5A1(src_pixel); | ||||
|                         break; | ||||
| 
 | ||||
|                     case Regs::PixelFormat::RGBA4: | ||||
|                         src_color = Color::DecodeRGBA4(src_pixel); | ||||
|                         break; | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", config.input_format.Value()); | ||||
|                         break; | ||||
|                     src_color = DecodePixel(config.input_format, src_pixel); | ||||
|                     if (config.scaling == config.ScaleX) { | ||||
|                         Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel); | ||||
|                         src_color = ((src_color + pixel) / 2).Cast<u8>(); | ||||
|                     } else if (config.scaling == config.ScaleXY) { | ||||
|                         Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel); | ||||
|                         Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel); | ||||
|                         Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel); | ||||
|                         src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>(); | ||||
|                     } | ||||
| 
 | ||||
|                     u8* dst_pixel = dst_pointer + dst_offset; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Emmanuel Gil Peyrot
						Emmanuel Gil Peyrot