PS_GPU Refactor pt. 2

This commit is contained in:
twinaphex 2017-04-22 17:43:39 +02:00
parent 7bf0144c2a
commit bd0ebd8623
6 changed files with 215 additions and 601 deletions

View File

@ -421,7 +421,7 @@ void GPU_ResetTS(void)
gpu->lastts = 0;
}
#include "gpu_common.cpp"
#include "gpu_common.h"
#include "gpu_polygon.cpp"
#include "gpu_sprite.cpp"
#include "gpu_line.cpp"
@ -432,25 +432,11 @@ template<int numvertices, bool shaded, bool textured,
static void G_Command_DrawPolygon(PS_GPU* g, const uint32 *cb)
{
if (PGXP_enabled())
g->Command_DrawPolygon<numvertices, shaded, textured,
BlendMode, TexMult, TexMode_TA, MaskEval_TA, true>(cb);
Command_DrawPolygon<numvertices, shaded, textured,
BlendMode, TexMult, TexMode_TA, MaskEval_TA, true>(g, cb);
else
g->Command_DrawPolygon<numvertices, shaded, textured,
BlendMode, TexMult, TexMode_TA, MaskEval_TA, false>(cb);
}
template<uint8 raw_size, bool textured, int BlendMode, bool TexMult,
uint32 TexMode_TA, bool MaskEval_TA>
static void G_Command_DrawSprite(PS_GPU* g, const uint32 *cb)
{
g->Command_DrawSprite<raw_size, textured, BlendMode, TexMult,
TexMode_TA, MaskEval_TA>(cb);
}
template<bool polyline, bool goraud, int BlendMode, bool MaskEval_TA>
static void G_Command_DrawLine(PS_GPU* g, const uint32 *cb)
{
g->Command_DrawLine<polyline, goraud, BlendMode, MaskEval_TA>(cb);
Command_DrawPolygon<numvertices, shaded, textured,
BlendMode, TexMult, TexMode_TA, MaskEval_TA, false>(g, cb);
}
void PS_GPU::InvalidateTexCache()
@ -466,12 +452,12 @@ void PS_GPU::InvalidateCache()
InvalidateTexCache();
}
static void G_Command_ClearCache(PS_GPU* g, const uint32 *cb)
static void Command_ClearCache(PS_GPU* g, const uint32 *cb)
{
g->InvalidateCache();
}
static void G_Command_IRQ(PS_GPU* g, const uint32 *cb)
static void Command_IRQ(PS_GPU* g, const uint32 *cb)
{
g->IRQPending = true;
IRQ_Assert(IRQ_GPU, g->IRQPending);
@ -479,7 +465,7 @@ static void G_Command_IRQ(PS_GPU* g, const uint32 *cb)
// Special RAM write mode(16 pixels at a time),
// does *not* appear to use mask drawing environment settings.
static void G_Command_FBFill(PS_GPU* gpu, const uint32 *cb)
static void Command_FBFill(PS_GPU* gpu, const uint32 *cb)
{
unsigned y;
int32_t r = cb[0] & 0xFF;
@ -515,7 +501,7 @@ static void G_Command_FBFill(PS_GPU* gpu, const uint32 *cb)
rsx_intf_fill_rect(cb[0], destX, destY, width, height);
}
static void G_Command_FBCopy(PS_GPU* g, const uint32 *cb)
static void Command_FBCopy(PS_GPU* g, const uint32 *cb)
{
unsigned y;
int32_t sourceX = (cb[1] >> 0) & 0x3FF;
@ -568,7 +554,7 @@ static void G_Command_FBCopy(PS_GPU* g, const uint32 *cb)
rsx_intf_copy_rect(sourceX, sourceY, destX, destY, width, height, g->MaskEvalAND != 0, g->MaskSetOR != 0);
}
static void G_Command_FBWrite(PS_GPU* g, const uint32 *cb)
static void Command_FBWrite(PS_GPU* g, const uint32 *cb)
{
//assert(InCmd == INCMD_NONE);
@ -597,7 +583,7 @@ static void G_Command_FBWrite(PS_GPU* g, const uint32 *cb)
* raw_height == 0, or raw_height != 0x200 && (raw_height & 0x1FF) == 0
*/
static void G_Command_FBRead(PS_GPU* g, const uint32 *cb)
static void Command_FBRead(PS_GPU* g, const uint32 *cb)
{
//assert(g->InCmd == INCMD_NONE);
@ -622,7 +608,7 @@ static void G_Command_FBRead(PS_GPU* g, const uint32 *cb)
g->InCmd = INCMD_FBREAD;
}
static void G_Command_DrawMode(PS_GPU* g, const uint32 *cb)
static void Command_DrawMode(PS_GPU* g, const uint32 *cb)
{
const uint32 cmdw = *cb;
@ -635,7 +621,7 @@ static void G_Command_DrawMode(PS_GPU* g, const uint32 *cb)
//printf("*******************DFE: %d -- scanline=%d\n", dfe, scanline);
}
static void G_Command_TexWindow(PS_GPU* g, const uint32 *cb)
static void Command_TexWindow(PS_GPU* g, const uint32 *cb)
{
g->tww = (*cb & 0x1F);
g->twh = ((*cb >> 5) & 0x1F);
@ -646,7 +632,7 @@ static void G_Command_TexWindow(PS_GPU* g, const uint32 *cb)
rsx_intf_set_tex_window(g->tww, g->twh, g->twx, g->twy);
}
static void G_Command_Clip0(PS_GPU* g, const uint32 *cb)
static void Command_Clip0(PS_GPU* g, const uint32 *cb)
{
g->ClipX0 = *cb & 1023;
g->ClipY0 = (*cb >> 10) & 1023;
@ -654,7 +640,7 @@ static void G_Command_Clip0(PS_GPU* g, const uint32 *cb)
g->ClipX1, g->ClipY1);
}
static void G_Command_Clip1(PS_GPU* g, const uint32 *cb)
static void Command_Clip1(PS_GPU* g, const uint32 *cb)
{
g->ClipX1 = *cb & 1023;
g->ClipY1 = (*cb >> 10) & 1023;
@ -662,7 +648,7 @@ static void G_Command_Clip1(PS_GPU* g, const uint32 *cb)
g->ClipX1, g->ClipY1);
}
static void G_Command_DrawingOffset(PS_GPU* g, const uint32 *cb)
static void Command_DrawingOffset(PS_GPU* g, const uint32 *cb)
{
g->OffsX = sign_x_to_s32(11, (*cb & 2047));
g->OffsY = sign_x_to_s32(11, ((*cb >> 11) & 2047));
@ -670,7 +656,7 @@ static void G_Command_DrawingOffset(PS_GPU* g, const uint32 *cb)
//fprintf(stderr, "[GPU] Drawing offset: %d(raw=%d) %d(raw=%d) -- %d\n", OffsX, *cb, OffsY, *cb >> 11, scanline);
}
static void G_Command_MaskSetting(PS_GPU* g, const uint32 *cb)
static void Command_MaskSetting(PS_GPU* g, const uint32 *cb)
{
//printf("Mask setting: %08x\n", *cb);
g->MaskSetOR = (*cb & 1) ? 0x8000 : 0x0000;
@ -683,8 +669,8 @@ CTEntry PS_GPU::Commands[256] =
{
/* 0x00 */
NULLCMD(),
OTHER_HELPER(1, 2, false, G_Command_ClearCache),
OTHER_HELPER(3, 3, false, G_Command_FBFill),
OTHER_HELPER(1, 2, false, Command_ClearCache),
OTHER_HELPER(3, 3, false, Command_FBFill),
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
@ -693,7 +679,7 @@ CTEntry PS_GPU::Commands[256] =
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
OTHER_HELPER(1, 1, false, G_Command_IRQ),
OTHER_HELPER(1, 1, false, Command_IRQ),
/* 0x20 */
POLY_HELPER(0x20),
@ -796,23 +782,23 @@ CTEntry PS_GPU::Commands[256] =
SPR_HELPER(0x7f),
/* 0x80 ... 0x9F */
OTHER_HELPER_X32(4, 2, false, G_Command_FBCopy),
OTHER_HELPER_X32(4, 2, false, Command_FBCopy),
/* 0xA0 ... 0xBF */
OTHER_HELPER_X32(3, 2, false, G_Command_FBWrite),
OTHER_HELPER_X32(3, 2, false, Command_FBWrite),
/* 0xC0 ... 0xDF */
OTHER_HELPER_X32(3, 2, false, G_Command_FBRead),
OTHER_HELPER_X32(3, 2, false, Command_FBRead),
/* 0xE0 */
NULLCMD(),
OTHER_HELPER(1, 2, false, G_Command_DrawMode),
OTHER_HELPER(1, 2, false, G_Command_TexWindow),
OTHER_HELPER(1, 1, true, G_Command_Clip0),
OTHER_HELPER(1, 1, true, G_Command_Clip1),
OTHER_HELPER(1, 1, true, G_Command_DrawingOffset),
OTHER_HELPER(1, 2, false, G_Command_MaskSetting),
OTHER_HELPER(1, 2, false, Command_DrawMode),
OTHER_HELPER(1, 2, false, Command_TexWindow),
OTHER_HELPER(1, 1, true, Command_Clip0),
OTHER_HELPER(1, 1, true, Command_Clip1),
OTHER_HELPER(1, 1, true, Command_DrawingOffset),
OTHER_HELPER(1, 2, false, Command_MaskSetting),
NULLCMD(),
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
@ -930,11 +916,11 @@ void PS_GPU::ProcessFIFO(uint32_t in_count)
}
if ((cc >= 0x80) && (cc <= 0x9F))
G_Command_FBCopy(this, CB);
Command_FBCopy(this, CB);
else if ((cc >= 0xA0) && (cc <= 0xBF))
G_Command_FBWrite(this, CB);
Command_FBWrite(this, CB);
else if ((cc >= 0xC0) && (cc <= 0xDF))
G_Command_FBRead(this, CB);
Command_FBRead(this, CB);
else
{
if (command->func[abr][TexMode])

View File

@ -335,18 +335,13 @@ class PS_GPU
uint8_t DitherLUT[4][4][512]; // Y, X, 8-bit source value(256 extra for saturation)
private:
template<uint32 TexMode_TA>
void Update_CLUT_Cache(uint16 raw_clut);
template<int BlendMode>
void PlotPixelBlend(uint16_t bg_pix, uint16_t *fore_pix);
template<int BlendMode, bool MaskEval_TA, bool textured>
void PlotPixel(int32 x, int32 y, uint16 pix);
template<int BlendMode, bool MaskEval_TA, bool textured>
void PlotNativePixel(int32 x, int32 y, uint16 pix);
@ -354,45 +349,6 @@ class PS_GPU
uint16 GetTexel(uint32 clut_offset, int32 u, int32 v);
uint16 ModTexel(uint16 texel, int32 r, int32 g, int32 b, const int32 dither_x, const int32 dither_y);
template<bool goraud, bool textured, int BlendMode, bool TexMult, uint32 TexMode, bool MaskEval_TA>
void DrawSpan(int y, uint32 clut_offset, const int32 x_start, const int32 x_bound, i_group ig, const i_deltas &idl);
template<bool shaded, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
void DrawTriangle(tri_vertex *vertices, uint32 clut);
template<bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA, bool FlipX, bool FlipY>
void DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg, uint8 v_arg, uint32 color, uint32 clut_offset);
template<bool goraud, int BlendMode, bool MaskEval_TA>
void DrawLine(line_point *vertices);
public:
template<int numvertices, bool shaded, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA, bool pgxp>
void Command_DrawPolygon(const uint32 *cb);
template<uint8 raw_size, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
void Command_DrawSprite(const uint32 *cb);
template<bool polyline, bool goraud, int BlendMode, bool MaskEval_TA>
void Command_DrawLine(const uint32 *cb);
void Command_ClearCache(const uint32 *cb);
void Command_IRQ(const uint32 *cb);
void Command_FBFill(const uint32 *cb);
void Command_FBCopy(const uint32 *cb);
void Command_FBWrite(const uint32 *cb);
void Command_FBRead(const uint32 *cb);
void Command_DrawMode(const uint32 *cb);
void Command_TexWindow(const uint32 *cb);
void Command_Clip0(const uint32 *cb);
void Command_Clip1(const uint32 *cb);
void Command_DrawingOffset(const uint32 *cb);
void Command_MaskSetting(const uint32 *cb);
void UpdateDisplayMode();
private:

View File

@ -1,329 +0,0 @@
template<int BlendMode>
INLINE void PS_GPU::PlotPixelBlend(uint16_t bg_pix, uint16_t *fore_pix)
{
/*
* fore_pix - foreground - the screen
* bg_pix - background - the texture
*/
uint32_t sum, carry;
/* Efficient 15bpp pixel math algorithms from blargg */
switch(BlendMode)
{
/* 0.5 x B + 0.5 x F */
case BLEND_MODE_AVERAGE:
bg_pix |= 0x8000;
*fore_pix = ((*fore_pix + bg_pix) - ((*fore_pix ^ bg_pix) & 0x0421)) >> 1;
break;
/* 1.0 x B + 1.0 x F */
case BLEND_MODE_ADD:
bg_pix &= ~0x8000;
sum = *fore_pix + bg_pix;
carry = (sum - ((*fore_pix ^ bg_pix) & 0x8421)) & 0x8420;
*fore_pix = (sum - carry) | (carry - (carry >> 5));
break;
/* 1.0 x B - 1.0 x F */
case BLEND_MODE_SUBTRACT:
{
uint32_t diff;
uint32_t borrow;
bg_pix |= 0x8000;
*fore_pix &= ~0x8000;
diff = bg_pix - *fore_pix + 0x108420;
borrow = (diff - ((bg_pix ^ *fore_pix) & 0x108420)) & 0x108420;
*fore_pix = (diff - borrow) & (borrow - (borrow >> 5));
}
break;
/* 1.0 x B + 0.25 * F */
case BLEND_MODE_ADD_FOURTH:
bg_pix &= ~0x8000;
*fore_pix = ((*fore_pix >> 2) & 0x1CE7) | 0x8000;
sum = *fore_pix + bg_pix;
carry = (sum - ((*fore_pix ^ bg_pix) & 0x8421)) & 0x8420;
*fore_pix = (sum - carry) | (carry - (carry >> 5));
break;
}
}
template<int BlendMode, bool MaskEval_TA, bool textured>
INLINE void PS_GPU::PlotPixel(int32_t x, int32_t y, uint16_t fore_pix)
{
// More Y precision bits than GPU RAM installed in (non-arcade, at least) Playstation hardware.
y &= (512 << upscale_shift) - 1;
if(BlendMode >= 0 && (fore_pix & 0x8000))
{
// Don't use bg_pix for mask evaluation, it's modified in blending code paths.
uint16_t bg_pix = vram_fetch(x, y);
PlotPixelBlend<BlendMode>(bg_pix, &fore_pix);
}
if(!MaskEval_TA || !(vram_fetch(x, y) & 0x8000))
vram_put(x, y, (textured ? fore_pix : (fore_pix & 0x7FFF)) | MaskSetOR);
}
/// Copy of PlotPixel without internal upscaling, used to draw lines and sprites
template<int BlendMode, bool MaskEval_TA, bool textured>
INLINE void PS_GPU::PlotNativePixel(int32_t x, int32_t y, uint16_t fore_pix)
{
uint16_t output;
y &= 511; // More Y precision bits than GPU RAM installed in (non-arcade, at least) Playstation hardware.
if(BlendMode >= 0 && (fore_pix & 0x8000))
{
uint16_t bg_pix = texel_fetch(x, y); // Don't use bg_pix for mask evaluation, it's modified in blending code paths.
PlotPixelBlend<BlendMode>(bg_pix, &fore_pix);
}
if(!MaskEval_TA || !(texel_fetch(x, y) & 0x8000))
texel_put(x, y, (textured ? fore_pix : (fore_pix & 0x7FFF)) | MaskSetOR);
}
INLINE uint16_t PS_GPU::ModTexel(uint16_t texel, int32_t r, int32_t g, int32_t b, const int32_t dither_x, const int32_t dither_y)
{
uint8_t *dither_offset = DitherLUT[dither_y][dither_x];
return (texel & 0x8000)
| (dither_offset[(((texel & 0x1F) * r) >> (5 - 1))] << 0)
| (dither_offset[(((texel & 0x3E0) * g) >> (10 - 1))] << 5)
| (dither_offset[(((texel & 0x7C00) * b) >> (15 - 1))] << 10);
}
template<uint32_t TexMode_TA>
INLINE void PS_GPU::Update_CLUT_Cache(uint16 raw_clut)
{
if(TexMode_TA < 2)
{
const uint32_t new_ccvb = ((raw_clut & 0x7FFF) | (TexMode_TA << 16)); // Confirmed upper bit of raw_clut is ignored(at least on SCPH-5501's GPU).
if(CLUT_Cache_VB != new_ccvb)
{
uint32 y = (raw_clut >> 6) & 0x1FF;
const uint32_t cxo = (raw_clut & 0x3F) << 4;
const uint32_t count = (TexMode_TA ? 256 : 16);
DrawTimeAvail -= count;
for(unsigned i = 0; i < count; i++)
{
CLUT_Cache[i] = texel_fetch((cxo + i) & 0x3FF, y);
}
CLUT_Cache_VB = new_ccvb;
}
}
}
#if 0
TexWindowX_AND = ~(tww << 3);
TexWindowX_ADD = ((twx & tww) << 3;
TexWindowY_AND = ~(twh << 3);
TexWindowY_OR = (twy & twh) << 3;
uint32_t u = (u_arg & TexWindowX_AND) TexWindowX_OR;
uint32_t v = (v_arg & TexWindowY_AND) | TexWindowY_OR;
uint32_t fbtex_x = TexPageX + (u >> (2 - TexMode_TA));
uint32_t fbtex_y = TexPageY + v;
uint16 fbw = GPURAM[fbtex_y][fbtex_x & 1023];
if(TexMode_TA != 2)
{
if(TexMode_TA == 0)
fbw = (fbw >> ((u & 3) * 4)) & 0xF;
else
fbw = (fbw >> ((u & 1) * 8)) & 0xFF;
fbw = CLUT_Cache[fbw];
}
#endif
INLINE void PS_GPU::RecalcTexWindowStuff(void)
{
unsigned x, y;
const unsigned TexWindowX_AND = ~(tww << 3);
const unsigned TexWindowX_OR = (twx & tww) << 3;
const unsigned TexWindowY_AND = ~(twh << 3);
const unsigned TexWindowY_OR = (twy & twh) << 3;
for(x = 0; x < 256; x++)
TexWindowXLUT[x] = (x & TexWindowX_AND) | TexWindowX_OR;
for(y = 0; y < 256; y++)
TexWindowYLUT[y] = (y & TexWindowY_AND) | TexWindowY_OR;
memset(TexWindowXLUT_Pre, TexWindowXLUT[0], sizeof(TexWindowXLUT_Pre));
memset(TexWindowXLUT_Post, TexWindowXLUT[255], sizeof(TexWindowXLUT_Post));
memset(TexWindowYLUT_Pre, TexWindowYLUT[0], sizeof(TexWindowYLUT_Pre));
memset(TexWindowYLUT_Post, TexWindowYLUT[255], sizeof(TexWindowYLUT_Post));
SUCV.TWX_AND = ~(tww << 3);
SUCV.TWX_ADD = ((twx & tww) << 3) + (TexPageX << (2 - std::min<uint32_t>(2, TexMode)));
SUCV.TWY_AND = ~(twh << 3);
SUCV.TWY_ADD = ((twy & twh) << 3) + TexPageY;
}
template<uint32_t TexMode_TA>
INLINE uint16_t PS_GPU::GetTexel(const uint32_t clut_offset, int32_t u_arg, int32_t v_arg)
{
#if 0
/* TODO */
uint32_t u_ext = ((u_arg & SUCV.TWX_AND) + SUCV.TWX_ADD);
uint32_t fbtex_x = ((u_ext >> (2 - TexMode_TA))) & 1023;
uint32_t fbtex_y = (v_arg & SUCV.TWY_AND) + SUCV.TWY_ADD;
uint32_t gro = fbtex_y * 1024U + fbtex_x;
decltype(&TexCache[0]) c;
switch(TexMode_TA)
{
case 0: c = &TexCache[((gro >> 2) & 0x3) | ((gro >> 8) & 0xFC)]; break; // 64x64
case 1: c = &TexCache[((gro >> 2) & 0x7) | ((gro >> 7) & 0xF8)]; break; // 64x32 (NOT 32x64!)
case 2: c = &TexCache[((gro >> 2) & 0x7) | ((gro >> 7) & 0xF8)]; break; // 32x32
}
if(MDFN_UNLIKELY(c->Tag != (gro &~ 0x3)))
{
// SCPH-1001 old revision GPU is like(for sprites at least): (20 + 4)
// SCPH-5501 new revision GPU is like(for sprites at least): (12 + 4)
//
// We'll be conservative and just go with 4 for now, until we can run some tests with triangles too.
//
DrawTimeAvail -= 4;
c->Data[0] = (&GPURAM[0][0])[gro &~ 0x3];
c->Data[1] = (&GPURAM[0][1])[gro &~ 0x3];
c->Data[2] = (&GPURAM[0][2])[gro &~ 0x3];
c->Data[3] = (&GPURAM[0][3])[gro &~ 0x3];
c->Tag = (gro &~ 0x3);
}
uint16 fbw = c->Data[gro & 0x3];
#else
uint32_t u_ext = TexWindowXLUT[u_arg];
uint32_t v = TexWindowYLUT[v_arg];
uint32_t fbtex_x = TexPageX + (u_ext >> (2 - TexMode_TA));
uint32_t fbtex_y = TexPageY + v;
uint16_t fbw = texel_fetch(fbtex_x & 1023, fbtex_y);
#endif
if(TexMode_TA != 2)
{
if(TexMode_TA == 0)
fbw = (fbw >> ((u_ext & 3) * 4)) & 0xF;
else
fbw = (fbw >> ((u_ext & 1) * 8)) & 0xFF;
#if 0
fbw = CLUT_Cache[fbw];
#else
fbw = texel_fetch((clut_offset + fbw) & 1023, (clut_offset >> 10) & 511);
#endif
}
return(fbw);
}
static INLINE bool LineSkipTest(PS_GPU* g, unsigned y)
{
#if 0
DisplayFB_XStart >= OffsX && DisplayFB_YStart >= OffsY &&
((y & 1) == (DisplayFB_CurLineYReadout & 1))
#endif
if((g->DisplayMode & 0x24) != 0x24)
return false;
if(!g->dfe && ((y & 1) == ((g->DisplayFB_YStart + g->field_ram_readout) & 1))/* && !DisplayOff*/) //&& (y >> 1) >= DisplayFB_YStart && (y >> 1) < (DisplayFB_YStart + (VertEnd - VertStart)))
return true;
return false;
}
// Command table generation macros follow:
//#define BM_HELPER(fg) { fg(0), fg(1), fg(2), fg(3) }
#define POLY_HELPER_SUB(bm, cv, tm, mam) \
G_Command_DrawPolygon<3 + ((cv & 0x8) >> 3), ((cv & 0x10) >> 4), ((cv & 0x4) >> 2), ((cv & 0x2) >> 1) ? bm : -1, ((cv & 1) ^ 1) & ((cv & 0x4) >> 2), tm, mam >
#define POLY_HELPER_FG(bm, cv) \
{ \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 0 : 0), 0), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 1 : 0), 0), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 0), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 0), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 0 : 0), 1), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 1 : 0), 1), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 1), \
POLY_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 1), \
}
#define POLY_HELPER(cv) \
{ \
{ POLY_HELPER_FG(0, cv), POLY_HELPER_FG(1, cv), POLY_HELPER_FG(2, cv), POLY_HELPER_FG(3, cv) }, \
1 + (3 /*+ ((cv & 0x8) >> 3)*/) * ( 1 + ((cv & 0x4) >> 2) + ((cv & 0x10) >> 4) ) - ((cv & 0x10) >> 4), \
1, \
false \
}
#define SPR_HELPER_SUB(bm, cv, tm, mam) G_Command_DrawSprite<(cv >> 3) & 0x3, ((cv & 0x4) >> 2), ((cv & 0x2) >> 1) ? bm : -1, ((cv & 1) ^ 1) & ((cv & 0x4) >> 2), tm, mam>
#define SPR_HELPER_FG(bm, cv) \
{ \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 0 : 0), 0), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 1 : 0), 0), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 0), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 0), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 0 : 0), 1), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 1 : 0), 1), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 1), \
SPR_HELPER_SUB(bm, cv, ((cv & 0x4) ? 2 : 0), 1), \
}
#define SPR_HELPER(cv) \
{ \
{ SPR_HELPER_FG(0, cv), SPR_HELPER_FG(1, cv), SPR_HELPER_FG(2, cv), SPR_HELPER_FG(3, cv) }, \
2 + ((cv & 0x4) >> 2) + ((cv & 0x18) ? 0 : 1), \
2 | ((cv & 0x4) >> 2) | ((cv & 0x18) ? 0 : 1), /* |, not +, for this */ \
false \
}
#define LINE_HELPER_SUB(bm, cv, mam) G_Command_DrawLine<((cv & 0x08) >> 3), ((cv & 0x10) >> 4), ((cv & 0x2) >> 1) ? bm : -1, mam>
#define LINE_HELPER_FG(bm, cv) \
{ \
LINE_HELPER_SUB(bm, cv, 0), \
LINE_HELPER_SUB(bm, cv, 0), \
LINE_HELPER_SUB(bm, cv, 0), \
LINE_HELPER_SUB(bm, cv, 0), \
LINE_HELPER_SUB(bm, cv, 1), \
LINE_HELPER_SUB(bm, cv, 1), \
LINE_HELPER_SUB(bm, cv, 1), \
LINE_HELPER_SUB(bm, cv, 1) \
}
#define LINE_HELPER(cv) \
{ \
{ LINE_HELPER_FG(0, cv), LINE_HELPER_FG(1, cv), LINE_HELPER_FG(2, cv), LINE_HELPER_FG(3, cv) }, \
3 + ((cv & 0x10) >> 4), \
1, \
false \
}
#define OTHER_HELPER_FG(bm, arg_ptr) { arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr }
#define OTHER_HELPER(arg_cs, arg_fbcs, arg_ss, arg_ptr) { { OTHER_HELPER_FG(0, arg_ptr), OTHER_HELPER_FG(1, arg_ptr), OTHER_HELPER_FG(2, arg_ptr), OTHER_HELPER_FG(3, arg_ptr) }, arg_cs, arg_fbcs, arg_ss }
#define OTHER_HELPER_X2(arg_cs, arg_fbcs, arg_ss, arg_ptr) OTHER_HELPER(arg_cs, arg_fbcs, arg_ss, arg_ptr), OTHER_HELPER(arg_cs, arg_fbcs, arg_ss, arg_ptr)
#define OTHER_HELPER_X4(arg_cs, arg_fbcs, arg_ss, arg_ptr) OTHER_HELPER_X2(arg_cs, arg_fbcs, arg_ss, arg_ptr), OTHER_HELPER_X2(arg_cs, arg_fbcs, arg_ss, arg_ptr)
#define OTHER_HELPER_X8(arg_cs, arg_fbcs, arg_ss, arg_ptr) OTHER_HELPER_X4(arg_cs, arg_fbcs, arg_ss, arg_ptr), OTHER_HELPER_X4(arg_cs, arg_fbcs, arg_ss, arg_ptr)
#define OTHER_HELPER_X16(arg_cs, arg_fbcs, arg_ss, arg_ptr) OTHER_HELPER_X8(arg_cs, arg_fbcs, arg_ss, arg_ptr), OTHER_HELPER_X8(arg_cs, arg_fbcs, arg_ss, arg_ptr)
#define OTHER_HELPER_X32(arg_cs, arg_fbcs, arg_ss, arg_ptr) OTHER_HELPER_X16(arg_cs, arg_fbcs, arg_ss, arg_ptr), OTHER_HELPER_X16(arg_cs, arg_fbcs, arg_ss, arg_ptr)
#define NULLCMD_FG(bm) { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
#define NULLCMD() { { NULLCMD_FG(0), NULLCMD_FG(1), NULLCMD_FG(2), NULLCMD_FG(3) }, 1, 1, true }

