IPU: Reference (slow but clear) implementation of yuv2rgb which could also be used as an alternative for SSEless processors, as if we really care about them.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3482 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1 2010-07-13 23:31:33 +00:00
parent 20292ca15c
commit 240349ea47
3 changed files with 43 additions and 12 deletions

View File

@ -1158,7 +1158,7 @@ void __fastcall ipu_csc(macroblock_8 *mb8, macroblock_rgb32 *rgb32, int sgn)
int i;
u8* p = (u8*)rgb32;
yuv2rgb_sse2();
yuv2rgb();
if (s_thresh[0] > 0)
{

View File

@ -23,10 +23,38 @@
#include "IPU.h"
#include "yuv2rgb.h"
#define IPU_Y_BIAS 16
#define IPU_C_BIAS 128
#define IPU_Y_COEFF 0x95 // 1.1640625
#define IPU_GCR_COEFF -0x68 // -0.8125
#define IPU_GCB_COEFF -0x32 // -0.390625
#define IPU_RCR_COEFF 0xcc // 1.59375
#define IPU_BCB_COEFF 0x102 // 2.015625
// conforming implementation for reference, do not optimise
void yuv2rgb_reference(void)
{
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x++)
{
s32 lum = (IPU_Y_COEFF * (max(0, (s32)mb8.Y[y][x] - IPU_Y_BIAS))) >> 6;
s32 rcr = (IPU_RCR_COEFF * ((s32)mb8.Cr[y>>1][x>>1] - 128)) >> 6;
s32 gcr = (IPU_GCR_COEFF * ((s32)mb8.Cr[y>>1][x>>1] - 128)) >> 6;
s32 gcb = (IPU_GCB_COEFF * ((s32)mb8.Cb[y>>1][x>>1] - 128)) >> 6;
s32 bcb = (IPU_BCB_COEFF * ((s32)mb8.Cb[y>>1][x>>1] - 128)) >> 6;
rgb32.c[y][x].r = max(0, min(255, (lum + rcr + 1) >> 1));
rgb32.c[y][x].g = max(0, min(255, (lum + gcr + gcb + 1) >> 1));
rgb32.c[y][x].b = max(0, min(255, (lum + bcb + 1) >> 1));
rgb32.c[y][x].a = 0x80; // the norm to save doing this on the alpha pass
}
}
// Everything below is bit accurate to the IPU specification (except maybe rounding).
// Know the specification before you touch it.
#define SSE_COEFFICIENTS(x) \
{(x)<<2,(x)<<2,(x)<<2,(x)<<2,(x)<<2,(x)<<2,(x)<<2,(x)<<2}
#define SSE_BYTES(x) {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}
#define SSE_WORDS(x) {x, x, x, x, x, x, x, x}
#define SSE_COEFFICIENTS(x) SSE_WORDS((x)<<2)
struct SSE2_Tables
{
@ -58,19 +86,19 @@ enum
static const __aligned16 SSE2_Tables sse2_tables =
{
{0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}, // c_bias
{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, // y_bias
{0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00}, // y_mask
SSE_WORDS(0x8000), // c_bias
SSE_BYTES(IPU_Y_BIAS), // y_bias
SSE_WORDS(0xff00), // y_mask
// Specifying round off instead of round down as everywhere else
// implies that this is right
{1,1,1,1,1,1,1,1}, // round_1bit
SSE_WORDS(1), // round_1bit
SSE_COEFFICIENTS(0x95), // 1.1640625 [Y_coefficients]
SSE_COEFFICIENTS(-0x68), // -0.8125 [GCr_coefficients]
SSE_COEFFICIENTS(-0x32), // -0.390625 [GCb_coefficients]
SSE_COEFFICIENTS(0xcc), // 1.59375 [RCr_coefficients]
SSE_COEFFICIENTS(0x102), // 2.015625 [BCb_coefficients]
SSE_COEFFICIENTS(IPU_Y_COEFF),
SSE_COEFFICIENTS(IPU_GCR_COEFF),
SSE_COEFFICIENTS(IPU_GCB_COEFF),
SSE_COEFFICIENTS(IPU_RCR_COEFF),
SSE_COEFFICIENTS(IPU_BCB_COEFF),
};
static __aligned16 u16 yuv2rgb_temp[3][8];

View File

@ -15,5 +15,8 @@
#pragma once
#define yuv2rgb yuv2rgb_sse2
extern void yuv2rgb_reference(void);
extern void yuv2rgb_sse2(void);
extern void yuv2rgb_init(void);