All pastes #1352686 Raw Edit

Mine

public diff v1 · immutable
#1352686 ·published 2009-03-04 13:20 UTC
rendered paste body
Index: pcsx2/IPU/IPU.cpp===================================================================--- pcsx2/IPU/IPU.cpp	(revision 630)+++ pcsx2/IPU/IPU.cpp	(working copy)@@ -96,9 +96,6 @@ //char convert_data_buffer[sizeof(convert_rgb_t)]; char convert_data_buffer[0x1C]; -convert_init_t convert_init={convert_data_buffer, sizeof(convert_data_buffer)};-convert_t *convert;- // Quantization matrix static u8 niq[64],			//non-intraquant matrix 		iq[64];			//intraquant matrix@@ -216,8 +213,7 @@  		if (!mpeg2_inited){ 			mpeg2_idct_init();-			convert=convert_rgb (CONVERT_RGB, 32);-			convert(16, 16, 0, NULL, &convert_init);+			yuv2rgb_init(); 			memzero_obj(mb8.Y); 			memzero_obj(mb8.Cb); 			memzero_obj(mb8.Cr);@@ -314,8 +310,7 @@ { 	if (!mpeg2_inited){         mpeg2_idct_init();-		convert=convert_rgb (CONVERT_RGB, 32);-		convert(16, 16, 0, NULL, &convert_init);+		yuv2rgb_init(); 		memzero_obj(mb8.Y); 		memzero_obj(mb8.Cb); 		memzero_obj(mb8.Cr);@@ -1274,8 +1269,7 @@ 	int i; 	u8* p = (u8*)rgb32; -	convert_init.start(convert_init.id, (u8*)rgb32, CONVERT_FRAME);-	convert_init.copy(convert_init.id, (u8*)mb8->Y, (u8*)mb8->Cr, (u8*)mb8->Cb, 0);+	yuv2rgb_sse2();  	if( s_thresh[0] > 0 ) { 		for(i = 0; i < 64*4; i++, p += 4) {Index: pcsx2/IPU/IPU.h===================================================================--- pcsx2/IPU/IPU.h	(revision 630)+++ pcsx2/IPU/IPU.h	(working copy)@@ -19,6 +19,8 @@ #ifndef __IPU_H__ #define __IPU_H__ +#include "mpeg2lib/Mpeg.h"+ // IPU_INLINE_IRQS // Scheduling ints into the future is a purist approach to emulation, and // is mostly cosmetic since the emulator itself performs all actions instantly@@ -222,6 +224,10 @@ extern int g_nIPU0Data; // or 0x80000000 whenever transferring extern u8* g_pIPU0Pointer; +// The IPU can only do one task at once and never uses other buffers so these+// should be made available to functions in other modules to save registers.+PCSX2_ALIGNED16(extern macroblock_rgb32 rgb32);+PCSX2_ALIGNED16(extern macroblock_8 mb8);  void dmaIPU0(); void dmaIPU1();Index: pcsx2/IPU/mpeg2lib/Mpeg.h===================================================================--- pcsx2/IPU/mpeg2lib/Mpeg.h	(revision 630)+++ pcsx2/IPU/mpeg2lib/Mpeg.h	(working copy)@@ -64,12 +64,10 @@ 	short Cr[8][8];				//2 }; -struct rgb32{-	unsigned char r, g, b, a;-};- struct macroblock_rgb32{-	struct rgb32	c[16][16];+	struct {+		unsigned char r, g, b, a;+	} c[16][16]; };  struct rgb16{Index: pcsx2/IPU/yuv2rgb.cpp===================================================================--- pcsx2/IPU/yuv2rgb.cpp	(revision 630)+++ pcsx2/IPU/yuv2rgb.cpp	(working copy)@@ -25,490 +25,292 @@ #include "PrecompiledHeader.h"  #include "System.h"-#include "mpeg2lib/Mpeg.h"+#include "IPU.h" #include "yuv2rgb.h" -//#include "convert_internal.h" //START-struct convert_rgb_t {-    u8 * rgb_ptr;-    int width;-    int uv_stride, uv_stride_frame;-    int rgb_stride, rgb_stride_frame;-    void (__fastcall * yuv2rgb) (u8 *, u8 *, u8 *, u8 *,-		      void *, void *, int);-};+// Everything below is bit accurate to the IPU specification (except maybe rounding).+// Know the specification before you touch it. -typedef void __fastcall yuv2rgb_copy (void * id, u8 * const * src,-			   unsigned int v_offset);+PCSX2_ALIGNED16(u16 C_bias)[8] = {0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000};+PCSX2_ALIGNED16(u8 Y_bias)[16] = {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};+#define SSE_COEFFICIENTS(name, x) \+	PCSX2_ALIGNED16(u16 name)[8] = {x<<2,x<<2,x<<2,x<<2,x<<2,x<<2,x<<2,x<<2};+SSE_COEFFICIENTS(Y_coefficients, 0x95);    // 1.1640625+SSE_COEFFICIENTS(RCr_coefficients, 0xcc);  // 1.59375+SSE_COEFFICIENTS(GCr_coefficients, (-0x68));  // -0.8125+SSE_COEFFICIENTS(GCb_coefficients, (-0x32));  // -0.390625+SSE_COEFFICIENTS(BCb_coefficients, 0x102); // 2.015625+PCSX2_ALIGNED16(u16 Y_mask)[8] = {0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00};+// Specifying round off instead of round down as everywhere else+// implies that this is right+PCSX2_ALIGNED16(u16 round_1bit)[8] = {1,1,1,1,1,1,1,1};+PCSX2_ALIGNED16(u16 yuv2rgb_temp)[3][8]; -yuv2rgb_copy __fastcall * yuv2rgb_init_mmxext (int bpp, int mode);-yuv2rgb_copy __fastcall * yuv2rgb_init_mmx (int bpp, int mode);-yuv2rgb_copy __fastcall * yuv2rgb_init_mlib (int bpp, int mode);-//#include "convert_internal.h" //END--static u32 matrix_coefficients = 6;--const s32 Inverse_Table_6_9[8][4] = {-    {117504, 138453, 13954, 34903}, /*0 no sequence_display_extension */-    {117504, 138453, 13954, 34903}, /*1 ITU-R Rec. 709 (1990) */-    {104597, 132201, 25675, 53279}, /*2 unspecified */-    {104597, 132201, 25675, 53279}, /*3 reserved */-    {104448, 132798, 24759, 53109}, /*4 FCC */-    {104597, 132201, 25675, 53279}, /*5 ITU-R Rec. 624-4 System B, G */-    {104597, 132201, 25675, 53279}, /*6 SMPTE 170M */-    {117579, 136230, 16907, 35559}  /*7 SMPTE 240M (1987) */-};--typedef void __fastcall yuv2rgb_c_internal (u8 *, u8 *, u8 *, u8 *,-				 void *, void *, int);--void * table_rV[256];-void * table_gU[256];-int table_gV[256];-void * table_bU[256];--#define _RGB(type,i)						\-	U = pu[i];						\-	V = pv[i];						\-	r = (type *) table_rV[V];				\-	g = (type *) (((u8 *)table_gU[U]) + table_gV[V]);	\-	b = (type *) table_bU[U];--#define DST(py,dst,i)				\-	Y = py[2*i];				\-	dst[2*i] = r[Y] + g[Y] + b[Y];		\-	Y = py[2*i+1];				\-	dst[2*i+1] = r[Y] + g[Y] + b[Y];--#define DSTRGB(py,dst,i)						\-	Y = py[2*i];							\-	dst[6*i] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y];		\-	Y = py[2*i+1];							\-	dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];--#define DSTBGR(py,dst,i)						\-	Y = py[2*i];							\-	dst[6*i] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y];		\-	Y = py[2*i+1];							\-	dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];--static void __fastcall yuv2rgb_c_32 (u8 * py_1, u8 * py_2,-			  u8 * pu, u8 * pv,-			  void * _dst_1, void * _dst_2, int width)+// This could potentially be improved for SSE4+void yuv2rgb_sse2(void) {-    int U, V, Y;-    u32 * r, * g, * b;-    u32 * dst_1, * dst_2;+#if defined(_MSC_VER) || defined(__INTEL_COMPILER)+	__asm {+		mov eax, 1+		mov esi, 0+		mov edi, 0 -    width >>= 3;-    dst_1 = (u32 *) _dst_1;-    dst_2 = (u32 *) _dst_2;+tworows:+		align 16+		movq xmm3, qword ptr [mb8+256+esi]+		movq xmm1, qword ptr [mb8+320+esi]+		pxor xmm2, xmm2+		pxor xmm0, xmm0+		// could skip the movq but punpck requires 128-bit alignment+		// for some reason, so two versions would be needed,+		// bloating the function (further)+		punpcklbw xmm2, xmm3+		punpcklbw xmm0, xmm1+		// unfortunately I don't think this will matter despite being+		// technically potentially a little faster, but this is+		// equivalent to an add or sub+		pxor xmm2, xmmword ptr [C_bias] // xmm2 <-- 8 x (Cb - 128) << 8+		pxor xmm0, xmmword ptr [C_bias] // xmm0 <-- 8 x (Cr - 128) << 8 -    do {-		_RGB (u32, 0);-		DST (py_1, dst_1, 0);-		DST (py_2, dst_2, 0);+		movaps xmm1, xmm0+		movaps xmm3, xmm2+		pmulhw xmm1, xmmword ptr [GCr_coefficients]+		pmulhw xmm3, xmmword ptr [GCb_coefficients]+		pmulhw xmm0, xmmword ptr [RCr_coefficients]+		pmulhw xmm2, xmmword ptr [BCb_coefficients]+		paddsw xmm1, xmm3+		// store for the next line; looking at the code above+		// compared to the code below, I have to wonder whether+		// this was worth the hassle+		movaps xmmword ptr [yuv2rgb_temp], xmm0+		movaps xmmword ptr [yuv2rgb_temp+16], xmm1+		movaps xmmword ptr [yuv2rgb_temp+32], xmm2+		jmp ihatemsvc -		_RGB (u32, 1);-		DST (py_2, dst_2, 1);-		DST (py_1, dst_1, 1);+onerow:+		align 16+		movaps xmm0, xmmword ptr [yuv2rgb_temp]+		movaps xmm1, xmmword ptr [yuv2rgb_temp+16]+		movaps xmm2, xmmword ptr [yuv2rgb_temp+32] -		_RGB (u32, 2);-		DST (py_1, dst_1, 2);-		DST (py_2, dst_2, 2);+// If masm directives worked properly in inline asm, I'd be using them,+// but I'm not inclined to write ~70 line #defines to simulate them.+// Maybe the function's faster like this anyway because it's smaller?+// I'd have to write a 70 line #define to benchmark it.+ihatemsvc:+		align 16+		movaps xmm3, xmm0+		movaps xmm4, xmm1+		movaps xmm5, xmm2 -		_RGB (u32, 3);-		DST (py_2, dst_2, 3);-		DST (py_1, dst_1, 3);+		movaps xmm6, xmmword ptr [mb8+edi]+		psubusb xmm6, xmmword ptr [Y_bias]+		movaps xmm7, xmm6+		psllw xmm6, 8                    // xmm6 <- Y << 8 for pixels 0,2,4,6,8,10,12,14+		pand xmm7, xmmword ptr [Y_mask]  // xmm7 <- Y << 8 for pixels 1,3,5,7,9,11,13,15 -		pu += 4;-		pv += 4;-		py_1 += 8;-		py_2 += 8;-		dst_1 += 8;-		dst_2 += 8;-    } while (--width);-}+		pmulhuw xmm6, xmmword ptr [Y_coefficients]+		pmulhuw xmm7, xmmword ptr [Y_coefficients] -/* This is very near from the yuv2rgb_c_32 code */-static void __fastcall yuv2rgb_c_24_rgb (u8 * py_1, u8 * py_2,-			      u8 * pu, u8 * pv,-			      void * _dst_1, void * _dst_2, int width)-{-    int U, V, Y;-    u8 * r, * g, * b;-    u8 * dst_1, * dst_2;+		paddsw xmm0, xmm6+		paddsw xmm3, xmm7+		paddsw xmm1, xmm6+		paddsw xmm4, xmm7+		paddsw xmm2, xmm6+		paddsw xmm5, xmm7 -    width >>= 3;-    dst_1 = (u8 *) _dst_1;-    dst_2 = (u8 *) _dst_2;+		// round+		movaps xmm6, xmmword ptr [round_1bit]+		paddw xmm0, xmm6+		paddw xmm1, xmm6+		paddw xmm2, xmm6+		paddw xmm3, xmm6+		paddw xmm4, xmm6+		paddw xmm5, xmm6+		psraw xmm0, 1+		psraw xmm1, 1+		psraw xmm2, 1+		psraw xmm3, 1+		psraw xmm4, 1+		psraw xmm5, 1 -    do {-		_RGB (u8, 0);-		DSTRGB (py_1, dst_1, 0);-		DSTRGB (py_2, dst_2, 0);+		// combine even and odd bytes+		packuswb xmm0, xmm3+		packuswb xmm1, xmm4+		packuswb xmm2, xmm5+		movhlps xmm3, xmm0+		movhlps xmm4, xmm1+		movhlps xmm5, xmm2+		punpcklbw xmm0, xmm3 // Red bytes, back in order +		punpcklbw xmm1, xmm4 // Green ""+		punpcklbw xmm2, xmm5 // Blue ""+		movaps xmm3, xmm0+		movaps xmm4, xmm1+		movaps xmm5, xmm2 -		_RGB (u8, 1);-		DSTRGB (py_2, dst_2, 1);-		DSTRGB (py_1, dst_1, 1);+		// Create RGBA (we could generate A here, but we don't) quads+		punpcklbw xmm0, xmm1+		punpcklbw xmm2, xmm7+		movaps xmm1, xmm0+		punpcklwd xmm0, xmm2+		punpckhwd xmm1, xmm2 -		_RGB (u8, 2);-		DSTRGB (py_1, dst_1, 2);-		DSTRGB (py_2, dst_2, 2);+		punpckhbw xmm3, xmm4+		punpckhbw xmm5, xmm7+		movaps xmm4, xmm3+		punpcklwd xmm3, xmm5+		punpckhwd xmm4, xmm5 -		_RGB (u8, 3);-		DSTRGB (py_2, dst_2, 3);-		DSTRGB (py_1, dst_1, 3);+		// at last+		movaps xmmword ptr [rgb32+edi*4+0], xmm0+		movaps xmmword ptr [rgb32+edi*4+16], xmm1+		movaps xmmword ptr [rgb32+edi*4+32], xmm3+		movaps xmmword ptr [rgb32+edi*4+48], xmm4 -		pu += 4;-		pv += 4;-		py_1 += 8;-		py_2 += 8;-		dst_1 += 24;-		dst_2 += 24;-    } while (--width);-}+		add edi, 16 -/* only trivial mods from yuv2rgb_c_24_rgb */-static void __fastcall yuv2rgb_c_24_bgr (u8 * py_1, u8 * py_2,-			      u8 * pu, u8 * pv,-			      void * _dst_1, void * _dst_2, int width)-{-    int U, V, Y;-    u8 * r, * g, * b;-    u8 * dst_1, * dst_2;+		neg eax+		jl onerow // run twice -    width >>= 3;-    dst_1 = (u8 *) _dst_1;-    dst_2 = (u8 *) _dst_2;+		add esi, 8+		cmp esi, 64+		jne tworows+	}+#elif defined(__GNUC__)+	asm(+		".intel_syntax noprefix\n"+		"mov eax, 1\n"+		"mov esi, 0\n"+		"mov edi, 0\n" -    do {-		_RGB (u8, 0);-		DSTBGR (py_1, dst_1, 0);-		DSTBGR (py_2, dst_2, 0);+"tworows:\n"+		".align 16\n"+		"movq xmm3, qword ptr [mb8+256+esi]\n"+		"movq xmm1, qword ptr [mb8+320+esi]\n"+		"pxor xmm2, xmm2\n"+		"pxor xmm0, xmm0\n"+		// could skip the movq but punpck requires 128-bit alignment+		// for some reason, so two versions would be needed,+		// bloating the function (further)+		"punpcklbw xmm2, xmm3\n"+		"punpcklbw xmm0, xmm1\n"+		// unfortunately I don't think this will matter despite being+		// technically potentially a little faster, but this is+		// equivalent to an add or sub+		"pxor xmm2, xmmword ptr [C_bias]\n" // xmm2 <-- 8 x (Cb - 128) << 8+		"pxor xmm0, xmmword ptr [C_bias]\n" // xmm0 <-- 8 x (Cr - 128) << 8 -		_RGB (u8, 1);-		DSTBGR (py_2, dst_2, 1);-		DSTBGR (py_1, dst_1, 1);+		"movaps xmm1, xmm0\n"+		"movaps xmm3, xmm2\n"+		"pmulhw xmm1, xmmword ptr [GCr_coefficients]\n"+		"pmulhw xmm3, xmmword ptr [GCb_coefficients]\n"+		"pmulhw xmm0, xmmword ptr [RCr_coefficients]\n"+		"pmulhw xmm2, xmmword ptr [BCb_coefficients]\n"+		"paddsw xmm1, xmm3\n"+		// store for the next line; looking at the code above+		// compared to the code below, I have to wonder whether+		// this was worth the hassle+		"movaps xmmword ptr [yuv2rgb_temp], xmm0\n"+		"movaps xmmword ptr [yuv2rgb_temp+16], xmm1\n"+		"movaps xmmword ptr [yuv2rgb_temp+32], xmm2\n"+		"jmp ihategcctoo\n" -		_RGB (u8, 2);-		DSTBGR (py_1, dst_1, 2);-		DSTBGR (py_2, dst_2, 2);+"onerow:\n"+		".align 16\n"+		"movaps xmm0, xmmword ptr [yuv2rgb_temp]\n"+		"movaps xmm1, xmmword ptr [yuv2rgb_temp+16]\n"+		"movaps xmm2, xmmword ptr [yuv2rgb_temp+32]\n" -		_RGB (u8, 3);-		DSTBGR (py_2, dst_2, 3);-		DSTBGR (py_1, dst_1, 3);+// If masm directives worked properly in inline asm, I'd be using them,+// but I'm not inclined to write ~70 line #defines to simulate them.+// Maybe the function's faster like this anyway because it's smaller?+// I'd have to write a 70 line #define to benchmark it.+"ihategcctoo:\n"+		".align 16\n"+		"movaps xmm3, xmm0\n"+		"movaps xmm4, xmm1\n"+		"movaps xmm5, xmm2\n" -		pu += 4;-		pv += 4;-		py_1 += 8;-		py_2 += 8;-		dst_1 += 24;-		dst_2 += 24;-    } while (--width);-}+		"movaps xmm6, xmmword ptr [mb8+edi]\n"+		"psubusb xmm6, xmmword ptr [Y_bias]\n"+		"movaps xmm7, xmm6\n"+		"psllw xmm6, 8\n"                   // xmm6 <- Y << 8 for pixels 0,2,4,6,8,10,12,14+		"pand xmm7, xmmword ptr [Y_mask]\n" // xmm7 <- Y << 8 for pixels 1,3,5,7,9,11,13,15 -/* This is exactly the same code as yuv2rgb_c_32 except for the types of */-/* r, g, b, dst_1, dst_2 */-static void __fastcall yuv2rgb_c_16 (u8 * py_1, u8 * py_2,-			  u8 * pu, u8 * pv,-			  void * _dst_1, void * _dst_2, int width)-{-    int U, V, Y;-    u16 * r, * g, * b;-    u16 * dst_1, * dst_2;+		"pmulhuw xmm6, xmmword ptr [Y_coefficients]\n"+		"pmulhuw xmm7, xmmword ptr [Y_coefficients]\n" -    width >>= 3;-    dst_1 = (u16 *) _dst_1;-    dst_2 = (u16 *) _dst_2;+		"paddsw xmm0, xmm6\n"+		"paddsw xmm3, xmm7\n"+		"paddsw xmm1, xmm6\n"+		"paddsw xmm4, xmm7\n"+		"paddsw xmm2, xmm6\n"+		"paddsw xmm5, xmm7\n" -    do {-		_RGB (u16, 0);-		DST (py_1, dst_1, 0);-		DST (py_2, dst_2, 0);+		// round+		"movaps xmm6, xmmword ptr [round_1bit]\n"+		"paddw xmm0, xmm6\n"+		"paddw xmm1, xmm6\n"+		"paddw xmm2, xmm6\n"+		"paddw xmm3, xmm6\n"+		"paddw xmm4, xmm6\n"+		"paddw xmm5, xmm6\n"+		"psraw xmm0, 1\n"+		"psraw xmm1, 1\n"+		"psraw xmm2, 1\n"+		"psraw xmm3, 1\n"+		"psraw xmm4, 1\n"+		"psraw xmm5, 1\n" -		_RGB (u16, 1);-		DST (py_2, dst_2, 1);-		DST (py_1, dst_1, 1);+		// combine even and odd bytes+		"packuswb xmm0, xmm3\n"+		"packuswb xmm1, xmm4\n"+		"packuswb xmm2, xmm5\n"+		"movhlps xmm3, xmm0\n"+		"movhlps xmm4, xmm1\n"+		"movhlps xmm5, xmm2\n"+		"punpcklbw xmm0, xmm3\n" // Red bytes, back in order+		"punpcklbw xmm1, xmm4\n" // Green ""+		"punpcklbw xmm2, xmm5\n" // Blue ""+		"movaps xmm3, xmm0\n"+		"movaps xmm4, xmm1\n"+		"movaps xmm5, xmm2\n" -		_RGB (u16, 2);-		DST (py_1, dst_1, 2);-		DST (py_2, dst_2, 2);+		// Create RGBA (we could generate A here, but we don't) quads+		"punpcklbw xmm0, xmm1\n"+		"punpcklbw xmm2, xmm7\n"+		"movaps xmm1, xmm0\n"+		"punpcklwd xmm0, xmm2\n"+		"punpckhwd xmm1, xmm2\n" -		_RGB (u16, 3);-		DST (py_2, dst_2, 3);-		DST (py_1, dst_1, 3);+		"punpckhbw xmm3, xmm4\n"+		"punpckhbw xmm5, xmm7\n"+		"movaps xmm4, xmm3\n"+		"punpcklwd xmm3, xmm5\n"+		"punpckhwd xmm4, xmm5\n" -		pu += 4;-		pv += 4;-		py_1 += 8;-		py_2 += 8;-		dst_1 += 8;-		dst_2 += 8;-    } while (--width);-}+		// at last+		"movaps xmmword ptr [rgb32+edi*4+0], xmm0\n"+		"movaps xmmword ptr [rgb32+edi*4+16], xmm1\n"+		"movaps xmmword ptr [rgb32+edi*4+32], xmm3\n"+		"movaps xmmword ptr [rgb32+edi*4+48], xmm4\n" -static int div_round (int dividend, int divisor)-{-    if (dividend > 0)-		return (dividend + (divisor>>1)) / divisor;-    else-		return -((-dividend + (divisor>>1)) / divisor);-}+		"add edi, 16\n" -static yuv2rgb_c_internal __fastcall * yuv2rgb_c_init (int order, int bpp)-{-    int i;-    u8 table_Y[1024];-    u32 * table_32 = 0;-    u16 * table_16 = 0;-    u8 * table_8 = 0;-    int entry_size = 0;-    void * table_r = 0;-    void * table_g = 0;-    void * table_b = 0;-    yuv2rgb_c_internal * yuv2rgb;+		"neg eax\n"+		"jl onerow\n" // run twice -    int crv = Inverse_Table_6_9[matrix_coefficients][0];-    int cbu = Inverse_Table_6_9[matrix_coefficients][1];-    int cgu = -Inverse_Table_6_9[matrix_coefficients][2];-    int cgv = -Inverse_Table_6_9[matrix_coefficients][3];--    for (i = 0; i < 1024; i++)-	{-		int j;--		j = (76309 * (i - 384 - 16) + 32768) >> 16;-		j = (j < 0) ? 0 : ((j > 255) ? 255 : j);-		table_Y[i] = j;-    }--    switch (bpp)-	{-    case 32:-		yuv2rgb = yuv2rgb_c_32;--		table_32 = (u32 *) malloc ((197 + 2*682 + 256 + 132) *-						sizeof (u32));--		entry_size = sizeof (u32);-		table_r = table_32 + 197;-		table_b = table_32 + 197 + 685;-		table_g = table_32 + 197 + 2*682;--		for (i = -197; i < 256+197; i++)-			((u32 *) table_r)[i] =-			table_Y[i+384] << ((order == CONVERT_RGB) ? 16 : 0);-		for (i = -132; i < 256+132; i++)-			((u32 *) table_g)[i] = table_Y[i+384] << 8;-		for (i = -232; i < 256+232; i++)-			((u32 *) table_b)[i] =-			table_Y[i+384] << ((order == CONVERT_RGB) ? 0 : 16);-	break;--    case 24:-		yuv2rgb = (order == CONVERT_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;--		table_8 = (u8 *) malloc ((256 + 2*232) * sizeof (u8));--		entry_size = sizeof (u8);-		table_r = table_g = table_b = table_8 + 232;--		for (i = -232; i < 256+232; i++)-			((u8 * )table_b)[i] = table_Y[i+384];-	break;--    case 15:-    case 16:-		yuv2rgb = yuv2rgb_c_16;--		table_16 = (u16 *) malloc ((197 + 2*682 + 256 + 132) *-						sizeof (u16));--		entry_size = sizeof (u16);-		table_r = table_16 + 197;-		table_b = table_16 + 197 + 685;-		table_g = table_16 + 197 + 2*682;--		for (i = -197; i < 256+197; i++) {-			int j = table_Y[i+384] >> 3;--			if (order == CONVERT_RGB)-			j <<= ((bpp==16) ? 11 : 10);--			((u16 *)table_r)[i] = j;-		}-		for (i = -132; i < 256+132; i++) {-			int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);--			((u16 *)table_g)[i] = j << 5;-		}-		for (i = -232; i < 256+232; i++) {-			int j = table_Y[i+384] >> 3;--			if (order == CONVERT_RGB)-			j <<= ((bpp==16) ? 11 : 10);--			((u16 *)table_b)[i] = j;-		}-	break;--#ifdef PCSX2_DEVBUILD-    default:-		DevCon::Error( "IPU Panic!  %ibpp not supported by yuv2rgb", params bpp );+		"add esi, 8\n"+		"cmp esi, 64\n"+		"jne tworows\n"+		".att_syntax\n"+	); #else-		jNO_DEFAULT+#error Unsupported compiler #endif-	}--    for (i = 0; i < 256; i++) {-		table_rV[i] = (((u8 *)table_r) +-			entry_size * div_round (crv * (i-128), 76309));-		table_gU[i] = (((u8 *)table_g) +-			entry_size * div_round (cgu * (i-128), 76309));-		table_gV[i] = entry_size * div_round (cgv * (i-128), 76309);-		table_bU[i] = (((u8 *)table_b) +-			entry_size * div_round (cbu * (i-128), 76309));-    }--    return yuv2rgb; } -static void __fastcall convert_yuv2rgb_c (void * _id, u8 * Y, u8 * Cr, u8 * Cb,-			       unsigned int v_offset)+void yuv2rgb_init(void) {-    convert_rgb_t * id = (convert_rgb_t *) _id;-    u8 * dst;-    u8 * py;-    u8 * pu;-    u8 * pv;-    int loop;--    dst = id->rgb_ptr + id->rgb_stride * v_offset;-    py = Y; pu = Cr; pv = Cb;--    loop = 8;-    do {-		id->yuv2rgb (py, py + (id->uv_stride << 1), pu, pv,-		     dst, dst + id->rgb_stride, id->width);-		py += id->uv_stride << 2;-		pu += id->uv_stride;-		pv += id->uv_stride;-		dst += 2 * id->rgb_stride;-    } while (--loop);-}--static void __fastcall convert_start (void * _id, u8 * dest, int flags)-{-    convert_rgb_t * id = (convert_rgb_t *) _id;-    id->rgb_ptr = dest;-    switch (flags) {-    case CONVERT_BOTTOM_FIELD:-		id->rgb_ptr += id->rgb_stride_frame;-		/* break thru */-    case CONVERT_TOP_FIELD:-		id->uv_stride = id->uv_stride_frame << 1;-		id->rgb_stride = id->rgb_stride_frame << 1;-	break;-    default:-		id->uv_stride = id->uv_stride_frame;-		id->rgb_stride = id->rgb_stride_frame;-    }-}--static void __fastcall convert_internal (int order, int bpp, int width, int height,-			      u32 accel, void * arg, convert_init_t * result)-{-    convert_rgb_t * id = (convert_rgb_t *) result->id;--    if (!id) {-		result->id_size = sizeof (convert_rgb_t);-    } else {-		id->width = width;-		id->uv_stride_frame = width >> 1;-		id->rgb_stride_frame = ((bpp + 7) >> 3) * width;--		result->buf_size[0] = id->rgb_stride_frame * height;-		result->buf_size[1] = result->buf_size[2] = 0;-		result->start = convert_start;--		result->copy = NULL;-	#ifdef ARCH_X86-		if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMXEXT)) {-			result->copy = yuv2rgb_init_mmxext (order, bpp);-		}-		if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMX)) {-			result->copy = yuv2rgb_init_mmx (order, bpp);-		}-	#endif-	#ifdef LIBVO_MLIB-		if ((result->copy == NULL) && (accel & MPEG2_ACCEL_MLIB)) {-			result->copy = yuv2rgb_init_mlib (order, bpp);-		}-	#endif-		if (result->copy == NULL) {-			result->copy = convert_yuv2rgb_c;-			id->yuv2rgb = yuv2rgb_c_init (order, bpp);-		}-    }-}--void __fastcall convert_rgb32 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_RGB, 32, width, height, accel, arg, result);-}--void __fastcall convert_rgb24 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_RGB, 24, width, height, accel, arg, result);-}--void __fastcall convert_rgb16 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_RGB, 16, width, height, accel, arg, result);-}--void __fastcall convert_rgb15 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_RGB, 15, width, height, accel, arg, result);-}--void __fastcall convert_bgr32 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_BGR, 32, width, height, accel, arg, result);-}--void __fastcall convert_bgr24 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_BGR, 24, width, height, accel, arg, result);-}--void __fastcall convert_bgr16 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_BGR, 16, width, height, accel, arg, result);-}--void __fastcall convert_bgr15 (int width, int height, u32 accel, void * arg,-		    convert_init_t * result)-{-    convert_internal (CONVERT_BGR, 15, width, height, accel, arg, result);-}--__forceinline convert_t* convert_rgb (int order, int bpp)-{-    if (order == CONVERT_RGB || order == CONVERT_BGR)-	switch (bpp) {-	case 32: return (order == CONVERT_RGB) ? convert_rgb32 : convert_bgr32;-	case 24: return (order == CONVERT_RGB) ? convert_rgb24 : convert_bgr24;-	case 16: return (order == CONVERT_RGB) ? convert_rgb16 : convert_bgr16;-	case 15: return (order == CONVERT_RGB) ? convert_rgb15 : convert_bgr15;-	}-    return NULL;-}+	/* For later reimplementation of C version */+}\ No newline at end of fileIndex: pcsx2/IPU/yuv2rgb.h===================================================================--- pcsx2/IPU/yuv2rgb.h	(revision 630)+++ pcsx2/IPU/yuv2rgb.h	(working copy)@@ -25,33 +25,7 @@ #ifndef YUV2RGB_H #define YUV2RGB_H -#define CONVERT_FRAME 0-#define CONVERT_TOP_FIELD 1-#define CONVERT_BOTTOM_FIELD 2-#define CONVERT_BOTH_FIELDS 3+void yuv2rgb_sse2(void);+void yuv2rgb_init(void); -struct convert_init_t {-    void * id;-    int id_size;-    int buf_size[3];-    void (__fastcall* start) (void * id, u8 * dest, int flags);-    void (__fastcall* copy) (void * id, u8 * Y, u8 * Cr, u8 * Cb, unsigned int v_offset);-};--typedef void __fastcall convert_t (int width, int height, u32 accel, void * arg,-			convert_init_t * result);--convert_t convert_rgb32;-convert_t convert_rgb24;-convert_t convert_rgb16;-convert_t convert_rgb15;-convert_t convert_bgr32;-convert_t convert_bgr24;-convert_t convert_bgr16;-convert_t convert_bgr15;--#define CONVERT_RGB 0-#define CONVERT_BGR 1-extern convert_t* convert_rgb (int order, int bpp);- #endif /* YUV2RGB_H */