View File

@ -102,7 +102,7 @@ static INLINE void AddLineStep(line_fxp_coord *point, const line_fxp_step *step)
}
template<bool goraud, int BlendMode, bool MaskEval_TA>
void PS_GPU::DrawLine(line_point *points)
static void DrawLine(PS_GPU *gpu, line_point *points)
{
line_fxp_coord cur_point;
line_fxp_step step;
@ -113,7 +113,7 @@ void PS_GPU::DrawLine(line_point *points)
if(points[0].x > points[1].x && k)
vertex_swap(line_point, points[1], points[0]);
DrawTimeAvail -= k * 2;
gpu->DrawTimeAvail -= k * 2;
line_points_to_fixed_point_step<goraud>(&points[0], &points[1], k, &step);
line_point_to_fixed_point_coord<goraud>(&points[0], &step, &cur_point);
@ -124,7 +124,7 @@ void PS_GPU::DrawLine(line_point *points)
int32_t x = (cur_point.x >> LINE_XY_FRACTBITS) & 2047;
int32_t y = (cur_point.y >> LINE_XY_FRACTBITS) & 2047;
if(!LineSkipTest(this, y))
if(!LineSkipTest(gpu, y))
{
uint8_t r, g, b;
uint16_t pix = 0x8000;
@ -142,9 +142,9 @@ void PS_GPU::DrawLine(line_point *points)
b = points[0].b;
}
if(DitherEnabled())
if(gpu->DitherEnabled())
{
uint8_t *dither_offset = DitherLUT[y & 3][x & 3];
uint8_t *dither_offset = gpu->DitherLUT[y & 3][x & 3];
pix = 0x8000 | (dither_offset[r] << 0) | (dither_offset[g] << 5) |
(dither_offset[b] << 10);
}
@ -154,8 +154,8 @@ void PS_GPU::DrawLine(line_point *points)
}
// FIXME: There has to be a faster way than checking for being inside the drawing area for each pixel.
if(x >= ClipX0 && x <= ClipX1 && y >= ClipY0 && y <= ClipY1)
PlotNativePixel<BlendMode, MaskEval_TA, false>(x, y, pix);
if(x >= gpu->ClipX0 && x <= gpu->ClipX1 && y >= gpu->ClipY0 && y <= gpu->ClipY1)
gpu->PlotNativePixel<BlendMode, MaskEval_TA, false>(x, y, pix);
}
AddLineStep<goraud>(&cur_point, &step);
@ -163,17 +163,17 @@ void PS_GPU::DrawLine(line_point *points)
}
template<bool polyline, bool goraud, int BlendMode, bool MaskEval_TA>
INLINE void PS_GPU::Command_DrawLine(const uint32_t *cb)
static void Command_DrawLine(PS_GPU *gpu, const uint32_t *cb)
{
line_point points[2];
const uint8_t cc = cb[0] >> 24; // For pline handling later.
DrawTimeAvail -= 16; // FIXME, correct time.
gpu->DrawTimeAvail -= 16; // FIXME, correct time.
if(polyline && InCmd == INCMD_PLINE)
if(polyline && gpu->InCmd == INCMD_PLINE)
{
//printf("PLINE N\n");
points[0] = InPLine_PrevPoint;
points[0] = gpu->InPLine_PrevPoint;
}
else
{
@ -182,8 +182,8 @@ INLINE void PS_GPU::Command_DrawLine(const uint32_t *cb)
points[0].b = (*cb >> 16) & 0xFF;
cb++;
points[0].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + OffsX;
points[0].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + OffsY;
points[0].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + gpu->OffsX;
points[0].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + gpu->OffsY;
cb++;
}
@ -201,18 +201,18 @@ INLINE void PS_GPU::Command_DrawLine(const uint32_t *cb)
points[1].b = points[0].b;
}
points[1].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + OffsX;
points[1].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + OffsY;
points[1].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + gpu->OffsX;
points[1].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + gpu->OffsY;
cb++;
if(polyline)
{
InPLine_PrevPoint = points[1];
gpu->InPLine_PrevPoint = points[1];
if(InCmd != INCMD_PLINE)
if(gpu->InCmd != INCMD_PLINE)
{
InCmd = INCMD_PLINE;
InCmd_CC = cc;
gpu->InCmd = INCMD_PLINE;
gpu->InCmd_CC = cc;
}
}
@ -229,11 +229,11 @@ INLINE void PS_GPU::Command_DrawLine(const uint32_t *cb)
points[1].x, points[1].y,
((uint32_t)points[0].r) | ((uint32_t)points[0].g << 8) | ((uint32_t)points[0].b << 16),
((uint32_t)points[1].r) | ((uint32_t)points[1].g << 8) | ((uint32_t)points[1].b << 16),
DitherEnabled(),
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR);
gpu->MaskSetOR);
if (rsx_intf_has_software_renderer())
DrawLine<goraud, BlendMode, MaskEval_TA>(points);
DrawLine<goraud, BlendMode, MaskEval_TA>(gpu, points);
}

