| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2009 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:29:41 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-03 14:43:52 -05:00
										 |  |  | #include "VideoBackends/Software/TextureEncoder.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  | #include "Common/Align.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-17 16:54:31 -05:00
										 |  |  | #include "Common/CommonFuncs.h"
 | 
					
						
							|  |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							|  |  |  | #include "Common/MsgHandler.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-03 14:43:52 -05:00
										 |  |  | #include "Common/Swap.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-17 16:54:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoBackends/Software/EfbInterface.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 20:50:36 +02:00
										 |  |  | #include "VideoCommon/BPMemory.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoCommon/LookUpTables.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  | #include "VideoCommon/TextureCacheBase.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoCommon/TextureDecoder.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-16 22:48:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | namespace TextureEncoder | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static inline void RGBA_to_RGBA8(const u8* src, u8* r, u8* g, u8* b, u8* a) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |   *a = Convert6To8(srcColor & 0x3f); | 
					
						
							|  |  |  |   *b = Convert6To8((srcColor >> 6) & 0x3f); | 
					
						
							|  |  |  |   *g = Convert6To8((srcColor >> 12) & 0x3f); | 
					
						
							|  |  |  |   *r = Convert6To8((srcColor >> 18) & 0x3f); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static inline void RGBA_to_RGB8(const u8* src, u8* r, u8* g, u8* b) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |   *b = Convert6To8((srcColor >> 6) & 0x3f); | 
					
						
							|  |  |  |   *g = Convert6To8((srcColor >> 12) & 0x3f); | 
					
						
							|  |  |  |   *r = Convert6To8((srcColor >> 18) & 0x3f); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-10 21:51:05 -04:00
										 |  |  | static inline u8 RGB8_to_I(u8 r, u8 g, u8 b) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // values multiplied by 256 to keep math integer
 | 
					
						
							|  |  |  |   u16 val = 4096 + 66 * r + 129 * g + 25 * b; | 
					
						
							|  |  |  |   return val >> 8; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | // box filter sampling averages 4 samples with the source texel being the top left of the box
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | // components are scaled to the range 0-255 after all samples are taken
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGBA_to_RGBA8(const u8* src, u8* r, u8* g, u8* b, u8* a) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 r16 = 0, g16 = 0, b16 = 0, a16 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       a16 += srcColor & 0x3f; | 
					
						
							|  |  |  |       b16 += (srcColor >> 6) & 0x3f; | 
					
						
							|  |  |  |       g16 += (srcColor >> 12) & 0x3f; | 
					
						
							|  |  |  |       r16 += (srcColor >> 18) & 0x3f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = r16 + (r16 >> 6); | 
					
						
							|  |  |  |   *g = g16 + (g16 >> 6); | 
					
						
							|  |  |  |   *b = b16 + (b16 >> 6); | 
					
						
							|  |  |  |   *a = a16 + (a16 >> 6); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGBA_to_RGB8(const u8* src, u8* r, u8* g, u8* b) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 r16 = 0, g16 = 0, b16 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       b16 += (srcColor >> 6) & 0x3f; | 
					
						
							|  |  |  |       g16 += (srcColor >> 12) & 0x3f; | 
					
						
							|  |  |  |       r16 += (srcColor >> 18) & 0x3f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = r16 + (r16 >> 6); | 
					
						
							|  |  |  |   *g = g16 + (g16 >> 6); | 
					
						
							|  |  |  |   *b = b16 + (b16 >> 6); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGBA_to_x8(const u8* src, u8* x8, int shift) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 x16 = 0; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       x16 += (srcColor >> shift) & 0x3f; | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *x8 = x16 + (x16 >> 6); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGBA_to_xx8(const u8* src, u8* x1, u8* x2, int shift1, int shift2) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 x16_1 = 0; | 
					
						
							|  |  |  |   u16 x16_2 = 0; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       x16_1 += (srcColor >> shift1) & 0x3f; | 
					
						
							|  |  |  |       x16_2 += (srcColor >> shift2) & 0x3f; | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *x1 = x16_1 + (x16_1 >> 6); | 
					
						
							|  |  |  |   *x2 = x16_2 + (x16_2 >> 6); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGB_to_RGB8(const u8* src, u8* r, u8* g, u8* b) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 r16 = 0, g16 = 0, b16 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       b16 += src[0]; | 
					
						
							|  |  |  |       g16 += src[1]; | 
					
						
							|  |  |  |       r16 += src[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *r = r16 >> 2; | 
					
						
							|  |  |  |   *g = g16 >> 2; | 
					
						
							|  |  |  |   *b = b16 >> 2; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:00:18 -04:00
										 |  |  | static inline void BoxfilterRGB_to_x8(const u8* src, u8* x8, int comp) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 x16 = 0; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       x16 += src[comp]; | 
					
						
							| 
									
										
										
										
											2010-12-31 06:45:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *x8 = x16 >> 2; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 02:20:46 -04:00
										 |  |  | static inline void BoxfilterRGB_to_xx8(const u8* src, u8* x1, u8* x2, int comp1, int comp2) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 x16_1 = 0; | 
					
						
							|  |  |  |   u16 x16_2 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int y = 0; y < 2; y++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for (int x = 0; x < 2; x++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       x16_1 += src[comp1]; | 
					
						
							|  |  |  |       x16_2 += src[comp2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       src += 3;  // move to next pixel
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     src += (640 - 2) * 3;  // move to next line
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *x1 = x16_1 >> 2; | 
					
						
							|  |  |  |   *x2 = x16_2 >> 2; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static void SetBlockDimensions(int blkWidthLog2, int blkHeightLog2, u16* sBlkCount, u16* tBlkCount, | 
					
						
							|  |  |  |                                u16* sBlkSize, u16* tBlkSize) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // if half_scale is 1 then the size is cut in half
 | 
					
						
							|  |  |  |   u32 width = bpmem.copyTexSrcWH.x >> bpmem.triggerEFBCopy.half_scale; | 
					
						
							|  |  |  |   u32 height = bpmem.copyTexSrcWH.y >> bpmem.triggerEFBCopy.half_scale; | 
					
						
							| 
									
										
										
										
											2013-04-13 23:54:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *sBlkCount = (width >> blkWidthLog2) + 1; | 
					
						
							|  |  |  |   *tBlkCount = (height >> blkHeightLog2) + 1; | 
					
						
							| 
									
										
										
										
											2013-04-13 23:54:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *sBlkSize = 1 << blkWidthLog2; | 
					
						
							|  |  |  |   *tBlkSize = 1 << blkHeightLog2; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static void SetSpans(int sBlkSize, int tBlkSize, s32* tSpan, s32* sBlkSpan, s32* tBlkSpan, | 
					
						
							|  |  |  |                      s32* writeStride) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // width is 1 less than the number of pixels of width
 | 
					
						
							|  |  |  |   u32 width = bpmem.copyTexSrcWH.x >> bpmem.triggerEFBCopy.half_scale; | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   u32 alignedWidth = Common::AlignUp(width, sBlkSize); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 readStride = 3 << bpmem.triggerEFBCopy.half_scale; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *tSpan = (640 - sBlkSize) * | 
					
						
							|  |  |  |            readStride;  // bytes to advance src pointer after each row of texels in a block
 | 
					
						
							|  |  |  |   *sBlkSpan = | 
					
						
							|  |  |  |       ((-640 * tBlkSize) + sBlkSize) * readStride;  // bytes to advance src pointer after each block
 | 
					
						
							|  |  |  |   *tBlkSpan = ((640 * tBlkSize) - alignedWidth) * | 
					
						
							|  |  |  |               readStride;  // bytes to advance src pointer after each row of blocks
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *writeStride = bpmem.copyMipMapStrideChannels * 32; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define ENCODE_LOOP_BLOCKS                                                                         \
 | 
					
						
							|  |  |  |   for (int tBlk = 0; tBlk < tBlkCount; tBlk++)                                                     \ | 
					
						
							|  |  |  |   {                                                                                                \ | 
					
						
							|  |  |  |     dst = dstBlockStart;                                                                           \ | 
					
						
							|  |  |  |     for (int sBlk = 0; sBlk < sBlkCount; sBlk++)                                                   \ | 
					
						
							|  |  |  |     {                                                                                              \ | 
					
						
							|  |  |  |       for (int t = 0; t < tBlkSize; t++)                                                           \ | 
					
						
							|  |  |  |       {                                                                                            \ | 
					
						
							|  |  |  |         for (int s = 0; s < sBlkSize; s++)                                                         \ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  | #define ENCODE_LOOP_SPANS                                                                          \
 | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += tSpan;                                                                                    \ | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += sBlkSpan;                                                                                 \ | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += tBlkSpan;                                                                                 \ | 
					
						
							|  |  |  |   dstBlockStart += writeStride;                                                                    \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ENCODE_LOOP_SPANS2                                                                         \
 | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += tSpan;                                                                                    \ | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += sBlkSpan;                                                                                 \ | 
					
						
							|  |  |  |   dst += 32;                                                                                       \ | 
					
						
							|  |  |  |   }                                                                                                \ | 
					
						
							|  |  |  |   src += tBlkSpan;                                                                                 \ | 
					
						
							|  |  |  |   dstBlockStart += writeStride;                                                                    \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeRGBA6(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u8 r, g, b, a; | 
					
						
							|  |  |  |   u32 readStride = 3; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         RGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst = RGB8_to_I(r, g, b) & 0xf0; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |         RGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst |= RGB8_to_I(r, g, b) >> 4; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst = (srcColor >> 16) & 0xf0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         srcColor = *(u32*)src; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst |= (srcColor >> 20) & 0x0f; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         RGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |         *dst++ = Convert6To8((srcColor >> 18) & 0x3f); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         RGBA_to_RGBA8(src, &r, &g, &b, &a); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = ((srcColor << 2) & 0xf0) | ((srcColor >> 20) & 0x0f); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         RGBA_to_RGBA8(src, &r, &g, &b, &a); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = a; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = Convert6To8(srcColor & 0x3f); | 
					
						
							|  |  |  |         *dst++ = Convert6To8((srcColor >> 18) & 0x3f); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB565: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       u16 val = | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |           ((srcColor >> 8) & 0xf800) | ((srcColor >> 7) & 0x07e0) | ((srcColor >> 7) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB5A3: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       u16 alpha = (srcColor << 9) & 0x7000; | 
					
						
							|  |  |  |       u16 val; | 
					
						
							|  |  |  |       if (alpha == 0x7000)  // 555
 | 
					
						
							|  |  |  |         val = 0x8000 | ((srcColor >> 9) & 0x7c00) | ((srcColor >> 8) & 0x03e0) | | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |               ((srcColor >> 7) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       else  // 4443
 | 
					
						
							|  |  |  |         val = alpha | ((srcColor >> 12) & 0x0f00) | ((srcColor >> 10) & 0x00f0) | | 
					
						
							|  |  |  |               ((srcColor >> 8) & 0x000f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       RGBA_to_RGBA8(src, &dst[1], &dst[32], &dst[33], &dst[0]); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::A8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       *dst++ = Convert6To8(srcColor & 0x3f); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 12) & 0x3f); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 6) & 0x3f); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 12) & 0x3f); | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 18) & 0x3f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::GB8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u32 srcColor = *(u32*)src; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 6) & 0x3f); | 
					
						
							|  |  |  |       *dst++ = Convert6To8((srcColor >> 12) & 0x3f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeRGBA6halfscale(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u8 r, g, b, a; | 
					
						
							|  |  |  |   u32 readStride = 6; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst = RGB8_to_I(r, g, b) & 0xf0; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |         BoxfilterRGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst |= RGB8_to_I(r, g, b) >> 4; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_x8(src, &r, 18); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst = r & 0xf0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BoxfilterRGBA_to_x8(src, &r, 18); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst |= r >> 4; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_x8(src, &r, 18); | 
					
						
							|  |  |  |         *dst++ = r; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = (a & 0xf0) | (r >> 4); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = a; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         *dst++ = a; | 
					
						
							|  |  |  |         *dst++ = r; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB565: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |       u16 val = ((r << 8) & 0xf800) | ((g << 3) & 0x07e0) | ((b >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB5A3: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       u16 val; | 
					
						
							|  |  |  |       if (a >= 224)  // 5551
 | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |         val = 0x8000 | ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       else  // 4443
 | 
					
						
							|  |  |  |         val = ((a << 7) & 0x7000) | ((r << 4) & 0x0f00) | (g & 0x00f0) | ((b >> 4) & 0x000f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_RGBA8(src, &dst[1], &dst[32], &dst[33], &dst[0]); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::A8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_x8(src, &a, 0); | 
					
						
							|  |  |  |       *dst++ = a; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_x8(src, &g, 12); | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_x8(src, &b, 6); | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_xx8(src, &r, &g, 18, 12); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       *dst++ = r; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::GB8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGBA_to_xx8(src, &g, &b, 12, 6); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeRGB8(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u32 readStride = 3; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst = RGB8_to_I(src[2], src[1], src[0]) & 0xf0; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |         *dst |= RGB8_to_I(src[2], src[1], src[0]) >> 4; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst = src[2] & 0xf0; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         *dst |= src[2] >> 4; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(src[2], src[1], src[0]); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = src[2]; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = 0xf0 | (RGB8_to_I(src[2], src[1], src[0]) >> 4); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = 0xf0 | (src[2] >> 4); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = 0xff; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(src[2], src[1], src[0]); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         *dst++ = 0xff; | 
					
						
							|  |  |  |         *dst++ = src[2]; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB565: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |       u16 val = ((src[2] << 8) & 0xf800) | ((src[1] << 3) & 0x07e0) | ((src[0] >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB5A3: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       u16 val = | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |           0x8000 | ((src[2] << 7) & 0x7c00) | ((src[1] << 2) & 0x03e0) | ((src[0] >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       dst[0] = 0xff; | 
					
						
							|  |  |  |       dst[1] = src[2]; | 
					
						
							|  |  |  |       dst[32] = src[1]; | 
					
						
							|  |  |  |       dst[33] = src[0]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::A8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS { *dst++ = 0xff; } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[0]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       // FIXME: is this backwards?
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       *dst++ = src[2]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::GB8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[0]; | 
					
						
							|  |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeRGB8halfscale(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u8 r, g, b; | 
					
						
							|  |  |  |   u32 readStride = 6; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         *dst = RGB8_to_I(r, g, b) & 0xf0; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |         BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         *dst |= RGB8_to_I(r, g, b) >> 4; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_x8(src, &r, 2); | 
					
						
							|  |  |  |         *dst = r & 0xf0; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BoxfilterRGB_to_x8(src, &r, 2); | 
					
						
							|  |  |  |         *dst |= r >> 4; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dst++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_x8(src, &r, 2); | 
					
						
							|  |  |  |         *dst++ = r; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         *dst++ = 0xf0 | (RGB8_to_I(r, g, b) >> 4); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_x8(src, &r, 2); | 
					
						
							|  |  |  |         *dst++ = 0xf0 | (r >> 4); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     if (yuv) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |         *dst++ = 0xff; | 
					
						
							|  |  |  |         *dst++ = RGB8_to_I(r, g, b); | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         BoxfilterRGB_to_x8(src, &r, 2); | 
					
						
							|  |  |  |         *dst++ = 0xff; | 
					
						
							|  |  |  |         *dst++ = r; | 
					
						
							|  |  |  |         src += readStride; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ENCODE_LOOP_SPANS | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB565: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |       u16 val = ((r << 8) & 0xf800) | ((g << 3) & 0x07e0) | ((b >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGB5A3: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							| 
									
										
										
										
											2016-12-14 23:56:06 +10:00
										 |  |  |       u16 val = 0x8000 | ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       *(u16*)dst = Common::swap16(val); | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_RGB8(src, &r, &g, &b); | 
					
						
							|  |  |  |       dst[0] = 0xff; | 
					
						
							|  |  |  |       dst[1] = r; | 
					
						
							|  |  |  |       dst[32] = g; | 
					
						
							|  |  |  |       dst[33] = b; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::A8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS { *dst++ = 0xff; } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &g, 1); | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &b, 0); | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_xx8(src, &r, &g, 2, 1); | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       *dst++ = r; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::GB8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_xx8(src, &g, &b, 1, 0); | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeZ24(u8* dst, const u8* src, EFBCopyFormat format) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u32 readStride = 3; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[2]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   // FIXME: handle RA8?
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       dst[0] = 0xff; | 
					
						
							|  |  |  |       dst[1] = src[2]; | 
					
						
							|  |  |  |       dst[32] = src[1]; | 
					
						
							|  |  |  |       dst[33] = src[0]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst = src[2] & 0xf0; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *dst |= src[2] >> 4; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dst++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[0]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8: | 
					
						
							|  |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // FIXME: should these be reversed?
 | 
					
						
							|  |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       *dst++ = src[2]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case EFBCopyFormat::GB8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       *dst++ = src[0]; | 
					
						
							|  |  |  |       *dst++ = src[1]; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  | static void EncodeZ24halfscale(u8* dst, const u8* src, EFBCopyFormat format) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; | 
					
						
							|  |  |  |   s32 tSpan, sBlkSpan, tBlkSpan, writeStride; | 
					
						
							|  |  |  |   u32 readStride = 6; | 
					
						
							|  |  |  |   u8 r, g, b; | 
					
						
							|  |  |  |   u8* dstBlockStart = dst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (format) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R8_0x1: | 
					
						
							|  |  |  |   case EFBCopyFormat::R8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &b, 2); | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   // FIXME: handle RA8?
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RGBA8: | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_RGB8(src, &dst[33], &dst[32], &dst[1]); | 
					
						
							|  |  |  |       dst[0] = 255; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |       dst += 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS2 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::R4:  // Z4
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     sBlkSize /= 2; | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &b, 2); | 
					
						
							|  |  |  |       *dst = b & 0xf0; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &b, 2); | 
					
						
							|  |  |  |       *dst |= b >> 4; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dst++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::G8:  // Z8M
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &g, 1); | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::B8:  // Z8L
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_x8(src, &r, 0); | 
					
						
							|  |  |  |       *dst++ = r; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::RG8:  // RG8
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_xx8(src, &r, &g, 0, 1); | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       *dst++ = r; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |   case EFBCopyFormat::GB8: | 
					
						
							|  |  |  |     SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); | 
					
						
							|  |  |  |     SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); | 
					
						
							|  |  |  |     ENCODE_LOOP_BLOCKS | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoxfilterRGB_to_xx8(src, &g, &b, 1, 2); | 
					
						
							|  |  |  |       // FIXME: is this backwards?
 | 
					
						
							|  |  |  |       *dst++ = b; | 
					
						
							|  |  |  |       *dst++ = g; | 
					
						
							|  |  |  |       src += readStride; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ENCODE_LOOP_SPANS | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-07-30 12:45:55 -07:00
										 |  |  |     PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  | namespace | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  | void EncodeEfbCopy(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, | 
					
						
							|  |  |  |                    u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, | 
					
						
							|  |  |  |                    bool scale_by_half) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const u8* src = EfbInterface::GetPixelPointer(src_rect.left, src_rect.top, params.depth); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  |   if (scale_by_half) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     switch (params.efb_format) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PEControl::RGBA6_Z24: | 
					
						
							|  |  |  |       EncodeRGBA6halfscale(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::RGB8_Z24: | 
					
						
							|  |  |  |       EncodeRGB8halfscale(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::RGB565_Z16: | 
					
						
							|  |  |  |       EncodeRGB8halfscale(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::Z24: | 
					
						
							|  |  |  |       EncodeZ24halfscale(dst, src, params.copy_format); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-12-02 21:52:07 +01:00
										 |  |  |     default: | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     switch (params.efb_format) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PEControl::RGBA6_Z24: | 
					
						
							|  |  |  |       EncodeRGBA6(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::RGB8_Z24: | 
					
						
							|  |  |  |       EncodeRGB8(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::RGB565_Z16: | 
					
						
							|  |  |  |       EncodeRGB8(dst, src, params.copy_format, params.yuv); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PEControl::Z24: | 
					
						
							|  |  |  |       EncodeZ24(dst, src, params.copy_format); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-12-02 21:52:07 +01:00
										 |  |  |     default: | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  | void Encode(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  |             u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, bool scale_by_half) | 
					
						
							| 
									
										
										
										
											2017-08-23 21:46:23 -05:00
										 |  |  | { | 
					
						
							|  |  |  |   if (params.copy_format == EFBCopyFormat::XFB) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-10-24 00:44:14 -05:00
										 |  |  |     EfbInterface::EncodeXFB(dst, native_width, src_rect, params.y_scale); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-09-02 21:30:34 -05:00
										 |  |  |     EncodeEfbCopy(dst, params, native_width, bytes_per_row, num_blocks_y, memory_stride, src_rect, | 
					
						
							|  |  |  |                   scale_by_half); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | } |