WIP 0.9.44.1

This commit is contained in:
zeromus 2020-04-06 01:30:02 -04:00
parent ff835a4185
commit 165f3db2d8
10 changed files with 1033 additions and 1157 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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) \
{ \

View File

@ -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] =
};
}
}

View File

@ -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] =
};
}
}

View File

@ -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] =
};
}
}

View File

@ -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;
}

View File

@ -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;