View File

@ -131,13 +131,13 @@ static INLINE void AddIDeltas_DY(i_group &ig, const i_deltas &idl, uint32_t coun
}
template<bool goraud, bool textured, int BlendMode, bool TexMult, uint32_t TexMode_TA, bool MaskEval_TA>
INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start, const int32_t x_bound, i_group ig, const i_deltas &idl)
static INLINE void DrawSpan(PS_GPU *gpu, int y, uint32_t clut_offset, const int32_t x_start, const int32_t x_bound, i_group ig, const i_deltas &idl)
{
int32_t xs = x_start, xb = x_bound;
int32 clipx0 = ClipX0 << upscale_shift;
int32 clipx1 = ClipX1 << upscale_shift;
int32 clipx0 = gpu->ClipX0 << gpu->upscale_shift;
int32 clipx1 = gpu->ClipX1 << gpu->upscale_shift;
if(LineSkipTest(this, y >> upscale_shift))
if(LineSkipTest(gpu, y >> gpu->upscale_shift))
return;
if(xs < xb) // (xs != xb)
@ -148,17 +148,17 @@ INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start,
if(xb > (clipx1 + 1))
xb = clipx1 + 1;
if(xs < xb && ((y & (upscale() - 1)) == 0))
if(xs < xb && ((y & (gpu->upscale() - 1)) == 0))
{
DrawTimeAvail -= (xb - xs) >> upscale_shift;
gpu->DrawTimeAvail -= (xb - xs) >> gpu->upscale_shift;
if(goraud || textured)
{
DrawTimeAvail -= (xb - xs) >> upscale_shift;
gpu->DrawTimeAvail -= (xb - xs) >> gpu->upscale_shift;
}
else if((BlendMode >= 0) || MaskEval_TA)
{
DrawTimeAvail -= (((((xb >> upscale_shift) + 1) & ~1) - ((xs >> upscale_shift) & ~1)) >> 1);
gpu->DrawTimeAvail -= (((((xb >> gpu->upscale_shift) + 1) & ~1) - ((xs >> gpu->upscale_shift) & ~1)) >> 1);
}
}
@ -182,9 +182,9 @@ INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start,
if(goraud)
{
r = RGB8SAT[COORD_GET_INT(ig.r)];
g = RGB8SAT[COORD_GET_INT(ig.g)];
b = RGB8SAT[COORD_GET_INT(ig.b)];
r = gpu->RGB8SAT[COORD_GET_INT(ig.r)];
g = gpu->RGB8SAT[COORD_GET_INT(ig.g)];
b = gpu->RGB8SAT[COORD_GET_INT(ig.b)];
}
else
{
@ -193,21 +193,19 @@ INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start,
b = COORD_GET_INT(ig.b);
}
bool dither = DitherEnabled();
int32_t dither_x = x >> dither_upscale_shift;
int32_t dither_y = y >> dither_upscale_shift;
bool dither = gpu->DitherEnabled();
int32_t dither_x = x >> gpu->dither_upscale_shift;
int32_t dither_y = y >> gpu->dither_upscale_shift;
if(textured)
{
uint16_t fbw = GetTexel<TexMode_TA>(clut_offset, COORD_GET_INT(ig.u), COORD_GET_INT(ig.v));
uint16_t fbw = gpu->GetTexel<TexMode_TA>(clut_offset, COORD_GET_INT(ig.u), COORD_GET_INT(ig.v));
if(fbw)
{
if(TexMult) {
fbw = ModTexel(fbw, r, g, b, (dither) ? (dither_x & 3) : 3, (dither) ? (dither_y & 3) : 2);
}
PlotPixel<BlendMode, MaskEval_TA, true>(x, y, fbw);
if(TexMult)
fbw = gpu->ModTexel(fbw, r, g, b, (dither) ? (dither_x & 3) : 3, (dither) ? (dither_y & 3) : 2);
gpu->PlotPixel<BlendMode, MaskEval_TA, true>(x, y, fbw);
}
}
else
@ -216,14 +214,14 @@ INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start,
if(goraud && dither)
{
uint8_t *dither_offset = DitherLUT[dither_y & 3][dither_x & 3];
uint8_t *dither_offset = gpu->DitherLUT[dither_y & 3][dither_x & 3];
pix = 0x8000 | (dither_offset[r] << 0) | (dither_offset[g] << 5) |
(dither_offset[b] << 10);
}
else
pix = 0x8000 | ((r >> 3) << 0) | ((g >> 3) << 5) | ((b >> 3) << 10);
PlotPixel<BlendMode, MaskEval_TA, false>(x, y, pix);
gpu->PlotPixel<BlendMode, MaskEval_TA, false>(x, y, pix);
}
AddIDeltas_DX<goraud, textured>(ig, idl);
@ -233,12 +231,12 @@ INLINE void PS_GPU::DrawSpan(int y, uint32_t clut_offset, const int32_t x_start,
}
template<bool goraud, bool textured, int BlendMode, bool TexMult, uint32_t TexMode_TA, bool MaskEval_TA>
void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32_t clut)
static INLINE void DrawTriangle(PS_GPU *gpu, tri_vertex *vertices, uint32_t clut)
{
i_deltas idl;
int32 clipy0 = ClipY0 << upscale_shift;
int32 clipy1 = ClipY1 << upscale_shift;
int32 clipy0 = gpu->ClipY0 << gpu->upscale_shift;
int32 clipy1 = gpu->ClipY1 << gpu->upscale_shift;
//
// Sort vertices by y.
@ -296,18 +294,17 @@ void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32_t clut)
ig.u = COORD_MF_INT(vertices[iggvi].u) + (1 << (COORD_FBS - 1));
ig.v = COORD_MF_INT(vertices[iggvi].v) + (1 << (COORD_FBS - 1));
if (upscale_shift > 0) {
// Bias the texture coordinates so that it rounds to the
// correct value when the game is mapping a 2D sprite using
// triangles. Otherwise this could cause a small "shift" in
// the texture coordinates when upscaling
if (gpu->upscale_shift > 0)
{
// Bias the texture coordinates so that it rounds to the
// correct value when the game is mapping a 2D sprite using
// triangles. Otherwise this could cause a small "shift" in
// the texture coordinates when upscaling
if (idl.du_dy == 0 && (int32_t)idl.du_dx > 0) {
ig.u -= (1 << (COORD_FBS - 1 - upscale_shift));
}
if (idl.dv_dx == 0 && (int32_t)idl.dv_dy > 0) {
ig.v -= (1 << (COORD_FBS - 1 - upscale_shift));
}
if (idl.du_dy == 0 && (int32_t)idl.du_dx > 0)
ig.u -= (1 << (COORD_FBS - 1 - gpu->upscale_shift));
if (idl.dv_dx == 0 && (int32_t)idl.dv_dy > 0)
ig.v -= (1 << (COORD_FBS - 1 - gpu->upscale_shift));
}
ig.r = COORD_MF_INT(vertices[iggvi].r);
@ -374,14 +371,14 @@ void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32_t clut)
{
for(int32_t y = y_start; y < y_middle; y++)
{
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ul), ig, idl);
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(gpu, y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ul), ig, idl);
base_coord += base_step;
bound_coord_ul += bound_coord_us;
}
for(int32_t y = y_middle; y < y_bound; y++)
{
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ll), ig, idl);
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(gpu, y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ll), ig, idl);
base_coord += base_step;
bound_coord_ll += bound_coord_ls;
}
@ -390,14 +387,14 @@ void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32_t clut)
{
for(int32_t y = y_start; y < y_middle; y++)
{
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(y, clut, GetPolyXFP_Int(bound_coord_ul), GetPolyXFP_Int(base_coord), ig, idl);
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(gpu, y, clut, GetPolyXFP_Int(bound_coord_ul), GetPolyXFP_Int(base_coord), ig, idl);
base_coord += base_step;
bound_coord_ul += bound_coord_us;
}
for(int32_t y = y_middle; y < y_bound; y++)
{
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(y, clut, GetPolyXFP_Int(bound_coord_ll), GetPolyXFP_Int(base_coord), ig, idl);
DrawSpan<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(gpu, y, clut, GetPolyXFP_Int(bound_coord_ll), GetPolyXFP_Int(base_coord), ig, idl);
base_coord += base_step;
bound_coord_ll += bound_coord_ls;
}
@ -414,7 +411,7 @@ void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32_t clut)
}
template<int numvertices, bool goraud, bool textured, int BlendMode, bool TexMult, uint32_t TexMode_TA, bool MaskEval_TA, bool pgxp>
INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
static void Command_DrawPolygon(PS_GPU *gpu, const uint32_t *cb)
{
tri_vertex vertices[3];
const uint32_t* baseCB = cb;
@ -458,25 +455,25 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
vertices[2].precise[2] = 0.0f;
// Base timing is approximate, and could be improved.
if(numvertices == 4 && InCmd == INCMD_QUAD)
DrawTimeAvail -= (28 + 18);
if(numvertices == 4 && gpu->InCmd == INCMD_QUAD)
gpu->DrawTimeAvail -= (28 + 18);
else
DrawTimeAvail -= (64 + 18);
gpu->DrawTimeAvail -= (64 + 18);
if(goraud && textured)
DrawTimeAvail -= 150 * 3;
gpu->DrawTimeAvail -= 150 * 3;
else if(goraud)
DrawTimeAvail -= 96 * 3;
gpu->DrawTimeAvail -= 96 * 3;
else if(textured)
DrawTimeAvail -= 60 * 3;
gpu->DrawTimeAvail -= 60 * 3;
if(numvertices == 4)
{
if(InCmd == INCMD_QUAD)
if(gpu->InCmd == INCMD_QUAD)
{
memcpy(&vertices[0], &InQuad_F3Vertices[1], 2 * sizeof(tri_vertex));
clut = InQuad_clut;
invalidW = InQuad_invalidW;
memcpy(&vertices[0], &gpu->InQuad_F3Vertices[1], 2 * sizeof(tri_vertex));
clut = gpu->InQuad_clut;
invalidW = gpu->InQuad_invalidW;
sv = 2;
}
}
@ -505,23 +502,23 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
int32 x = sign_x_to_s32(11, ((int16_t)(*cb & 0xFFFF)));
int32 y = sign_x_to_s32(11, ((int16_t)(*cb >> 16)));
vertices[v].x = (x + OffsX) << upscale_shift;
vertices[v].y = (y + OffsY) << upscale_shift;
vertices[v].x = (x + gpu->OffsX) << gpu->upscale_shift;
vertices[v].y = (y + gpu->OffsY) << gpu->upscale_shift;
if (pgxp) {
OGLVertex vert;
PGXP_GetVertex(cb - baseCB, cb, &vert, 0, 0);
vertices[v].precise[0] = ((vert.x + (float)OffsX) * upscale());
vertices[v].precise[1] = ((vert.y + (float)OffsY) * upscale());
vertices[v].precise[0] = ((vert.x + (float)gpu->OffsX) * gpu->upscale());
vertices[v].precise[1] = ((vert.y + (float)gpu->OffsY) * gpu->upscale());
vertices[v].precise[2] = vert.w;
if (!vert.valid_w)
invalidW = true;
} else {
vertices[v].precise[0] = (float)x + OffsX;
vertices[v].precise[1] = (float)y + OffsY;
vertices[v].precise[0] = (float)x + gpu->OffsX;
vertices[v].precise[1] = (float)y + gpu->OffsY;
invalidW = true;
}
@ -550,35 +547,35 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
if(numvertices == 4)
{
if(InCmd == INCMD_QUAD)
if(gpu->InCmd == INCMD_QUAD)
{
InCmd = INCMD_NONE;
gpu->InCmd = INCMD_NONE;
// default first vertex of quad to 1 if any of the vertices are 1 (even if the first triangle was okay)
if (invalidW)
InQuad_F3Vertices[0].precise[2] = 1.f;
// default first vertex of quad to 1 if any of the vertices are 1 (even if the first triangle was okay)
if (invalidW)
gpu->InQuad_F3Vertices[0].precise[2] = 1.f;
}
else
{
InCmd = INCMD_QUAD;
InCmd_CC = cb0 >> 24;
memcpy(&InQuad_F3Vertices[0], &vertices[0], sizeof(tri_vertex) * 3);
InQuad_clut = clut;
InQuad_invalidW = invalidW;
gpu->InCmd = INCMD_QUAD;
gpu->InCmd_CC = cb0 >> 24;
memcpy(&gpu->InQuad_F3Vertices[0], &vertices[0], sizeof(tri_vertex) * 3);
gpu->InQuad_clut = clut;
gpu->InQuad_invalidW = invalidW;
}
}
if(abs(vertices[2].y - vertices[0].y) >= (512 << upscale_shift) ||
abs(vertices[2].y - vertices[1].y) >= (512 << upscale_shift) ||
abs(vertices[1].y - vertices[0].y) >= (512 << upscale_shift))
if(abs(vertices[2].y - vertices[0].y) >= (512 << gpu->upscale_shift) ||
abs(vertices[2].y - vertices[1].y) >= (512 << gpu->upscale_shift) ||
abs(vertices[1].y - vertices[0].y) >= (512 << gpu->upscale_shift))
{
//PSX_WARNING("[GPU] Triangle height too large: %d", (vertices[2].y - vertices[0].y));
return;
}
if(abs(vertices[2].x - vertices[0].x) >= (1024 << upscale_shift) ||
abs(vertices[2].x - vertices[1].x) >= (1024 << upscale_shift) ||
abs(vertices[1].x - vertices[0].x) >= (1024 << upscale_shift))
if(abs(vertices[2].x - vertices[0].x) >= (1024 << gpu->upscale_shift) ||
abs(vertices[2].x - vertices[1].x) >= (1024 << gpu->upscale_shift) ||
abs(vertices[1].x - vertices[0].x) >= (1024 << gpu->upscale_shift))
{
//PSX_WARNING("[GPU] Triangle width too large: %d %d %d", abs(vertices[2].x - vertices[0].x), abs(vertices[2].x - vertices[1].x), abs(vertices[1].x - vertices[0].x));
return;
@ -597,49 +594,51 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
blend_mode = BLEND_MODE_ADD;
}
if (numvertices == 4) {
if (InCmd == INCMD_NONE) {
// We have 4 quad vertices, we can push that at once
tri_vertex *first = &InQuad_F3Vertices[0];
if (numvertices == 4)
{
if (gpu->InCmd == INCMD_NONE)
{
// We have 4 quad vertices, we can push that at once
tri_vertex *first = &gpu->InQuad_F3Vertices[0];
rsx_intf_push_quad(
first->precise[0],
first->precise[1],
first->precise[2],
vertices[0].precise[0],
vertices[0].precise[1],
vertices[0].precise[2],
vertices[1].precise[0],
vertices[1].precise[1],
vertices[1].precise[2],
vertices[2].precise[0],
vertices[2].precise[1],
vertices[2].precise[2],
((uint32_t)first->r) |
((uint32_t)first->g << 8) |
((uint32_t)first->b << 16),
((uint32_t)vertices[0].r) |
((uint32_t)vertices[0].g << 8) |
((uint32_t)vertices[0].b << 16),
((uint32_t)vertices[1].r) |
((uint32_t)vertices[1].g << 8) |
((uint32_t)vertices[1].b << 16),
((uint32_t)vertices[2].r) |
((uint32_t)vertices[2].g << 8) |
((uint32_t)vertices[2].b << 16),
first->u, first->v,
vertices[0].u, vertices[0].v,
vertices[1].u, vertices[1].v,
vertices[2].u, vertices[2].v,
this->TexPageX, this->TexPageY,
clut_x, clut_y,
blend_mode,
2 - TexMode_TA,
DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR != 0);
}
rsx_intf_push_quad(
first->precise[0],
first->precise[1],
first->precise[2],
vertices[0].precise[0],
vertices[0].precise[1],
vertices[0].precise[2],
vertices[1].precise[0],
vertices[1].precise[1],
vertices[1].precise[2],
vertices[2].precise[0],
vertices[2].precise[1],
vertices[2].precise[2],
((uint32_t)first->r) |
((uint32_t)first->g << 8) |
((uint32_t)first->b << 16),
((uint32_t)vertices[0].r) |
((uint32_t)vertices[0].g << 8) |
((uint32_t)vertices[0].b << 16),
((uint32_t)vertices[1].r) |
((uint32_t)vertices[1].g << 8) |
((uint32_t)vertices[1].b << 16),
((uint32_t)vertices[2].r) |
((uint32_t)vertices[2].g << 8) |
((uint32_t)vertices[2].b << 16),
first->u, first->v,
vertices[0].u, vertices[0].v,
vertices[1].u, vertices[1].v,
vertices[2].u, vertices[2].v,
gpu->TexPageX, gpu->TexPageY,
clut_x, clut_y,
blend_mode,
2 - TexMode_TA,
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
gpu->MaskSetOR != 0);
}
} else {
// Push a single triangle
rsx_intf_push_triangle(
@ -664,18 +663,18 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32_t *cb)
vertices[0].u, vertices[0].v,
vertices[1].u, vertices[1].v,
vertices[2].u, vertices[2].v,
this->TexPageX, this->TexPageY,
gpu->TexPageX, gpu->TexPageY,
clut_x, clut_y,
blend_mode,
2 - TexMode_TA,
DitherEnabled(),
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR != 0);
gpu->MaskSetOR != 0);
}
if (rsx_intf_has_software_renderer())
DrawTriangle<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(vertices, clut);
DrawTriangle<goraud, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(gpu, vertices, clut);
}
#undef COORD_POST_PADDING

