apply my planned mosaic optimizations to BG

This commit is contained in:
zeromus 2009-01-22 07:24:57 +00:00
parent 3e57278979
commit 672b8e3c8f
2 changed files with 117 additions and 44 deletions

View File

@ -75,6 +75,9 @@ extern BOOL click;
NDS_Screen MainScreen;
NDS_Screen SubScreen;
//instantiate static instance
GPU::MosaicLookup GPU::mosaicLookup;
//#define DEBUG_TRI
CACHE_ALIGN u8 GPU_screen[4*256*192];
@ -212,6 +215,7 @@ u16 fadeOutColors[17][0x8000];
// INITIALIZATION
/*****************************************************************************/
static void GPU_InitFadeColors()
{
/*
@ -1589,50 +1593,31 @@ static BOOL setFinal3DColorSpecialDecreaseWnd(GPU *gpu, u32 passing, u8 *dst, u1
return windowDraw;
}
static void __setFinalColorBck(GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, bool opaque)
INLINE static void __setFinalColorBck(GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, bool opaque)
{
struct _BGxCNT *bgCnt = &(gpu->dispx_st)->dispx_BGxCNT[bgnum].bits;
bool enabled = bgCnt->Mosaic_Enable;
// if(!opaque) color = 0xFFFF;
// else color &= 0x7FFF;
if(!opaque)
return;
if(enabled)
{
u8 y = gpu->currLine;
//I intend to cache all this at the beginning of line rendering
u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0);
u8 mw = (mosaic_control & 0xF) +1 ; // horizontal granularity of the mosaic
u8 mh = ((mosaic_control>>4) & 0xF) +1 ; // vertical granularity of the mosaic
//mosaic test hacks
//mw = 4;
//mh = 4;
//enabled = true;
//I intend to make all this a 16x256 lookup table
// if(enabled)
{
bool x_zero = (x%mw)==0;
bool y_zero = (y%mh)==0;
int x_int;
if(enabled)
x_int = x/mw*mw;
else
x_int = x;
if(x_zero && y_zero) {}
else color = gpu->MosaicColors.bg[bgnum][x_int];
gpu->MosaicColors.bg[bgnum][x] = color;
}
//due to this early out, we will get incorrect behavior in cases where
//we enable mosaic in the middle of a frame. this is deemed unlikely.
if(!gpu->curr_mosaic_enabled) {
if(opaque) goto finish;
else return;
}
// if(color != 0xFFFF)
if(!opaque) color = 0xFFFF;
else color &= 0x7FFF;
//due to the early out, enabled must always be true
//int x_int = enabled ? GPU::mosaicLookup.width[x].trunc : x;
int x_int = GPU::mosaicLookup.width[x].trunc;
if(GPU::mosaicLookup.width[x].begin && GPU::mosaicLookup.height[gpu->currLine].begin) {}
else color = gpu->MosaicColors.bg[bgnum][x_int];
gpu->MosaicColors.bg[bgnum][x] = color;
if(color != 0xFFFF)
{
finish:
gpu->setFinalColorBck(gpu,0,bgnum,dst,color,x);
}
}
void mosaicSpriteLinePixel(GPU * gpu, int x, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
@ -3079,6 +3064,13 @@ static void GPU_ligne_layer(NDS_Screen * screen, u16 l)
i16 = item->BGs[i];
if (gpu->LayersEnable[i16])
{
struct _BGxCNT *bgCnt = &(gpu->dispx_st)->dispx_BGxCNT[i16].bits;
gpu->curr_mosaic_enabled = bgCnt->Mosaic_Enable;
//mosaic test hacks
//gpu->curr_mosaic_enabled = true;
if (gpu->core == GPU_MAIN)
{
if (i16 == 0 && dispCnt->BG0_3D)
@ -3313,7 +3305,18 @@ static INLINE void GPU_ligne_MasterBrightness(NDS_Screen * screen, u16 l)
void GPU_ligne(NDS_Screen * screen, u16 l)
{
GPU * gpu = screen->gpu;
//cache some parameters which are assumed to be stable throughout the rendering of the entire line
gpu->currLine = (u8)l;
u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0);
u16 mosaic_width = (mosaic_control & 0xF);
u16 mosaic_height = ((mosaic_control>>4) & 0xF);
//mosaic test hacks
//mosaic_width = mosaic_height = 3;
GPU::mosaicLookup.width = &GPU::mosaicLookup.table[mosaic_width][0];
GPU::mosaicLookup.height = &GPU::mosaicLookup.table[mosaic_height][0];
// initialize the scanline black
// not doing this causes invalid colors when all active BGs are prevented to draw at some place
@ -3370,3 +3373,53 @@ bool gpu_loadstate(std::istream* is)
is->read((char*)GPU_screen,sizeof(GPU_screen));
return !is->fail();
}
//here is an old bg mosaic with some old code commented out. I am going to leave it here for a while to look at it
//sometimes in case I find a problem with the mosaic.
//static void __setFinalColorBck(GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, bool opaque)
//{
// struct _BGxCNT *bgCnt = &(gpu->dispx_st)->dispx_BGxCNT[bgnum].bits;
// bool enabled = bgCnt->Mosaic_Enable;
//
//// if(!opaque) color = 0xFFFF;
//// else color &= 0x7FFF;
// if(!opaque)
// return;
//
// //mosaic test hacks
// enabled = true;
//
// //due to this early out, we will get incorrect behavior in cases where
// //we enable mosaic in the middle of a frame. this is deemed unlikely.
// if(enabled)
// {
// u8 y = gpu->currLine;
//
// //I intend to cache all this at the beginning of line rendering
//
// u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0);
// u8 mw = (mosaic_control & 0xF);
// u8 mh = ((mosaic_control>>4) & 0xF);
//
// //mosaic test hacks
// mw = 3;
// mh = 3;
//
// MosaicLookup::TableEntry &te_x = mosaicLookup.table[mw][x];
// MosaicLookup::TableEntry &te_y = mosaicLookup.table[mh][y];
//
// //int x_int;
// //if(enabled)
// int x_int = te_x.trunc;
// //else x_int = x;
//
// if(te_x.begin && te_y.begin) {}
// else color = gpu->MosaicColors.bg[bgnum][x_int];
// gpu->MosaicColors.bg[bgnum][x] = color;
// }
//
//// if(color != 0xFFFF)
// gpu->setFinalColorBck(gpu,0,bgnum,dst,color,x);
//}

View File

@ -589,9 +589,7 @@ typedef struct
#define ARM9MEM_AOBJ 0x06400000
#define ARM9MEM_BOBJ 0x06600000
typedef struct _GPU GPU;
struct _GPU
struct GPU
{
// some structs are becoming redundant
// some functions too (no need to recopy some vars as it is done by MMU)
@ -621,7 +619,6 @@ struct _GPU
u8 sprNum[256];
u8 core;
u8 dispMode;
@ -677,8 +674,31 @@ struct _GPU
u32 MasterBrightFactor;
u8 bgPixels[256];
u8 currLine;
static struct MosaicLookup {
struct TableEntry {
u8 begin, trunc;
} table[16][256];
MosaicLookup() {
for(int m=0;m<16;m++)
for(int i=0;i<256;i++) {
int mosaic = m+1;
TableEntry &te = table[m][i];
te.begin = (i%mosaic==0);
te.trunc = i/mosaic*mosaic;
}
}
TableEntry *width, *height;
} mosaicLookup;
bool curr_mosaic_enabled;
BOOL (*setFinalColorBck)(GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x);
BOOL (*setFinalColorSpr)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x);
BOOL (*setFinalColor3D) (GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u16 x);