WIP 0.9.44.1
This commit is contained in:
parent
ff835a4185
commit
165f3db2d8
|
@ -158,3 +158,5 @@
|
|||
[OK] psx/dis : add const
|
||||
[OK] psx/dma : update GPU api. NOTE: found biz bug here.
|
||||
[OK] psx/frontio : add cold
|
||||
[OK] psx/gpu : (big change to make GPU static)
|
||||
[OK] psx/psx : associated with GPU, add cold; ignored PSF loader cold. NOTE: at smoe point we got RMD_Drive, which I'm not using
|
|
@ -76,6 +76,8 @@ typedef __uint8_t uint8;
|
|||
//#define MDFN_NOWARN_UNUSED __attribute__((unused))
|
||||
#define MDFN_NOWARN_UNUSED
|
||||
|
||||
#define MDFN_FASTCALL
|
||||
|
||||
//#define MDFN_FORMATSTR(a,b,c) __attribute__ ((format (a, b, c)))
|
||||
#define MDFN_FORMATSTR(a,b,c)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu.cpp:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -69,60 +69,29 @@
|
|||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
|
||||
//static data
|
||||
uint8 PS_GPU::DitherLUT[4][4][512]; // Y, X, 8-bit source value(256 extra for saturation)
|
||||
PS_GPU GPU;
|
||||
|
||||
static const int8 dither_table[4][4] =
|
||||
{
|
||||
namespace PS_GPU_INTERNAL
|
||||
{
|
||||
#include "gpu_common.inc"
|
||||
}
|
||||
using namespace PS_GPU_INTERNAL;
|
||||
|
||||
void GPU_Init(bool pal_clock_and_tv)
|
||||
{
|
||||
static const int8 dither_table[4][4] =
|
||||
{
|
||||
{ -4, 0, -3, 1 },
|
||||
{ 2, -2, 3, -1 },
|
||||
{ -3, 1, -4, 0 },
|
||||
{ 3, -1, 2, -2 },
|
||||
};
|
||||
};
|
||||
|
||||
HardwarePALType = pal_clock_and_tv;
|
||||
|
||||
void PS_GPU::StaticInitialize()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if(initialized) return;
|
||||
|
||||
initialized = true;
|
||||
for(int y = 0; y < 4; y++)
|
||||
{
|
||||
for(int x = 0; x < 4; x++)
|
||||
{
|
||||
for(int v = 0; v < 512; v++)
|
||||
{
|
||||
int value = v + dither_table[y][x];
|
||||
|
||||
value >>= 3;
|
||||
|
||||
if(value < 0)
|
||||
value = 0;
|
||||
|
||||
if(value > 0x1F)
|
||||
value = 0x1F;
|
||||
|
||||
DitherLUT[y][x][v] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&Commands[0x00], Commands_00_1F, sizeof(Commands_00_1F));
|
||||
memcpy(&Commands[0x20], Commands_20_3F, sizeof(Commands_20_3F));
|
||||
memcpy(&Commands[0x40], Commands_40_5F, sizeof(Commands_40_5F));
|
||||
memcpy(&Commands[0x60], Commands_60_7F, sizeof(Commands_60_7F));
|
||||
memcpy(&Commands[0x80], Commands_80_FF, sizeof(Commands_80_FF));
|
||||
}
|
||||
|
||||
PS_GPU::PS_GPU(bool pal_clock_and_tv) : HardwarePALType(pal_clock_and_tv)
|
||||
{
|
||||
//printf("%zu\n", (size_t)((uintptr_t)DitherLUT - (uintptr_t)this));
|
||||
//printf("%zu\n", (size_t)((uintptr_t)GPURAM - (uintptr_t)this));
|
||||
//
|
||||
//todo - not thread safe
|
||||
StaticInitialize();
|
||||
|
||||
if(HardwarePALType == false) // NTSC clock
|
||||
{
|
||||
GPUClockRatio = 103896; // 65536 * 53693181.818 / (44100 * 768)
|
||||
|
@ -136,12 +105,12 @@ PS_GPU::PS_GPU(bool pal_clock_and_tv) : HardwarePALType(pal_clock_and_tv)
|
|||
|
||||
}
|
||||
|
||||
PS_GPU::~PS_GPU()
|
||||
void GPU_Kill(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PS_GPU::FillVideoParams(MDFNGI* gi)
|
||||
void PS_GPU_FillVideoParams(MDFNGI* gi)
|
||||
{
|
||||
if(HardwarePALType)
|
||||
{
|
||||
|
@ -185,7 +154,20 @@ void PS_GPU::FillVideoParams(MDFNGI* gi)
|
|||
gi->mouse_offs_y = LineVisFirst;
|
||||
}
|
||||
|
||||
void PS_GPU::SoftReset(void) // Control command 0x00
|
||||
static INLINE void InvalidateTexCache(void)
|
||||
{
|
||||
for(auto& c : TexCache)
|
||||
c.Tag = ~0U;
|
||||
}
|
||||
|
||||
static void InvalidateCache(void)
|
||||
{
|
||||
CLUT_Cache_VB = ~0U;
|
||||
|
||||
InvalidateTexCache();
|
||||
}
|
||||
|
||||
static void SoftReset(void) // Control command 0x00
|
||||
{
|
||||
IRQPending = false;
|
||||
IRQ_Assert(IRQ_GPU, IRQPending);
|
||||
|
@ -199,7 +181,7 @@ void PS_GPU::SoftReset(void) // Control command 0x00
|
|||
|
||||
BlitterFIFO.Flush();
|
||||
DataReadBufferEx = 0;
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
|
||||
DisplayOff = 1;
|
||||
DisplayFB_XStart = 0;
|
||||
|
@ -253,7 +235,7 @@ void PS_GPU::SoftReset(void) // Control command 0x00
|
|||
TexDisableAllowChange = false;
|
||||
}
|
||||
|
||||
void PS_GPU::Power(void)
|
||||
void GPU_Power(void)
|
||||
{
|
||||
memset(GPURAM, 0, sizeof(GPURAM));
|
||||
|
||||
|
@ -298,7 +280,7 @@ void PS_GPU::Power(void)
|
|||
BlitterFIFO.Flush();
|
||||
DataReadBuffer = 0; // Don't reset in SoftReset()
|
||||
DataReadBufferEx = 0;
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
FBRW_X = 0;
|
||||
FBRW_Y = 0;
|
||||
FBRW_W = 0;
|
||||
|
@ -353,15 +335,13 @@ void PS_GPU::Power(void)
|
|||
TIMER_SetVBlank(InVBlank);
|
||||
}
|
||||
|
||||
void PS_GPU::ResetTS(void)
|
||||
void GPU_ResetTS(void)
|
||||
{
|
||||
lastts = 0;
|
||||
}
|
||||
|
||||
#include "gpu_common.inc"
|
||||
|
||||
// Special RAM write mode(16 pixels at a time), does *not* appear to use mask drawing environment settings.
|
||||
INLINE void PS_GPU::Command_FBFill(const uint32 *cb)
|
||||
static void Command_FBFill(const uint32 *cb)
|
||||
{
|
||||
int32 r = cb[0] & 0xFF;
|
||||
int32 g = (cb[0] >> 8) & 0xFF;
|
||||
|
@ -395,7 +375,7 @@ INLINE void PS_GPU::Command_FBFill(const uint32 *cb)
|
|||
}
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_FBCopy(const uint32 *cb)
|
||||
static void Command_FBCopy(const uint32 *cb)
|
||||
{
|
||||
int32 sourceX = (cb[1] >> 0) & 0x3FF;
|
||||
int32 sourceY = (cb[1] >> 16) & 0x3FF;
|
||||
|
@ -445,9 +425,9 @@ INLINE void PS_GPU::Command_FBCopy(const uint32 *cb)
|
|||
}
|
||||
|
||||
|
||||
INLINE void PS_GPU::Command_FBWrite(const uint32 *cb)
|
||||
static void Command_FBWrite(const uint32 *cb)
|
||||
{
|
||||
assert(InCmd == INCMD_NONE);
|
||||
assert(InCmd == PS_GPU::INCMD_NONE);
|
||||
|
||||
FBRW_X = (cb[1] >> 0) & 0x3FF;
|
||||
FBRW_Y = (cb[1] >> 16) & 0x3FF;
|
||||
|
@ -467,16 +447,16 @@ INLINE void PS_GPU::Command_FBWrite(const uint32 *cb)
|
|||
InvalidateTexCache();
|
||||
|
||||
if(FBRW_W != 0 && FBRW_H != 0)
|
||||
InCmd = INCMD_FBWRITE;
|
||||
InCmd = PS_GPU::INCMD_FBWRITE;
|
||||
}
|
||||
|
||||
//
|
||||
// FBRead: PS1 GPU in SCPH-5501 gives odd, inconsistent results when raw_height == 0, or
|
||||
// raw_height != 0x200 && (raw_height & 0x1FF) == 0
|
||||
//
|
||||
INLINE void PS_GPU::Command_FBRead(const uint32 *cb)
|
||||
static void Command_FBRead(const uint32 *cb)
|
||||
{
|
||||
assert(InCmd == INCMD_NONE);
|
||||
assert(InCmd == PS_GPU::INCMD_NONE);
|
||||
|
||||
FBRW_X = (cb[1] >> 0) & 0x3FF;
|
||||
FBRW_Y = (cb[1] >> 16) & 0x3FF;
|
||||
|
@ -494,7 +474,7 @@ INLINE void PS_GPU::Command_FBRead(const uint32 *cb)
|
|||
FBRW_CurY = FBRW_Y;
|
||||
|
||||
if(FBRW_W != 0 && FBRW_H != 0)
|
||||
InCmd = INCMD_FBREAD;
|
||||
InCmd = PS_GPU::INCMD_FBREAD;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -505,7 +485,7 @@ INLINE void PS_GPU::RecalcTexPageStuff(uint32 tpage)
|
|||
}
|
||||
*/
|
||||
|
||||
INLINE void PS_GPU::SetTPage(const uint32 cmdw)
|
||||
static void SetTPage(const uint32 cmdw)
|
||||
{
|
||||
const unsigned NewTexPageX = (cmdw & 0xF) * 64;
|
||||
const unsigned NewTexPageY = (cmdw & 0x10) * 16;
|
||||
|
@ -538,7 +518,7 @@ INLINE void PS_GPU::SetTPage(const uint32 cmdw)
|
|||
RecalcTexWindowStuff();
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_DrawMode(const uint32 *cb)
|
||||
static void Command_DrawMode(const uint32 *cb)
|
||||
{
|
||||
const uint32 cmdw = *cb;
|
||||
|
||||
|
@ -551,7 +531,7 @@ INLINE void PS_GPU::Command_DrawMode(const uint32 *cb)
|
|||
//printf("*******************DFE: %d -- scanline=%d\n", dfe, scanline);
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_TexWindow(const uint32 *cb)
|
||||
static void Command_TexWindow(const uint32 *cb)
|
||||
{
|
||||
tww = (*cb & 0x1F);
|
||||
twh = ((*cb >> 5) & 0x1F);
|
||||
|
@ -561,7 +541,7 @@ INLINE void PS_GPU::Command_TexWindow(const uint32 *cb)
|
|||
RecalcTexWindowStuff();
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_Clip0(const uint32 *cb)
|
||||
static void Command_Clip0(const uint32 *cb)
|
||||
{
|
||||
ClipX0 = *cb & 1023;
|
||||
ClipY0 = (*cb >> 10) & 1023;
|
||||
|
@ -569,7 +549,7 @@ INLINE void PS_GPU::Command_Clip0(const uint32 *cb)
|
|||
//fprintf(stderr, "[GPU] Clip0: x=%d y=%d, raw=0x%08x --- %d\n", ClipX0, ClipY0, *cb, scanline);
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_Clip1(const uint32 *cb)
|
||||
static void Command_Clip1(const uint32 *cb)
|
||||
{
|
||||
ClipX1 = *cb & 1023;
|
||||
ClipY1 = (*cb >> 10) & 1023;
|
||||
|
@ -577,7 +557,7 @@ INLINE void PS_GPU::Command_Clip1(const uint32 *cb)
|
|||
//fprintf(stderr, "[GPU] Clip1: x=%d y=%d, raw=0x%08x --- %d\n", ClipX1, ClipY1, *cb, scanline);
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_DrawingOffset(const uint32 *cb)
|
||||
static void Command_DrawingOffset(const uint32 *cb)
|
||||
{
|
||||
OffsX = sign_x_to_s32(11, (*cb & 2047));
|
||||
OffsY = sign_x_to_s32(11, ((*cb >> 11) & 2047));
|
||||
|
@ -585,109 +565,32 @@ INLINE void PS_GPU::Command_DrawingOffset(const uint32 *cb)
|
|||
//fprintf(stderr, "[GPU] Drawing offset: x=%d y=%d, raw=0x%08x --- %d\n", OffsX, OffsY, *cb, scanline);
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_MaskSetting(const uint32 *cb)
|
||||
static void Command_MaskSetting(const uint32 *cb)
|
||||
{
|
||||
//printf("Mask setting: %08x\n", *cb);
|
||||
MaskSetOR = (*cb & 1) ? 0x8000 : 0x0000;
|
||||
MaskEvalAND = (*cb & 2) ? 0x8000 : 0x0000;
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::InvalidateTexCache(void)
|
||||
{
|
||||
for(int i=0;i<ARRAY_SIZE(TexCache);i++)
|
||||
TexCache[i].Tag = ~0U;
|
||||
}
|
||||
|
||||
|
||||
void PS_GPU::InvalidateCache(void)
|
||||
{
|
||||
CLUT_Cache_VB = ~0U;
|
||||
|
||||
InvalidateTexCache();
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_ClearCache(const uint32 *cb)
|
||||
static void Command_ClearCache(const uint32 *cb)
|
||||
{
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::Command_IRQ(const uint32 *cb)
|
||||
static void Command_IRQ(const uint32 *cb)
|
||||
{
|
||||
IRQPending = true;
|
||||
IRQ_Assert(IRQ_GPU, IRQPending);
|
||||
}
|
||||
|
||||
//
|
||||
// C-style function wrappers so our command table isn't so ginormous(in memory usage).
|
||||
//
|
||||
static void G_Command_ClearCache(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_ClearCache(cb);
|
||||
}
|
||||
|
||||
static void G_Command_IRQ(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_IRQ(cb);
|
||||
}
|
||||
|
||||
static void G_Command_FBFill(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_FBFill(cb);
|
||||
}
|
||||
|
||||
static void G_Command_FBCopy(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_FBCopy(cb);
|
||||
}
|
||||
|
||||
static void G_Command_FBWrite(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_FBWrite(cb);
|
||||
}
|
||||
|
||||
static void G_Command_FBRead(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_FBRead(cb);
|
||||
}
|
||||
|
||||
static void G_Command_DrawMode(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_DrawMode(cb);
|
||||
}
|
||||
|
||||
static void G_Command_TexWindow(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_TexWindow(cb);
|
||||
}
|
||||
|
||||
static void G_Command_Clip0(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_Clip0(cb);
|
||||
}
|
||||
|
||||
static void G_Command_Clip1(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_Clip1(cb);
|
||||
}
|
||||
|
||||
static void G_Command_DrawingOffset(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_DrawingOffset(cb);
|
||||
}
|
||||
|
||||
static void G_Command_MaskSetting(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_MaskSetting(cb);
|
||||
}
|
||||
|
||||
CTEntry PS_GPU::Commands[0x100];
|
||||
|
||||
const CTEntry PS_GPU::Commands_00_1F[0x20] =
|
||||
namespace PS_GPU_INTERNAL
|
||||
{
|
||||
extern const CTEntry Commands_00_1F[0x20] =
|
||||
{
|
||||
/* 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(),
|
||||
|
@ -697,29 +600,29 @@ const CTEntry PS_GPU::Commands_00_1F[0x20] =
|
|||
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
|
||||
|
||||
/* 0x1F */
|
||||
OTHER_HELPER(1, 1, false, G_Command_IRQ)
|
||||
};
|
||||
OTHER_HELPER(1, 1, false, Command_IRQ)
|
||||
};
|
||||
|
||||
const CTEntry PS_GPU::Commands_80_FF[0x80] =
|
||||
{
|
||||
extern const CTEntry Commands_80_FF[0x80] =
|
||||
{
|
||||
/* 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(),
|
||||
|
@ -727,9 +630,10 @@ const CTEntry PS_GPU::Commands_80_FF[0x80] =
|
|||
/* 0xF0 */
|
||||
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(),
|
||||
NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD()
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void PS_GPU::ProcessFIFO(void)
|
||||
static void ProcessFIFO(void)
|
||||
{
|
||||
if(!BlitterFIFO.CanRead())
|
||||
return;
|
||||
|
@ -740,14 +644,14 @@ void PS_GPU::ProcessFIFO(void)
|
|||
abort();
|
||||
break;
|
||||
|
||||
case INCMD_NONE:
|
||||
case PS_GPU::INCMD_NONE:
|
||||
break;
|
||||
|
||||
case INCMD_FBREAD:
|
||||
case PS_GPU::INCMD_FBREAD:
|
||||
PSX_WARNING("[GPU] Command FIFO not empty while in FB Read?!");
|
||||
return;
|
||||
|
||||
case INCMD_FBWRITE:
|
||||
case PS_GPU::INCMD_FBWRITE:
|
||||
{
|
||||
uint32 InData = BlitterFIFO.Read();
|
||||
|
||||
|
@ -763,7 +667,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
FBRW_CurY++;
|
||||
if(FBRW_CurY == (FBRW_Y + FBRW_H))
|
||||
{
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
break; // Break out of the for() loop.
|
||||
}
|
||||
}
|
||||
|
@ -773,7 +677,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
}
|
||||
break;
|
||||
|
||||
case INCMD_QUAD:
|
||||
case PS_GPU::INCMD_QUAD:
|
||||
{
|
||||
if(DrawTimeAvail < 0)
|
||||
return;
|
||||
|
@ -790,13 +694,13 @@ void PS_GPU::ProcessFIFO(void)
|
|||
CB[i] = BlitterFIFO.Read();
|
||||
}
|
||||
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](this, CB);
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](CB);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case INCMD_PLINE:
|
||||
case PS_GPU::INCMD_PLINE:
|
||||
{
|
||||
if(DrawTimeAvail < 0)
|
||||
return;
|
||||
|
@ -809,7 +713,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
if((BlitterFIFO.Peek() & 0xF000F000) == 0x50005000)
|
||||
{
|
||||
BlitterFIFO.Read();
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -820,7 +724,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
CB[i] = BlitterFIFO.Read();
|
||||
}
|
||||
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](this, CB);
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](CB);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -843,7 +747,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
if(!command->ss_cmd)
|
||||
DrawTimeAvail -= 2;
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
PSX_WARNING("[GPU] Command: %08x %s %d %d %d", CB[0], command->name, command->len, scanline, DrawTimeAvail);
|
||||
if(1)
|
||||
{
|
||||
|
@ -852,7 +756,7 @@ void PS_GPU::ProcessFIFO(void)
|
|||
printf("0x%08x ", CB[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
// A very very ugly kludge to support texture mode specialization. fixme/cleanup/SOMETHING in the future.
|
||||
if(cc >= 0x20 && cc <= 0x3F && (cc & 0x4))
|
||||
{
|
||||
|
@ -869,14 +773,14 @@ void PS_GPU::ProcessFIFO(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](this, CB);
|
||||
command->func[abr][TexMode | (MaskEvalAND ? 0x4 : 0x0)](CB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void PS_GPU::WriteCB(uint32 InData)
|
||||
static void WriteCB(uint32 InData)
|
||||
{
|
||||
if(BlitterFIFO.CanRead() >= 0x10 && (InCmd != INCMD_NONE || (BlitterFIFO.CanRead() - 0x10) >= Commands[BlitterFIFO.Peek() >> 24].fifo_fb_len))
|
||||
if(BlitterFIFO.CanRead() >= 0x10 && (InCmd != PS_GPU::INCMD_NONE || (BlitterFIFO.CanRead() - 0x10) >= Commands[BlitterFIFO.Peek() >> 24].fifo_fb_len))
|
||||
{
|
||||
PSX_DBG(PSX_DBG_WARNING, "GPU FIFO overflow!!!\n");
|
||||
return;
|
||||
|
@ -886,7 +790,7 @@ INLINE void PS_GPU::WriteCB(uint32 InData)
|
|||
ProcessFIFO();
|
||||
}
|
||||
|
||||
void PS_GPU::Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V)
|
||||
MDFN_FASTCALL void GPU_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V)
|
||||
{
|
||||
V <<= (A & 3) * 8;
|
||||
|
||||
|
@ -915,7 +819,7 @@ void PS_GPU::Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V)
|
|||
if(DrawTimeAvail < 0)
|
||||
DrawTimeAvail = 0;
|
||||
BlitterFIFO.Flush();
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
break;
|
||||
|
||||
case 0x02: // Acknowledge IRQ
|
||||
|
@ -1004,14 +908,14 @@ void PS_GPU::Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V)
|
|||
}
|
||||
|
||||
|
||||
void PS_GPU::WriteDMA(uint32 V)
|
||||
MDFN_FASTCALL void GPU_WriteDMA(uint32 V)
|
||||
{
|
||||
WriteCB(V);
|
||||
}
|
||||
|
||||
INLINE uint32 PS_GPU::ReadData(void)
|
||||
static INLINE uint32 ReadData(void)
|
||||
{
|
||||
if(InCmd == INCMD_FBREAD)
|
||||
if(InCmd == PS_GPU::INCMD_FBREAD)
|
||||
{
|
||||
DataReadBufferEx = 0;
|
||||
for(int i = 0; i < 2; i++)
|
||||
|
@ -1023,7 +927,7 @@ INLINE uint32 PS_GPU::ReadData(void)
|
|||
{
|
||||
if((FBRW_CurY + 1) == (FBRW_Y + FBRW_H))
|
||||
{
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1039,12 +943,12 @@ INLINE uint32 PS_GPU::ReadData(void)
|
|||
return DataReadBuffer;
|
||||
}
|
||||
|
||||
uint32 PS_GPU::ReadDMA(void)
|
||||
uint32 GPU_ReadDMA(void)
|
||||
{
|
||||
return ReadData();
|
||||
}
|
||||
|
||||
uint32 PS_GPU::Read(const pscpu_timestamp_t timestamp, uint32 A)
|
||||
MDFN_FASTCALL uint32 GPU_Read(const pscpu_timestamp_t timestamp, uint32 A)
|
||||
{
|
||||
uint32 ret = 0;
|
||||
|
||||
|
@ -1067,13 +971,13 @@ uint32 PS_GPU::Read(const pscpu_timestamp_t timestamp, uint32 A)
|
|||
|
||||
ret |= DisplayOff << 23;
|
||||
|
||||
if(InCmd == INCMD_NONE && DrawTimeAvail >= 0 && BlitterFIFO.CanRead() == 0x00) // GPU idle bit.
|
||||
if(InCmd == PS_GPU::INCMD_NONE && DrawTimeAvail >= 0 && BlitterFIFO.CanRead() == 0x00) // GPU idle bit.
|
||||
ret |= 1 << 26;
|
||||
|
||||
if(InCmd == INCMD_FBREAD) // Might want to more accurately emulate this in the future?
|
||||
if(InCmd == PS_GPU::INCMD_FBREAD) // Might want to more accurately emulate this in the future?
|
||||
ret |= (1 << 27);
|
||||
|
||||
ret |= CalcFIFOReadyBit() << 28; // FIFO has room bit? (kinda).
|
||||
ret |= GPU_CalcFIFOReadyBit() << 28; // FIFO has room bit? (kinda).
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -1116,7 +1020,7 @@ static INLINE uint32 MDFN_NOWARN_UNUSED ShiftHelper(uint32 val, int shamt, uint3
|
|||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("no-unroll-loops,no-peel-loops,no-crossjumping")
|
||||
INLINE void PS_GPU::ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x)
|
||||
static INLINE void ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x)
|
||||
{
|
||||
if(bpp24) // 24bpp
|
||||
{
|
||||
|
@ -1139,13 +1043,13 @@ INLINE void PS_GPU::ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32
|
|||
{
|
||||
uint32 srcpix = src[fb_x >> 1];
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
dest[x] = OutputLUT[(uint8)srcpix] | (OutputLUT + 256)[(srcpix >> 8) & 0x7F];
|
||||
#else
|
||||
#else
|
||||
dest[x] = ShiftHelper(srcpix, out_Rshift + 3 - 0, (0xF8 << out_Rshift)) |
|
||||
ShiftHelper(srcpix, out_Gshift + 3 - 5, (0xF8 << out_Gshift)) |
|
||||
ShiftHelper(srcpix, out_Bshift + 3 - 10, (0xF8 << out_Bshift));
|
||||
#endif
|
||||
#endif
|
||||
fb_x = (fb_x + 2) & 0x7FF;
|
||||
}
|
||||
}
|
||||
|
@ -1153,13 +1057,13 @@ INLINE void PS_GPU::ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32
|
|||
}
|
||||
|
||||
template<uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift>
|
||||
void NO_INLINE PS_GPU::ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x)
|
||||
static NO_INLINE void ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x)
|
||||
{
|
||||
ReorderRGB_Var(out_Rshift, out_Gshift, out_Bshift, bpp24, src, dest, dx_start, dx_end, fb_x);
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
||||
MDFN_FASTCALL pscpu_timestamp_t GPU_Update(const pscpu_timestamp_t sys_timestamp)
|
||||
{
|
||||
static const uint32 DotClockRatios[5] = { 10, 8, 5, 4, 7 };
|
||||
const uint32 dmc = (DisplayMode & 0x40) ? 4 : (DisplayMode & 0x3);
|
||||
|
@ -1237,9 +1141,9 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
|||
scanline = (scanline + 1) % LinesPerField;
|
||||
PhaseChange = !PhaseChange;
|
||||
|
||||
#ifdef WANT_DEBUGGER
|
||||
#ifdef WANT_DEBUGGER
|
||||
DBG_GPUScanlineHook(scanline);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -1316,9 +1220,7 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
|||
|
||||
if(!DisplayOff)
|
||||
{
|
||||
char buffer[256];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), ("VIDEO STANDARD MISMATCH"));
|
||||
printf("VIDEO STANDARD MISMATCH");
|
||||
/*DrawText(surface, 0, (DisplayRect->h / 2) - (13 / 2), buffer,
|
||||
surface->MakeColor(0x00, 0xFF, 0x00), MDFN_FONT_6x13_12x13, DisplayRect->w);*/
|
||||
}
|
||||
|
@ -1442,30 +1344,6 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
|||
|
||||
LineWidths[dest_line] = dmw - dmpa * 2;
|
||||
|
||||
//adjustments for people who really just want to see the PSX framebuffer
|
||||
//effectively fixes the xstart registers to be nominal values.
|
||||
//it's unclear what happens to games displaying a peculiar Y range
|
||||
if (dump_framebuffer)
|
||||
{
|
||||
//printf("%d %d %d\n", VertStart, VertEnd, DisplayOff);
|
||||
//special hack: if the game (or the bios...) is set to display no range here, don't modify it
|
||||
//also, as you can see just above, this condition is used to represent an 'off' display
|
||||
//unfortunately, this will usually be taking effect at dest_line==0, and so the
|
||||
//fully overscanned area will get set for LineWidths[0].
|
||||
//so later on we'll have to use LineWidths[NN], say, as a heuristic to get the framebuffer size
|
||||
if (dx_start == dx_end)
|
||||
{ }
|
||||
else
|
||||
{
|
||||
dx_start = 0;
|
||||
dx_end = 2560 / DotClockRatios[dmc];
|
||||
if(FirstLine == -99)
|
||||
FirstLine = dest_line;
|
||||
|
||||
LineWidths[dest_line] = dx_end - dx_start;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const uint16 *src = GPURAM[DisplayFB_CurLineYReadout];
|
||||
const uint32 black = surface->MakeColor(0, 0, 0);
|
||||
|
@ -1507,11 +1385,11 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
|||
PSX_SetEventNT(PSX_EVENT_TIMER, TIMER_Update(sys_timestamp)); // Mostly so the next event time gets recalculated properly in regards to our calls
|
||||
// to TIMER_SetVBlank() and TIMER_SetHRetrace().
|
||||
} // end if(!LineClockCounter)
|
||||
} // end while(gpu_clocks > 0)
|
||||
} // end while(gpu_clocks > 0)
|
||||
|
||||
//puts("GPU Update End");
|
||||
|
||||
TheEnd:
|
||||
TheEnd:
|
||||
lastts = sys_timestamp;
|
||||
|
||||
{
|
||||
|
@ -1528,7 +1406,7 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp)
|
|||
}
|
||||
}
|
||||
|
||||
void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg)
|
||||
void GPU_StartFrame(EmulateSpecStruct *espec_arg)
|
||||
{
|
||||
sl_zero_reached = false;
|
||||
|
||||
|
@ -1549,8 +1427,6 @@ void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg)
|
|||
LineWidths = espec->LineWidths;
|
||||
skip = espec->skip;
|
||||
|
||||
FirstLine = -99;
|
||||
|
||||
if(espec->VideoFormatChanged)
|
||||
{
|
||||
const auto& f = surface->format;
|
||||
|
@ -1695,7 +1571,7 @@ SYNCFUNC(PS_GPU)
|
|||
|
||||
}
|
||||
|
||||
void PS_GPU::SetRenderOptions(::ShockRenderOptions* opts)
|
||||
void GPU_SetRenderOptions(::ShockRenderOptions* opts)
|
||||
{
|
||||
hide_hoverscan = opts->renderType == eShockRenderType_ClipOverscan;
|
||||
dump_framebuffer = opts->renderType == eShockRenderType_Framebuffer;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu.h:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -22,21 +22,22 @@
|
|||
// WARNING WARNING WARNING: ONLY use CanRead() method of BlitterFIFO, and NOT CanWrite(), since the FIFO is larger than the actual PS1 GPU FIFO to accommodate
|
||||
// our lack of fancy superscalarish command sequencer.
|
||||
|
||||
#pragma once
|
||||
#ifndef __MDFN_PSX_GPU_H
|
||||
#define __MDFN_PSX_GPU_H
|
||||
|
||||
#include "FastFIFO.h"
|
||||
#include "git.h"
|
||||
#include "psx.h"
|
||||
#include "octoshock.h"
|
||||
#include "emuware/emuware.h"
|
||||
|
||||
struct ShockRenderOptions;
|
||||
|
||||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
|
||||
class PS_GPU;
|
||||
|
||||
struct CTEntry
|
||||
{
|
||||
void (*func[4][8])(PS_GPU* g, const uint32 *cb);
|
||||
void (*func[4][8])(const uint32 *cb);
|
||||
uint8 len;
|
||||
uint8 fifo_fb_len;
|
||||
bool ss_cmd;
|
||||
|
@ -49,90 +50,21 @@ struct tri_vertex
|
|||
int32 r, g, b;
|
||||
};
|
||||
|
||||
struct i_group;
|
||||
struct i_deltas;
|
||||
|
||||
struct line_point
|
||||
{
|
||||
int32 x, y;
|
||||
uint8 r, g, b;
|
||||
};
|
||||
|
||||
class PS_GPU
|
||||
struct PS_GPU
|
||||
{
|
||||
public:
|
||||
|
||||
void SetRenderOptions(ShockRenderOptions* opts);
|
||||
|
||||
PS_GPU(bool pal_clock_and_tv) MDFN_COLD;
|
||||
~PS_GPU() MDFN_COLD;
|
||||
static void StaticInitialize() MDFN_COLD;
|
||||
|
||||
template<bool isReader>void SyncState(EW::NewState *ns);
|
||||
|
||||
void FillVideoParams(MDFNGI* gi) MDFN_COLD;
|
||||
|
||||
void Power(void) MDFN_COLD;
|
||||
|
||||
void ResetTS(void);
|
||||
|
||||
void StartFrame(EmulateSpecStruct *espec);
|
||||
|
||||
pscpu_timestamp_t Update(const pscpu_timestamp_t timestamp);
|
||||
|
||||
void Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V);
|
||||
|
||||
INLINE bool CalcFIFOReadyBit(void)
|
||||
{
|
||||
if(InCmd & (INCMD_PLINE | INCMD_QUAD))
|
||||
return(false);
|
||||
|
||||
if(BlitterFIFO.CanRead() == 0)
|
||||
return(true);
|
||||
|
||||
if(InCmd & (INCMD_FBREAD | INCMD_FBWRITE))
|
||||
return(false);
|
||||
|
||||
if(BlitterFIFO.CanRead() >= Commands[BlitterFIFO.Peek() >> 24].fifo_fb_len)
|
||||
return(false);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
INLINE bool DMACanWrite(void)
|
||||
{
|
||||
return CalcFIFOReadyBit();
|
||||
}
|
||||
|
||||
void WriteDMA(uint32 V);
|
||||
uint32 ReadDMA(void);
|
||||
|
||||
uint32 Read(const pscpu_timestamp_t timestamp, uint32 A);
|
||||
|
||||
inline int32 GetScanlineNum(void)
|
||||
{
|
||||
return(scanline);
|
||||
}
|
||||
|
||||
INLINE uint16 PeekRAM(uint32 A)
|
||||
{
|
||||
return(GPURAM[(A >> 10) & 0x1FF][A & 0x3FF]);
|
||||
}
|
||||
|
||||
INLINE void PokeRAM(uint32 A, uint16 V)
|
||||
{
|
||||
GPURAM[(A >> 10) & 0x1FF][A & 0x3FF] = V;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint16 CLUT_Cache[256];
|
||||
uint32 CLUT_Cache_VB; // Don't try to be clever and reduce it to 16 bits... ~0U is value for invalidated state.
|
||||
|
||||
template<uint32 TexMode_TA>
|
||||
void Update_CLUT_Cache(uint16 raw_clut);
|
||||
|
||||
struct // Speedup-cache varibles, derived from other variables; shouldn't be saved in save states.
|
||||
struct // Speedup-cache variables, derived from other variables; shouldn't be saved in save states.
|
||||
{
|
||||
// TW*_* variables derived from tww, twh, twx, twy, TexPageX, TexPageY
|
||||
uint32 TWX_AND;
|
||||
|
@ -141,7 +73,6 @@ class PS_GPU
|
|||
uint32 TWY_AND;
|
||||
uint32 TWY_ADD;
|
||||
} SUCV;
|
||||
void RecalcTexWindowStuff(void);
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -149,16 +80,6 @@ class PS_GPU
|
|||
uint32 Tag;
|
||||
} TexCache[256];
|
||||
|
||||
void InvalidateTexCache(void);
|
||||
void InvalidateCache(void);
|
||||
|
||||
void SetTPage(uint32);
|
||||
|
||||
void ProcessFIFO(void);
|
||||
void WriteCB(uint32 data);
|
||||
uint32 ReadData(void);
|
||||
void SoftReset(void);
|
||||
|
||||
uint32 DMAControl;
|
||||
|
||||
//
|
||||
|
@ -196,62 +117,6 @@ class PS_GPU
|
|||
uint32 abr;
|
||||
uint32 TexMode;
|
||||
|
||||
bool LineSkipTest(unsigned y);
|
||||
|
||||
template<int BlendMode, bool MaskEval_TA, bool textured>
|
||||
void PlotPixel(uint32 x, uint32 y, uint16 pix);
|
||||
|
||||
template<uint32 TexMode_TA>
|
||||
uint16 GetTexel(uint32 u, uint32 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, 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);
|
||||
|
||||
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);
|
||||
|
||||
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>
|
||||
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);
|
||||
|
||||
private:
|
||||
static CTEntry Commands[256];
|
||||
static const CTEntry Commands_00_1F[0x20];
|
||||
static const CTEntry Commands_20_3F[0x20];
|
||||
static const CTEntry Commands_40_5F[0x20];
|
||||
static const CTEntry Commands_60_7F[0x20];
|
||||
static const CTEntry Commands_80_FF[0x80];
|
||||
|
||||
FastFIFO<uint32, 0x20> BlitterFIFO; // 0x10 on actual PS1 GPU, 0x20 here(see comment at top of gpu.h)
|
||||
uint32 DataReadBuffer;
|
||||
uint32 DataReadBufferEx;
|
||||
|
@ -326,7 +191,9 @@ class PS_GPU
|
|||
|
||||
pscpu_timestamp_t lastts;
|
||||
|
||||
static uint8 DitherLUT[4][4][512]; // Y, X, 8-bit source value(256 extra for saturation)
|
||||
uint8 DitherLUT[4][4][512]; // Y, X, 8-bit source value(256 extra for saturation)
|
||||
|
||||
CTEntry Commands[256];
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -340,21 +207,77 @@ class PS_GPU
|
|||
int32 *LineWidths;
|
||||
int LineVisFirst, LineVisLast;
|
||||
int32 hmc_to_visible;
|
||||
/*const*/ bool HardwarePALType;
|
||||
uint32 OutputLUT[384];
|
||||
|
||||
void ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x);
|
||||
|
||||
template<uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift>
|
||||
void ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) NO_INLINE;
|
||||
//
|
||||
//
|
||||
// Y, X
|
||||
uint16 GPURAM[512][1024];
|
||||
|
||||
public:
|
||||
uint32 GetVertStart() { return VertStart; }
|
||||
uint32 GetVertEnd() { return VertEnd; }
|
||||
int FirstLine;
|
||||
const bool HardwarePALType;
|
||||
|
||||
// Y, X
|
||||
uint16 GPURAM[512][1024];
|
||||
};
|
||||
|
||||
extern PS_GPU GPU;
|
||||
|
||||
void GPU_Init(bool pal_clock_and_tv) MDFN_COLD;
|
||||
void GPU_Kill(void) MDFN_COLD;
|
||||
|
||||
|
||||
|
||||
|
||||
void GPU_Power(void) MDFN_COLD;
|
||||
|
||||
void GPU_ResetTS(void);
|
||||
|
||||
void GPU_StartFrame(EmulateSpecStruct *espec);
|
||||
|
||||
MDFN_FASTCALL pscpu_timestamp_t GPU_Update(const pscpu_timestamp_t timestamp);
|
||||
|
||||
MDFN_FASTCALL void GPU_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V);
|
||||
|
||||
static INLINE bool GPU_CalcFIFOReadyBit(void)
|
||||
{
|
||||
if(GPU.InCmd & (PS_GPU::INCMD_PLINE | PS_GPU::INCMD_QUAD))
|
||||
return false;
|
||||
|
||||
if(GPU.BlitterFIFO.CanRead() == 0)
|
||||
return true;
|
||||
|
||||
if(GPU.InCmd & (PS_GPU::INCMD_FBREAD | PS_GPU::INCMD_FBWRITE))
|
||||
return false;
|
||||
|
||||
if(GPU.BlitterFIFO.CanRead() >= GPU.Commands[GPU.BlitterFIFO.Peek() >> 24].fifo_fb_len)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static INLINE bool GPU_DMACanWrite(void)
|
||||
{
|
||||
return GPU_CalcFIFOReadyBit();
|
||||
}
|
||||
|
||||
MDFN_FASTCALL void GPU_WriteDMA(uint32 V);
|
||||
uint32 GPU_ReadDMA(void);
|
||||
|
||||
MDFN_FASTCALL uint32 GPU_Read(const pscpu_timestamp_t timestamp, uint32 A);
|
||||
|
||||
static INLINE int32 GPU_GetScanlineNum(void)
|
||||
{
|
||||
return GPU.scanline;
|
||||
}
|
||||
|
||||
static INLINE uint16 GPU_PeekRAM(uint32 A)
|
||||
{
|
||||
return GPU.GPURAM[(A >> 10) & 0x1FF][A & 0x3FF];
|
||||
}
|
||||
|
||||
static INLINE void GPU_PokeRAM(uint32 A, uint16 V)
|
||||
{
|
||||
GPU.GPURAM[(A >> 10) & 0x1FF][A & 0x3FF] = V;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu_common.inc:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -19,8 +19,107 @@
|
|||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// Reference voodoo, since section anchors don't work with externs
|
||||
// WARNING: Don't use with members of (transparent) unions!
|
||||
//
|
||||
#define GLBVAR(x) static auto& x = GPU.x;
|
||||
|
||||
GLBVAR(CLUT_Cache)
|
||||
GLBVAR(CLUT_Cache_VB)
|
||||
GLBVAR(SUCV)
|
||||
GLBVAR(TexCache)
|
||||
GLBVAR(DMAControl)
|
||||
GLBVAR(ClipX0)
|
||||
GLBVAR(ClipY0)
|
||||
GLBVAR(ClipX1)
|
||||
GLBVAR(ClipY1)
|
||||
GLBVAR(OffsX)
|
||||
GLBVAR(OffsY)
|
||||
GLBVAR(MaskSetOR)
|
||||
GLBVAR(MaskEvalAND)
|
||||
GLBVAR(dtd)
|
||||
GLBVAR(dfe)
|
||||
GLBVAR(TexDisable)
|
||||
GLBVAR(TexDisableAllowChange)
|
||||
GLBVAR(tww)
|
||||
GLBVAR(twh)
|
||||
GLBVAR(twx)
|
||||
GLBVAR(twy)
|
||||
GLBVAR(TexPageX)
|
||||
GLBVAR(TexPageY)
|
||||
GLBVAR(SpriteFlip)
|
||||
GLBVAR(abr)
|
||||
GLBVAR(TexMode)
|
||||
GLBVAR(Commands)
|
||||
GLBVAR(BlitterFIFO)
|
||||
GLBVAR(DataReadBuffer)
|
||||
GLBVAR(DataReadBufferEx)
|
||||
GLBVAR(IRQPending)
|
||||
GLBVAR(InCmd)
|
||||
GLBVAR(InCmd_CC)
|
||||
GLBVAR(InQuad_F3Vertices)
|
||||
GLBVAR(InPLine_PrevPoint)
|
||||
GLBVAR(FBRW_X)
|
||||
GLBVAR(FBRW_Y)
|
||||
GLBVAR(FBRW_W)
|
||||
GLBVAR(FBRW_H)
|
||||
GLBVAR(FBRW_CurY)
|
||||
GLBVAR(FBRW_CurX)
|
||||
GLBVAR(DisplayFB_XStart)
|
||||
GLBVAR(DisplayFB_YStart)
|
||||
GLBVAR(HorizStart)
|
||||
GLBVAR(HorizEnd)
|
||||
GLBVAR(VertStart)
|
||||
GLBVAR(VertEnd)
|
||||
GLBVAR(DisplayMode)
|
||||
GLBVAR(DisplayOff)
|
||||
GLBVAR(PhaseChange)
|
||||
GLBVAR(InVBlank)
|
||||
GLBVAR(sl_zero_reached)
|
||||
GLBVAR(skip)
|
||||
GLBVAR(hide_hoverscan)
|
||||
GLBVAR(dump_framebuffer)
|
||||
GLBVAR(field)
|
||||
GLBVAR(field_ram_readout)
|
||||
GLBVAR(DisplayFB_CurYOffset)
|
||||
GLBVAR(DisplayFB_CurLineYReadout)
|
||||
GLBVAR(GPUClockCounter)
|
||||
GLBVAR(GPUClockRatio)
|
||||
GLBVAR(LinesPerField)
|
||||
GLBVAR(scanline)
|
||||
GLBVAR(DotClockCounter)
|
||||
GLBVAR(LineClockCounter)
|
||||
GLBVAR(LinePhase)
|
||||
GLBVAR(DrawTimeAvail)
|
||||
GLBVAR(lastts)
|
||||
GLBVAR(DitherLUT)
|
||||
GLBVAR(espec)
|
||||
GLBVAR(surface)
|
||||
GLBVAR(DisplayRect)
|
||||
GLBVAR(LineWidths)
|
||||
GLBVAR(LineVisFirst)
|
||||
GLBVAR(LineVisLast)
|
||||
GLBVAR(hmc_to_visible)
|
||||
GLBVAR(HardwarePALType)
|
||||
GLBVAR(OutputLUT)
|
||||
GLBVAR(GPURAM)
|
||||
|
||||
#undef GLBVAR
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
extern const CTEntry Commands_00_1F[0x20];
|
||||
extern const CTEntry Commands_20_3F[0x20];
|
||||
extern const CTEntry Commands_40_5F[0x20];
|
||||
extern const CTEntry Commands_60_7F[0x20];
|
||||
extern const CTEntry Commands_80_FF[0x80];
|
||||
|
||||
|
||||
template<int BlendMode, bool MaskEval_TA, bool textured>
|
||||
INLINE void PS_GPU::PlotPixel(uint32 x, uint32 y, uint16 fore_pix)
|
||||
static INLINE void PlotPixel(uint32 x, uint32 y, uint16 fore_pix)
|
||||
{
|
||||
y &= 511; // More Y precision bits than GPU RAM installed in (non-arcade, at least) Playstation hardware.
|
||||
|
||||
|
@ -92,7 +191,7 @@ INLINE void PS_GPU::PlotPixel(uint32 x, uint32 y, uint16 fore_pix)
|
|||
}
|
||||
}
|
||||
|
||||
INLINE uint16 PS_GPU::ModTexel(uint16 texel, int32 r, int32 g, int32 b, const int32 dither_x, const int32 dither_y)
|
||||
static INLINE uint16 ModTexel(uint16 texel, int32 r, int32 g, int32 b, const int32 dither_x, const int32 dither_y)
|
||||
{
|
||||
uint16 ret = texel & 0x8000;
|
||||
|
||||
|
@ -104,7 +203,7 @@ INLINE uint16 PS_GPU::ModTexel(uint16 texel, int32 r, int32 g, int32 b, const in
|
|||
}
|
||||
|
||||
template<uint32 TexMode_TA>
|
||||
INLINE void PS_GPU::Update_CLUT_Cache(uint16 raw_clut)
|
||||
static INLINE void Update_CLUT_Cache(uint16 raw_clut)
|
||||
{
|
||||
if(TexMode_TA < 2)
|
||||
{
|
||||
|
@ -152,7 +251,7 @@ INLINE void PS_GPU::Update_CLUT_Cache(uint16 raw_clut)
|
|||
}
|
||||
#endif
|
||||
|
||||
INLINE void PS_GPU::RecalcTexWindowStuff(void)
|
||||
static INLINE void RecalcTexWindowStuff(void)
|
||||
{
|
||||
SUCV.TWX_AND = ~(tww << 3);
|
||||
SUCV.TWX_ADD = ((twx & tww) << 3) + (TexPageX << (2 - std::min<uint32>(2, TexMode)));
|
||||
|
@ -162,7 +261,7 @@ INLINE void PS_GPU::RecalcTexWindowStuff(void)
|
|||
}
|
||||
|
||||
template<uint32 TexMode_TA>
|
||||
INLINE uint16 PS_GPU::GetTexel(uint32 u_arg, uint32 v_arg)
|
||||
static INLINE uint16 GetTexel(uint32 u_arg, uint32 v_arg)
|
||||
{
|
||||
static_assert(TexMode_TA <= 2, "TexMode_TA must be <= 2");
|
||||
|
||||
|
@ -210,7 +309,7 @@ INLINE uint16 PS_GPU::GetTexel(uint32 u_arg, uint32 v_arg)
|
|||
return(fbw);
|
||||
}
|
||||
|
||||
INLINE bool PS_GPU::LineSkipTest(unsigned y)
|
||||
static INLINE bool LineSkipTest(unsigned y)
|
||||
{
|
||||
//DisplayFB_XStart >= OffsX && DisplayFB_YStart >= OffsY &&
|
||||
// ((y & 1) == (DisplayFB_CurLineYReadout & 1))
|
||||
|
@ -232,7 +331,7 @@ INLINE bool PS_GPU::LineSkipTest(unsigned y)
|
|||
//#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 >
|
||||
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) \
|
||||
{ \
|
||||
|
@ -257,7 +356,7 @@ INLINE bool PS_GPU::LineSkipTest(unsigned y)
|
|||
//
|
||||
//
|
||||
|
||||
#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_SUB(bm, cv, tm, mam) 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) \
|
||||
{ \
|
||||
|
@ -283,7 +382,7 @@ INLINE bool PS_GPU::LineSkipTest(unsigned y)
|
|||
//
|
||||
//
|
||||
|
||||
#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_SUB(bm, cv, mam) Command_DrawLine<((cv & 0x08) >> 3), ((cv & 0x10) >> 4), ((cv & 0x2) >> 1) ? bm : -1, mam>
|
||||
|
||||
#define LINE_HELPER_FG(bm, cv) \
|
||||
{ \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu_line.cpp:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -25,6 +25,9 @@
|
|||
|
||||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
namespace PS_GPU_INTERNAL
|
||||
{
|
||||
|
||||
#include "gpu_common.inc"
|
||||
|
||||
struct line_fxp_coord
|
||||
|
@ -116,7 +119,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(line_point *points)
|
||||
{
|
||||
int32 i_dx;
|
||||
int32 i_dy;
|
||||
|
@ -201,14 +204,14 @@ 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 *cb)
|
||||
static void Command_DrawLine(const uint32 *cb)
|
||||
{
|
||||
const uint8 cc = cb[0] >> 24; // For pline handling later.
|
||||
line_point points[2];
|
||||
|
||||
DrawTimeAvail -= 16; // FIXME, correct time.
|
||||
|
||||
if(polyline && InCmd == INCMD_PLINE)
|
||||
if(polyline && InCmd == PS_GPU::INCMD_PLINE)
|
||||
{
|
||||
//printf("PLINE N\n");
|
||||
points[0] = InPLine_PrevPoint;
|
||||
|
@ -247,9 +250,9 @@ INLINE void PS_GPU::Command_DrawLine(const uint32 *cb)
|
|||
{
|
||||
InPLine_PrevPoint = points[1];
|
||||
|
||||
if(InCmd != INCMD_PLINE)
|
||||
if(InCmd != PS_GPU::INCMD_PLINE)
|
||||
{
|
||||
InCmd = INCMD_PLINE;
|
||||
InCmd = PS_GPU::INCMD_PLINE;
|
||||
InCmd_CC = cc;
|
||||
}
|
||||
}
|
||||
|
@ -257,16 +260,7 @@ INLINE void PS_GPU::Command_DrawLine(const uint32 *cb)
|
|||
DrawLine<goraud, BlendMode, MaskEval_TA>(points);
|
||||
}
|
||||
|
||||
//
|
||||
// C-style function wrappers so our command table isn't so ginormous(in memory usage).
|
||||
//
|
||||
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);
|
||||
}
|
||||
|
||||
const CTEntry PS_GPU::Commands_40_5F[0x20] =
|
||||
extern const CTEntry Commands_40_5F[0x20] =
|
||||
{
|
||||
LINE_HELPER(0x40),
|
||||
LINE_HELPER(0x41),
|
||||
|
@ -303,3 +297,4 @@ const CTEntry PS_GPU::Commands_40_5F[0x20] =
|
|||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu_polygon.cpp:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -18,9 +18,8 @@
|
|||
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#pragma GCC optimize ("no-unroll-loops,no-peel-loops")
|
||||
#endif
|
||||
|
||||
#include "psx.h"
|
||||
#include "gpu.h"
|
||||
|
@ -28,6 +27,8 @@
|
|||
|
||||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
namespace PS_GPU_INTERNAL
|
||||
{
|
||||
#include "gpu_common.inc"
|
||||
|
||||
#define COORD_FBS 12
|
||||
|
@ -144,7 +145,7 @@ static INLINE void AddIDeltas_DY(i_group &ig, const i_deltas &idl, uint32 count
|
|||
}
|
||||
|
||||
template<bool goraud, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
|
||||
INLINE void PS_GPU::DrawSpan(int y, const int32 x_start, const int32 x_bound, i_group ig, const i_deltas &idl)
|
||||
static INLINE void DrawSpan(int y, const int32 x_start, const int32 x_bound, i_group ig, const i_deltas &idl)
|
||||
{
|
||||
if(LineSkipTest(y))
|
||||
return;
|
||||
|
@ -235,7 +236,7 @@ INLINE void PS_GPU::DrawSpan(int y, const int32 x_start, const int32 x_bound, i_
|
|||
}
|
||||
|
||||
template<bool goraud, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
|
||||
INLINE void PS_GPU::DrawTriangle(tri_vertex *vertices)
|
||||
static INLINE void DrawTriangle(tri_vertex *vertices)
|
||||
{
|
||||
i_deltas idl;
|
||||
unsigned core_vertex;
|
||||
|
@ -505,7 +506,7 @@ INLINE void PS_GPU::DrawTriangle(tri_vertex *vertices)
|
|||
}
|
||||
|
||||
template<int numvertices, bool goraud, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
|
||||
INLINE void PS_GPU::Command_DrawPolygon(const uint32 *cb)
|
||||
static void Command_DrawPolygon(const uint32 *cb)
|
||||
{
|
||||
const unsigned cb0 = cb[0];
|
||||
tri_vertex vertices[3];
|
||||
|
@ -513,7 +514,7 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32 *cb)
|
|||
//uint32 tpage = 0;
|
||||
|
||||
// Base timing is approximate, and could be improved.
|
||||
if(numvertices == 4 && InCmd == INCMD_QUAD)
|
||||
if(numvertices == 4 && InCmd == PS_GPU::INCMD_QUAD)
|
||||
DrawTimeAvail -= (28 + 18);
|
||||
else
|
||||
DrawTimeAvail -= (64 + 18);
|
||||
|
@ -527,7 +528,7 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32 *cb)
|
|||
|
||||
if(numvertices == 4)
|
||||
{
|
||||
if(InCmd == INCMD_QUAD)
|
||||
if(InCmd == PS_GPU::INCMD_QUAD)
|
||||
{
|
||||
memcpy(&vertices[0], &InQuad_F3Vertices[1], 2 * sizeof(tri_vertex));
|
||||
sv = 2;
|
||||
|
@ -575,13 +576,13 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32 *cb)
|
|||
|
||||
if(numvertices == 4)
|
||||
{
|
||||
if(InCmd == INCMD_QUAD)
|
||||
if(InCmd == PS_GPU::INCMD_QUAD)
|
||||
{
|
||||
InCmd = INCMD_NONE;
|
||||
InCmd = PS_GPU::INCMD_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
InCmd = INCMD_QUAD;
|
||||
InCmd = PS_GPU::INCMD_QUAD;
|
||||
InCmd_CC = cb0 >> 24;
|
||||
memcpy(&InQuad_F3Vertices[0], &vertices[0], sizeof(tri_vertex) * 3);
|
||||
}
|
||||
|
@ -594,16 +595,7 @@ INLINE void PS_GPU::Command_DrawPolygon(const uint32 *cb)
|
|||
#undef COORD_FBS
|
||||
#undef COORD_MF_INT
|
||||
|
||||
//
|
||||
// C-style function wrappers so our command table isn't so ginormous(in memory usage).
|
||||
//
|
||||
template<int numvertices, bool shaded, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
|
||||
static void G_Command_DrawPolygon(PS_GPU* g, const uint32 *cb)
|
||||
{
|
||||
g->Command_DrawPolygon<numvertices, shaded, textured, BlendMode, TexMult, TexMode_TA, MaskEval_TA>(cb);
|
||||
}
|
||||
|
||||
const CTEntry PS_GPU::Commands_20_3F[0x20] =
|
||||
extern const CTEntry Commands_20_3F[0x20] =
|
||||
{
|
||||
/* 0x20 */
|
||||
POLY_HELPER(0x20),
|
||||
|
@ -641,3 +633,4 @@ const CTEntry PS_GPU::Commands_20_3F[0x20] =
|
|||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Mednafen Sony PS1 Emulation Module */
|
||||
/******************************************************************************/
|
||||
/* gpu_sprite.cpp:
|
||||
** Copyright (C) 2011-2016 Mednafen Team
|
||||
** Copyright (C) 2011-2017 Mednafen Team
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
|
@ -25,10 +25,12 @@
|
|||
|
||||
namespace MDFN_IEN_PSX
|
||||
{
|
||||
namespace PS_GPU_INTERNAL
|
||||
{
|
||||
#include "gpu_common.inc"
|
||||
|
||||
template<bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA, bool FlipX, bool FlipY>
|
||||
void PS_GPU::DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg, uint8 v_arg, uint32 color)
|
||||
static void DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg, uint8 v_arg, uint32 color)
|
||||
{
|
||||
const int32 r = color & 0xFF;
|
||||
const int32 g = (color >> 8) & 0xFF;
|
||||
|
@ -147,7 +149,7 @@ void PS_GPU::DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg,
|
|||
}
|
||||
|
||||
template<uint8 raw_size, bool textured, int BlendMode, bool TexMult, uint32 TexMode_TA, bool MaskEval_TA>
|
||||
INLINE void PS_GPU::Command_DrawSprite(const uint32 *cb)
|
||||
static void Command_DrawSprite(const uint32 *cb)
|
||||
{
|
||||
int32 x, y;
|
||||
int32 w, h;
|
||||
|
@ -233,16 +235,7 @@ INLINE void PS_GPU::Command_DrawSprite(const uint32 *cb)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// C-style function wrappers so our command table isn't so ginormous(in memory usage).
|
||||
//
|
||||
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);
|
||||
}
|
||||
|
||||
const CTEntry PS_GPU::Commands_60_7F[0x20] =
|
||||
extern const CTEntry Commands_60_7F[0x20] =
|
||||
{
|
||||
SPR_HELPER(0x60),
|
||||
SPR_HELPER(0x61),
|
||||
|
@ -279,3 +272,4 @@ const CTEntry PS_GPU::Commands_60_7F[0x20] =
|
|||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ static unsigned const psx_dbg_level = 0;
|
|||
|
||||
struct MDFN_PseudoRNG // Based off(but not the same as) public-domain "JKISS" PRNG.
|
||||
{
|
||||
MDFN_PseudoRNG()
|
||||
MDFN_COLD MDFN_PseudoRNG()
|
||||
{
|
||||
ResetState();
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ struct MDFN_PseudoRNG // Based off(but not the same as) public-domain "JKISS" PR
|
|||
return(mina + tmp);
|
||||
}
|
||||
|
||||
void ResetState(void) // Must always reset to the same state.
|
||||
MDFN_COLD void ResetState(void) // Must always reset to the same state.
|
||||
{
|
||||
x = 123456789;
|
||||
y = 987654321;
|
||||
|
@ -183,7 +183,6 @@ static int64 Memcard_SaveDelay[8];
|
|||
|
||||
PS_CPU *CPU = NULL;
|
||||
PS_SPU *SPU = NULL;
|
||||
PS_GPU *GPU = NULL;
|
||||
PS_CDC *CDC = NULL;
|
||||
FrontIO *FIO = NULL;
|
||||
|
||||
|
@ -342,7 +341,7 @@ void PSX_SetEventNT(const int type, const pscpu_timestamp_t next_timestamp)
|
|||
// Called from debug.cpp too.
|
||||
void ForceEventUpdates(const pscpu_timestamp_t timestamp)
|
||||
{
|
||||
PSX_SetEventNT(PSX_EVENT_GPU, GPU->Update(timestamp));
|
||||
PSX_SetEventNT(PSX_EVENT_GPU, GPU_Update(timestamp));
|
||||
PSX_SetEventNT(PSX_EVENT_CDC, CDC->Update(timestamp));
|
||||
|
||||
PSX_SetEventNT(PSX_EVENT_TIMER, TIMER_Update(timestamp));
|
||||
|
@ -368,7 +367,7 @@ bool PSX_EventHandler(const pscpu_timestamp_t timestamp)
|
|||
default: abort();
|
||||
|
||||
case PSX_EVENT_GPU:
|
||||
nt = GPU->Update(e->event_time);
|
||||
nt = GPU_Update(e->event_time);
|
||||
break;
|
||||
|
||||
case PSX_EVENT_CDC:
|
||||
|
@ -551,9 +550,9 @@ template<typename T, bool IsWrite, bool Access24> static INLINE void MemRW(pscpu
|
|||
timestamp++;
|
||||
|
||||
if(IsWrite)
|
||||
GPU->Write(timestamp, A, V);
|
||||
GPU_Write(timestamp, A, V);
|
||||
else
|
||||
V = GPU->Read(timestamp, A);
|
||||
V = GPU_Read(timestamp, A);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1011,7 +1010,7 @@ static void PSX_Power(bool powering_up)
|
|||
|
||||
MDEC_Power();
|
||||
CDC->Power();
|
||||
GPU->Power();
|
||||
GPU_Power();
|
||||
//SPU->Power(); // Called from CDC->Power()
|
||||
IRQ_Power();
|
||||
|
||||
|
@ -1392,12 +1391,10 @@ EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
|
|||
|
||||
CPU = new PS_CPU();
|
||||
SPU = new PS_SPU();
|
||||
GPU_Init(region == REGION_EU);
|
||||
CDC = new PS_CDC();
|
||||
DMA_Init();
|
||||
|
||||
//these steps can't be done without more information
|
||||
GPU = new PS_GPU(region == REGION_EU);
|
||||
|
||||
//setup gpu output surfaces
|
||||
MDFN_PixelFormat nf(MDFN_COLORSPACE_RGB, 16, 8, 0, 24);
|
||||
for(int i=0;i<2;i++)
|
||||
|
@ -1449,11 +1446,7 @@ EW_EXPORT s32 shock_Destroy(void* psx)
|
|||
SPU = NULL;
|
||||
}
|
||||
|
||||
if(GPU)
|
||||
{
|
||||
delete GPU;
|
||||
GPU = NULL;
|
||||
}
|
||||
GPU_Kill();
|
||||
|
||||
if(CPU)
|
||||
{
|
||||
|
@ -1554,7 +1547,7 @@ EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
|
|||
s_ShockPeripheralState.UpdateInput();
|
||||
|
||||
//GPU->StartFrame(psf_loader ? NULL : espec); //a reminder that when we do psf, we will be telling the gpu not to draw
|
||||
GPU->StartFrame(&espec);
|
||||
GPU_StartFrame(&espec);
|
||||
|
||||
//not that it matters, but we may need to control this at some point
|
||||
static const int ResampleQuality = 5;
|
||||
|
@ -1567,15 +1560,15 @@ EW_EXPORT s32 shock_Step(void* psx, eShockStep step)
|
|||
assert(timestamp);
|
||||
|
||||
ForceEventUpdates(timestamp);
|
||||
if(GPU->GetScanlineNum() < 100)
|
||||
printf("[BUUUUUUUG] Frame timing end glitch; scanline=%u, st=%u\n", GPU->GetScanlineNum(), timestamp);
|
||||
if(GPU_GetScanlineNum() < 100)
|
||||
printf("[BUUUUUUUG] Frame timing end glitch; scanline=%u, st=%u\n", GPU_GetScanlineNum(), timestamp);
|
||||
|
||||
espec.SoundBufSize = SPU->EndFrame(espec.SoundBuf);
|
||||
|
||||
CDC->ResetTS();
|
||||
TIMER_ResetTS();
|
||||
DMA_ResetTS();
|
||||
GPU->ResetTS();
|
||||
GPU_ResetTS();
|
||||
FIO->ResetTS();
|
||||
|
||||
RebaseTS(timestamp);
|
||||
|
@ -1637,8 +1630,8 @@ static void _shock_AnalyzeFramebufferCropInfo(int fbIndex, FramebufferCropInfo*
|
|||
{
|
||||
//printf("%d %d %d %d | %d | %d\n",yo,height, GPU->GetVertStart(), GPU->GetVertEnd(), espec.DisplayRect.y, GPU->FirstLine);
|
||||
|
||||
height = GPU->GetVertEnd() - GPU->GetVertStart();
|
||||
yo = GPU->FirstLine;
|
||||
height = GPU.GetVertEnd() - GPU.GetVertStart();
|
||||
yo = GPU.FirstLine;
|
||||
|
||||
if (espec.DisplayRect.h == 288 || espec.DisplayRect.h == 240)
|
||||
{
|
||||
|
@ -1702,7 +1695,7 @@ void NormalizeFramebuffer()
|
|||
|
||||
int virtual_width = 800;
|
||||
int virtual_height = 480;
|
||||
if (GPU->HardwarePALType)
|
||||
if (GPU.HardwarePALType)
|
||||
virtual_height = 576;
|
||||
|
||||
if (s_ShockConfig.opts.renderType == eShockRenderType_ClipOverscan)
|
||||
|
@ -1907,7 +1900,7 @@ EW_EXPORT s32 shock_GetFramebuffer(void* psx, ShockFramebufferInfo* fb)
|
|||
return SHOCK_OK;
|
||||
}
|
||||
|
||||
static void LoadEXE(const uint8 *data, const uint32 size, bool ignore_pcsp = false)
|
||||
static MDFN_COLD void LoadEXE(const uint8 *data, const uint32 size, bool ignore_pcsp = false)
|
||||
{
|
||||
uint32 PC;
|
||||
uint32 SP;
|
||||
|
@ -2628,7 +2621,7 @@ EW_EXPORT s32 shock_GetMemData(void* psx, void** ptr, s32* size, s32 memType)
|
|||
case eMemType_MainRAM: *ptr = MainRAM.data8; *size = 2048*1024; break;
|
||||
case eMemType_BiosROM: *ptr = BIOSROM->data8; *size = 512*1024; break;
|
||||
case eMemType_PIOMem: *ptr = PIOMem->data8; *size = 64*1024; break;
|
||||
case eMemType_GPURAM: *ptr = GPU->GPURAM; *size = 2*512*1024; break;
|
||||
case eMemType_GPURAM: *ptr = GPU.GPURAM; *size = 2*512*1024; break;
|
||||
case eMemType_SPURAM: *ptr = SPU->SPURAM; *size = 512*1024; break;
|
||||
case eMemType_DCache: *ptr = CPU->debug_GetScratchRAMPtr(); *size = 1024; break;
|
||||
default:
|
||||
|
@ -2698,7 +2691,7 @@ SYNCFUNC(PSX)
|
|||
MDEC_SyncState(isReader,ns);
|
||||
ns->ExitSection("MDEC");
|
||||
|
||||
TSS(GPU); //did some special logic for the CPU, ordering may matter, but probably not
|
||||
TSS((&GPU)); //did some special logic for the CPU, ordering may matter, but probably not
|
||||
|
||||
TSS(SPU);
|
||||
TSS(FIO); //TODO - DUALSHOCK, MC
|
||||
|
@ -2794,7 +2787,7 @@ EW_EXPORT s32 shock_SetRegister_CPU(void* psx, s32 index, u32 value)
|
|||
|
||||
EW_EXPORT s32 shock_SetRenderOptions(void* pxs, ShockRenderOptions* opts)
|
||||
{
|
||||
GPU->SetRenderOptions(opts);
|
||||
GPU.SetRenderOptions(opts);
|
||||
s_ShockConfig.opts = *opts;
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,6 @@ namespace MDFN_IEN_PSX
|
|||
class PS_SPU;
|
||||
|
||||
extern PS_CPU *CPU;
|
||||
extern PS_GPU *GPU;
|
||||
extern PS_CDC *CDC;
|
||||
extern PS_SPU *SPU;
|
||||
extern MultiAccessSizeMem<2048 * 1024, false> MainRAM;
|
||||
|
|
Loading…
Reference in New Issue