View File

@ -1,7 +1,7 @@
template<bool textured, int BlendMode, bool TexMult, uint32_t TexMode_TA,
bool MaskEval_TA, bool FlipX, bool FlipY>
void PS_GPU::DrawSprite(int32_t x_arg, int32_t y_arg, int32_t w, int32_t h,
static void DrawSprite(PS_GPU *gpu, int32_t x_arg, int32_t y_arg, int32_t w, int32_t h,
uint8_t u_arg, uint8_t v_arg, uint32_t color, uint32_t clut_offset)
{
uint8_t u, v;
@ -40,27 +40,27 @@ void PS_GPU::DrawSprite(int32_t x_arg, int32_t y_arg, int32_t w, int32_t h,
v_inc = -1;
}
if(x_start < ClipX0)
if(x_start < gpu->ClipX0)
{
if(textured)
u += (ClipX0 - x_start) * u_inc;
u += (gpu->ClipX0 - x_start) * u_inc;
x_start = ClipX0;
x_start = gpu->ClipX0;
}
if(y_start < ClipY0)
if(y_start < gpu->ClipY0)
{
if(textured)
v += (ClipY0 - y_start) * v_inc;
v += (gpu->ClipY0 - y_start) * v_inc;
y_start = ClipY0;
y_start = gpu->ClipY0;
}
if(x_bound > (ClipX1 + 1))
x_bound = ClipX1 + 1;
if(x_bound > (gpu->ClipX1 + 1))
x_bound = gpu->ClipX1 + 1;
if(y_bound > (ClipY1 + 1))
y_bound = ClipY1 + 1;
if(y_bound > (gpu->ClipY1 + 1))
y_bound = gpu->ClipY1 + 1;
//HeightMode && !dfe && ((y & 1) == ((DisplayFB_YStart + !field_atvs) & 1)) && !DisplayOff
//printf("%d:%d, %d, %d ---- heightmode=%d displayfb_ystart=%d field_atvs=%d displayoff=%d\n", w, h, scanline, dfe, HeightMode, DisplayFB_YStart, field_atvs, DisplayOff);
@ -72,7 +72,7 @@ void PS_GPU::DrawSprite(int32_t x_arg, int32_t y_arg, int32_t w, int32_t h,
if(textured)
u_r = u;
if(!LineSkipTest(this, y))
if(!LineSkipTest(gpu, y))
{
if(y_bound > y_start && x_bound > x_start)
{
@ -84,24 +84,24 @@ void PS_GPU::DrawSprite(int32_t x_arg, int32_t y_arg, int32_t w, int32_t h,
if((BlendMode >= 0) || MaskEval_TA)
suck_time += (((x_bound + 1) & ~1) - (x_start & ~1)) >> 1;
DrawTimeAvail -= suck_time;
gpu->DrawTimeAvail -= suck_time;
}
for(int32_t x = x_start; MDFN_LIKELY(x < x_bound); x++)
{
if(textured)
{
uint16_t fbw = GetTexel<TexMode_TA>(clut_offset, u_r, v);
uint16_t fbw = gpu->GetTexel<TexMode_TA>(clut_offset, u_r, v);
if(fbw)
{
if(TexMult)
fbw = ModTexel(fbw, r, g, b, 3, 2);
PlotNativePixel<BlendMode, MaskEval_TA, true>(x, y, fbw);
fbw = gpu->ModTexel(fbw, r, g, b, 3, 2);
gpu->PlotNativePixel<BlendMode, MaskEval_TA, true>(x, y, fbw);
}
}
else
PlotNativePixel<BlendMode, MaskEval_TA, false>(x, y, fill_color);
gpu->PlotNativePixel<BlendMode, MaskEval_TA, false>(x, y, fill_color);
if(textured)
u_r += u_inc;
@ -146,7 +146,7 @@ void rsx_gl_push_sprite(
template<uint8_t raw_size, bool textured, int BlendMode,
bool TexMult, uint32_t TexMode_TA, bool MaskEval_TA>
INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
static void Command_DrawSprite(PS_GPU *gpu, const uint32_t *cb)
{
int32_t x, y;
int32_t w, h;
@ -155,7 +155,7 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
uint32_t color = 0;
uint32_t clut = 0;
DrawTimeAvail -= 16; // FIXME, correct time.
gpu->DrawTimeAvail -= 16; // FIXME, correct time.
color = *cb & 0x00FFFFFF;
cb++;
@ -169,7 +169,7 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
u = *cb & 0xFF;
v = (*cb >> 8) & 0xFF;
clut = ((*cb >> 16) & 0xFFFF) << 4;
Update_CLUT_Cache<TexMode_TA>((*cb >> 16) & 0xFFFF);
gpu->Update_CLUT_Cache<TexMode_TA>((*cb >> 16) & 0xFFFF);
cb++;
}
@ -198,8 +198,8 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
break;
}
x = sign_x_to_s32(11, x + OffsX);
y = sign_x_to_s32(11, y + OffsY);
x = sign_x_to_s32(11, x + gpu->OffsX);
y = sign_x_to_s32(11, y + gpu->OffsY);
uint16_t clut_x = (clut & (0x3f << 4));
uint16_t clut_y = (clut >> 10) & 0x1ff;
@ -242,16 +242,16 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
v + h, /* t2y */
u + w, /* t5x */
v + h, /* t5y */
this->TexPageX,
this->TexPageY,
gpu->TexPageX,
gpu->TexPageY,
clut_x,
clut_y,
blend_mode,
2 - TexMode_TA,
DitherEnabled(),
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR != 0);
gpu->MaskSetOR != 0);
}
else
#endif
@ -265,14 +265,15 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
u, v,
u + w, v,
u, v + h,
this->TexPageX, this->TexPageY,
gpu->TexPageX,
gpu->TexPageY,
clut_x, clut_y,
blend_mode,
2 - TexMode_TA,
DitherEnabled(),
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR != 0);
gpu->MaskSetOR != 0);
rsx_intf_push_triangle(x + w, y, 1,
x, y + h, 1,
@ -283,14 +284,15 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
u + w, v,
u, v + h,
u + w, v + h,
this->TexPageX, this->TexPageY,
gpu->TexPageX,
gpu->TexPageY,
clut_x, clut_y,
blend_mode,
2 - TexMode_TA,
DitherEnabled(),
gpu->DitherEnabled(),
BlendMode,
MaskEval_TA,
MaskSetOR != 0);
gpu->MaskSetOR != 0);
}
#if 0
@ -300,34 +302,34 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32_t *cb)
if (!rsx_intf_has_software_renderer())
return;
switch(SpriteFlip & 0x3000)
switch(gpu->SpriteFlip & 0x3000)
{
case 0x0000:
if(!TexMult || color == 0x808080)
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, false, false>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, false, false>(gpu, x, y, w, h, u, v, color, clut);
else
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, false, false>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, false, false>(gpu, x, y, w, h, u, v, color, clut);
break;
case 0x1000:
if(!TexMult || color == 0x808080)
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, true, false>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, true, false>(gpu, x, y, w, h, u, v, color, clut);
else
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, true, false>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, true, false>(gpu, x, y, w, h, u, v, color, clut);
break;
case 0x2000:
if(!TexMult || color == 0x808080)
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, false, true>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, false, true>(gpu, x, y, w, h, u, v, color, clut);
else
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, false, true>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, false, true>(gpu, x, y, w, h, u, v, color, clut);
break;
case 0x3000:
if(!TexMult || color == 0x808080)
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, true, true>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, false, TexMode_TA, MaskEval_TA, true, true>(gpu, x, y, w, h, u, v, color, clut);
else
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, true, true>(x, y, w, h, u, v, color, clut);
DrawSprite<textured, BlendMode, true, TexMode_TA, MaskEval_TA, true, true>(gpu, x, y, w, h, u, v, color, clut);
break;
}
}