mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
8-bit texture upload byte selection (thanks to Ville; but not tested yet); code cleanup
This commit is contained in:
parent
d155fbd6e4
commit
d8aefa421d
|
@ -41,8 +41,8 @@
|
|||
* The render currently cannot cope with this.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include "Supermodel.h"
|
||||
#include <cstring>
|
||||
|
||||
// Macros that divide memory regions into pages and mark them as dirty when they are written to
|
||||
#define PAGE_WIDTH 12
|
||||
|
@ -150,7 +150,7 @@ void CReal3D::EndVBlank(void)
|
|||
error = false; // clear error (just needs to be done once per frame)
|
||||
}
|
||||
|
||||
UINT32 CReal3D::SyncSnapshots(void)
|
||||
uint32_t CReal3D::SyncSnapshots(void)
|
||||
{
|
||||
// Update read-only copy of command port flag
|
||||
commandPortWrittenRO = commandPortWritten;
|
||||
|
@ -167,7 +167,7 @@ UINT32 CReal3D::SyncSnapshots(void)
|
|||
return UpdateSnapshots(false);
|
||||
}
|
||||
|
||||
UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned size, UINT8 *dirty)
|
||||
uint32_t CReal3D::UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty)
|
||||
{
|
||||
unsigned dirtySize = DIRTY_SIZE(size);
|
||||
if (copyWhole)
|
||||
|
@ -180,12 +180,12 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
|
|||
else
|
||||
{
|
||||
// Otherwise, loop through dirty pages array to find out what needs to be updated and copy only those parts
|
||||
UINT32 copied = 0;
|
||||
UINT8 *pSrc = src;
|
||||
UINT8 *pDst = dst;
|
||||
uint32_t copied = 0;
|
||||
uint8_t *pSrc = src;
|
||||
uint8_t *pDst = dst;
|
||||
for (unsigned i = 0; i < dirtySize; i++)
|
||||
{
|
||||
UINT8 d = dirty[i];
|
||||
uint8_t d = dirty[i];
|
||||
if (d)
|
||||
{
|
||||
for (unsigned j = 0; j < 8; j++)
|
||||
|
@ -193,7 +193,7 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
|
|||
if (d&1)
|
||||
{
|
||||
// If not at very end of region, then copy an extra 4 bytes to allow for a possible 32-bit overlap
|
||||
UINT32 toCopy = (i < dirtySize - 1 || j < 7 ? PAGE_SIZE + 4 : PAGE_SIZE);
|
||||
uint32_t toCopy = (i < dirtySize - 1 || j < 7 ? PAGE_SIZE + 4 : PAGE_SIZE);
|
||||
memcpy(pDst, pSrc, toCopy);
|
||||
copied += toCopy;
|
||||
}
|
||||
|
@ -213,13 +213,13 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
|
|||
}
|
||||
}
|
||||
|
||||
UINT32 CReal3D::UpdateSnapshots(bool copyWhole)
|
||||
uint32_t CReal3D::UpdateSnapshots(bool copyWhole)
|
||||
{
|
||||
// Update all memory region snapshots
|
||||
UINT32 cullLoCopied = UpdateSnapshot(copyWhole, (UINT8*)cullingRAMLo, (UINT8*)cullingRAMLoRO, 0x400000, cullingRAMLoDirty);
|
||||
UINT32 cullHiCopied = UpdateSnapshot(copyWhole, (UINT8*)cullingRAMHi, (UINT8*)cullingRAMHiRO, 0x100000, cullingRAMHiDirty);
|
||||
UINT32 polyCopied = UpdateSnapshot(copyWhole, (UINT8*)polyRAM, (UINT8*)polyRAMRO, 0x400000, polyRAMDirty);
|
||||
UINT32 textureCopied = UpdateSnapshot(copyWhole, (UINT8*)textureRAM, (UINT8*)textureRAMRO, 0x800000, textureRAMDirty);
|
||||
uint32_t cullLoCopied = UpdateSnapshot(copyWhole, (uint8_t*)cullingRAMLo, (uint8_t*)cullingRAMLoRO, 0x400000, cullingRAMLoDirty);
|
||||
uint32_t cullHiCopied = UpdateSnapshot(copyWhole, (uint8_t*)cullingRAMHi, (uint8_t*)cullingRAMHiRO, 0x100000, cullingRAMHiDirty);
|
||||
uint32_t polyCopied = UpdateSnapshot(copyWhole, (uint8_t*)polyRAM, (uint8_t*)polyRAMRO, 0x400000, polyRAMDirty);
|
||||
uint32_t textureCopied = UpdateSnapshot(copyWhole, (uint8_t*)textureRAM, (uint8_t*)textureRAMRO, 0x800000, textureRAMDirty);
|
||||
//printf("Read3D copied - cullLo:%4uK, cullHi:%4uK, poly:%4uK, texture:%4uK\n", cullLoCopied / 1024, cullHiCopied / 1024, polyCopied / 1024, textureCopied / 1024);
|
||||
return cullLoCopied + cullHiCopied + polyCopied + textureCopied;
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ void CReal3D::DMACopy(void)
|
|||
{
|
||||
while (dmaLength != 0)
|
||||
{
|
||||
UINT32 data = Bus->Read32(dmaSrc);
|
||||
uint32_t data = Bus->Read32(dmaSrc);
|
||||
Bus->Write32(dmaDest, FLIPENDIAN32(data));
|
||||
dmaSrc += 4;
|
||||
dmaDest += 4;
|
||||
|
@ -286,7 +286,7 @@ void CReal3D::DMACopy(void)
|
|||
}
|
||||
}
|
||||
|
||||
UINT8 CReal3D::ReadDMARegister8(unsigned reg)
|
||||
uint8_t CReal3D::ReadDMARegister8(unsigned reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
|
@ -302,7 +302,7 @@ UINT8 CReal3D::ReadDMARegister8(unsigned reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CReal3D::WriteDMARegister8(unsigned reg, UINT8 data)
|
||||
void CReal3D::WriteDMARegister8(unsigned reg, uint8_t data)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
|
@ -323,7 +323,7 @@ void CReal3D::WriteDMARegister8(unsigned reg, UINT8 data)
|
|||
//DebugLog("Real3D: WriteDMARegister8: reg=%X, data=%02X\n", reg, data);
|
||||
}
|
||||
|
||||
UINT32 CReal3D::ReadDMARegister32(unsigned reg)
|
||||
uint32_t CReal3D::ReadDMARegister32(unsigned reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
|
@ -337,7 +337,7 @@ UINT32 CReal3D::ReadDMARegister32(unsigned reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CReal3D::WriteDMARegister32(unsigned reg, UINT32 data)
|
||||
void CReal3D::WriteDMARegister32(unsigned reg, uint32_t data)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
|
@ -408,12 +408,9 @@ static const int tapFSM[][2] = // finite state machine, each state can lead to
|
|||
* Inserts a bit into an arbitrarily long bit field. Bit 0 is assumed to be
|
||||
* the MSB of the first byte in the buffer.
|
||||
*/
|
||||
void CReal3D::InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit)
|
||||
void CReal3D::InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit)
|
||||
{
|
||||
unsigned bitInByte;
|
||||
|
||||
bitInByte = 7 - (bitNum & 7);
|
||||
|
||||
unsigned bitInByte = 7 - (bitNum & 7);
|
||||
buf[bitNum / 8] &= ~(1 << bitInByte);
|
||||
buf[bitNum / 8] |= (bit << bitInByte);
|
||||
}
|
||||
|
@ -423,11 +420,9 @@ void CReal3D::InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit)
|
|||
*
|
||||
* Inserts a 32-bit ID code into the ID bit field.
|
||||
*/
|
||||
void CReal3D::InsertID(UINT32 id, unsigned startBit)
|
||||
void CReal3D::InsertID(uint32_t id, unsigned startBit)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 31; i >= 0; i--)
|
||||
for (int i = 31; i >= 0; i--)
|
||||
InsertBit(tapID, startBit++, (id >> i) & 1);
|
||||
}
|
||||
|
||||
|
@ -438,14 +433,12 @@ void CReal3D::InsertID(UINT32 id, unsigned startBit)
|
|||
* the number of bits must be specified. The bit shifted out of the LSB is
|
||||
* returned.
|
||||
*/
|
||||
unsigned CReal3D::Shift(UINT8 *data, unsigned numBits)
|
||||
unsigned CReal3D::Shift(uint8_t *data, unsigned numBits)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned shiftOut, shiftIn;
|
||||
|
||||
// This loop takes care of all the fully-filled bytes
|
||||
shiftIn = 0;
|
||||
shiftOut = 0;
|
||||
unsigned shiftIn = 0;
|
||||
unsigned shiftOut = 0;
|
||||
size_t i;
|
||||
for (i = 0; i < numBits / 8; i++)
|
||||
{
|
||||
shiftOut = data[i] & 1;
|
||||
|
@ -477,13 +470,9 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
|
|||
|
||||
// Go to next state
|
||||
tapState = tapFSM[tapState][tms];
|
||||
|
||||
switch (tapState)
|
||||
{
|
||||
case 3: // Capture-DR
|
||||
//printf("TAP: Capture-DR\n");
|
||||
//bit = 0;
|
||||
|
||||
/*
|
||||
* Read ASIC IDs.
|
||||
*
|
||||
|
@ -532,31 +521,22 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
|
|||
InsertID(0x316C6057, 1 + 4 * 32 + 1);
|
||||
InsertID(0x316C6057, 1 + 5 * 32 + 1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4: // Shift-DR
|
||||
|
||||
tapTDO = Shift(tapID, tapIDSize);
|
||||
//printf("TAP: Shift-DR Bit %d\n", bit++);
|
||||
break;
|
||||
|
||||
case 10: // Capture-IR
|
||||
|
||||
// Load lower 2 bits with 01 as per IEEE 1149.1-1990
|
||||
tapIR = 1;
|
||||
break;
|
||||
|
||||
case 11: // Shift-IR
|
||||
|
||||
// Shift IR towards output and load in new data from TDI
|
||||
tapTDO = tapIR & 1; // shift LSB to output
|
||||
tapIR >>= 1;
|
||||
tapIR |= ((UINT64) tdi << 45);
|
||||
tapIR |= ((uint64_t) tdi << 45);
|
||||
break;
|
||||
|
||||
case 15: // Update-IR
|
||||
|
||||
/*
|
||||
* Latch IR (technically, this should occur on the falling edge of
|
||||
* TCK)
|
||||
|
@ -565,7 +545,6 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
|
|||
tapCurrentInstruction = tapIR;
|
||||
//printf("TAP: Update-IR %XLL\n", tapCurrentInstruction);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -623,22 +602,28 @@ static const unsigned decode[64] =
|
|||
50,51,54,55,58,59,62,63
|
||||
};
|
||||
|
||||
void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, UINT16 *texData, unsigned bytesPerTexel)
|
||||
static void StoreTexelByte(uint16_t *texel, size_t byteSelect, uint8_t byte)
|
||||
{
|
||||
unsigned x, y, xx, yy, destOffset;
|
||||
if ((byteSelect & 1)) // write to LSB
|
||||
*texel = (*texel & 0xFF00) | byte;
|
||||
if ((byteSelect & 2)) // write to MSB
|
||||
*texel = (*texel & 0x00FF) | (uint16_t(byte) << 8);
|
||||
}
|
||||
|
||||
if (bytesPerTexel == 2) // 16-bit textures
|
||||
void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header)
|
||||
{
|
||||
if ((header & 0x00800000)) // 16-bit textures
|
||||
{
|
||||
// Outer 2 loops: 8x8 tiles
|
||||
for (y = yPos; y < (yPos+height); y += 8)
|
||||
for (size_t y = yPos; y < (yPos+height); y += 8)
|
||||
{
|
||||
for (x = xPos; x < (xPos+width); x += 8)
|
||||
for (size_t x = xPos; x < (xPos+width); x += 8)
|
||||
{
|
||||
// Inner 2 loops: 8x8 texels for the current tile
|
||||
destOffset = y*2048+x;
|
||||
for (yy = 0; yy < 8; yy++)
|
||||
size_t destOffset = y*2048+x;
|
||||
for (size_t yy = 0; yy < 8; yy++)
|
||||
{
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
for (size_t xx = 0; xx < 8; xx++)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
|
@ -659,24 +644,31 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
|
|||
* swapped.
|
||||
*/
|
||||
|
||||
size_t byteSelect = (header>>21)&3; // which byte to unpack to
|
||||
if (byteSelect == 3) // write to both?
|
||||
DebugLog("Observed 8-bit texture with byte_select=3!");
|
||||
|
||||
// Outer 2 loops: 8x8 tiles
|
||||
for (y = yPos; y < (yPos+height); y += 8)
|
||||
for (size_t y = yPos; y < (yPos+height); y += 8)
|
||||
{
|
||||
for (x = xPos; x < (xPos+width); x += 8)
|
||||
for (size_t x = xPos; x < (xPos+width); x += 8)
|
||||
{
|
||||
// Inner 2 loops: 8x8 texels for the current tile
|
||||
destOffset = y*2048+x;
|
||||
for (yy = 0; yy < 8; yy++)
|
||||
size_t destOffset = y*2048+x;
|
||||
for (size_t yy = 0; yy < 8; yy++)
|
||||
{
|
||||
for (xx = 0; xx < 8; xx += 2)
|
||||
for (size_t xx = 0; xx < 8; xx += 2)
|
||||
{
|
||||
uint8_t byte1 = texData[decode[(yy^1)*8+((xx+0)^1)]/2]>>8;
|
||||
uint8_t byte2 = texData[decode[(yy^1)*8+((xx+1)^1)]/2]&0xFF;
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
textureRAM[destOffset++] = texData[decode[(yy^1)*8+((xx+0)^1)]/2]>>8;
|
||||
StoreTexelByte(&textureRAM[destOffset], byteSelect, byte1);
|
||||
++destOffset;
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(textureRAMDirty, destOffset * 2);
|
||||
textureRAM[destOffset++] = texData[decode[(yy^1)*8+((xx+1)^1)]/2]&0xFF;
|
||||
|
||||
StoreTexelByte(&textureRAM[destOffset], byteSelect, byte2);
|
||||
++destOffset;
|
||||
}
|
||||
destOffset += 2048-8;
|
||||
}
|
||||
|
@ -702,20 +694,18 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
|
|||
}
|
||||
|
||||
// Texture data will be in little endian format
|
||||
void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
|
||||
void CReal3D::UploadTexture(uint32_t header, uint16_t *texData)
|
||||
{
|
||||
unsigned x, y, page, width, height, bytesPerTexel,
|
||||
mipYPos, mipWidth, mipHeight, mipNum, mipX, mipY;
|
||||
|
||||
// Position: texture RAM is arranged as 2 2048x1024 texel sheets
|
||||
x = 32*(header&0x3F);
|
||||
y = 32*((header>>7)&0x1F);
|
||||
page = (header>>20)&1;
|
||||
size_t x = 32*(header&0x3F);
|
||||
size_t y = 32*((header>>7)&0x1F);
|
||||
size_t page = (header>>20)&1;
|
||||
y += page*1024; // treat page as additional Y bit (one 2048x2048 sheet)
|
||||
|
||||
// Texture size and bit depth
|
||||
width = 32<<((header>>14)&7);
|
||||
height = 32<<((header>>17)&7);
|
||||
size_t width = 32<<((header>>14)&7);
|
||||
size_t height = 32<<((header>>17)&7);
|
||||
size_t bytesPerTexel;
|
||||
if ((header&0x00800000)) // 16 bits per texel
|
||||
bytesPerTexel = 2;
|
||||
else // 8 bits
|
||||
|
@ -725,7 +715,7 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
|
|||
}
|
||||
|
||||
// Mipmaps
|
||||
mipYPos = 32*((header>>7)&0x1F);
|
||||
size_t mipYPos = 32*((header>>7)&0x1F);
|
||||
|
||||
// Process texture data
|
||||
DebugLog("Real3D: Texture upload: pos=(%d,%d) size=(%d,%d), %d-bit\n", x, y, width, height, bytesPerTexel*8);
|
||||
|
@ -733,10 +723,11 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
|
|||
switch ((header>>24)&0x0F)
|
||||
{
|
||||
case 0x00: // texture w/ mipmaps
|
||||
StoreTexture(x, y, width, height, texData, bytesPerTexel);
|
||||
mipWidth = width;
|
||||
mipHeight = height;
|
||||
mipNum = 0;
|
||||
{
|
||||
StoreTexture(x, y, width, height, texData, header);
|
||||
size_t mipWidth = width;
|
||||
size_t mipHeight = height;
|
||||
size_t mipNum = 0;
|
||||
|
||||
while((mipHeight>8) && (mipWidth>8))
|
||||
{
|
||||
|
@ -746,38 +737,40 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
|
|||
texData += (mipWidth*mipHeight);
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
|
||||
mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
|
||||
size_t mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
|
||||
size_t mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
|
||||
if(page)
|
||||
mipY += 1024;
|
||||
mipNum++;
|
||||
StoreTexture(mipX, mipY, mipWidth, mipHeight, (UINT16 *) texData, bytesPerTexel);
|
||||
StoreTexture(mipX, mipY, mipWidth, mipHeight, (uint16_t *) texData, header);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x01: // texture w/out mipmaps
|
||||
StoreTexture(x, y, width, height, texData, bytesPerTexel);
|
||||
StoreTexture(x, y, width, height, texData, header);
|
||||
break;
|
||||
case 0x02: // mipmaps only
|
||||
mipWidth = width;
|
||||
mipHeight = height;
|
||||
mipNum = 0;
|
||||
{
|
||||
size_t mipWidth = width;
|
||||
size_t mipHeight = height;
|
||||
size_t mipNum = 0;
|
||||
while((mipHeight>8) && (mipWidth>8))
|
||||
{
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
|
||||
mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
|
||||
size_t mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
|
||||
size_t mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
|
||||
if(page)
|
||||
mipY += 1024;
|
||||
mipNum++;
|
||||
StoreTexture(mipX, mipY, mipWidth, mipHeight, texData, bytesPerTexel);
|
||||
StoreTexture(mipX, mipY, mipWidth, mipHeight, texData, header);
|
||||
if (bytesPerTexel == 1)
|
||||
texData += (mipWidth*mipHeight)/2;
|
||||
else
|
||||
texData += (mipWidth*mipHeight);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x80: // MAME thinks these might be a gamma table
|
||||
//break;
|
||||
default: // unknown
|
||||
|
@ -794,21 +787,17 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
|
|||
|
||||
void CReal3D::Flush(void)
|
||||
{
|
||||
unsigned i, size;
|
||||
UINT32 header;
|
||||
|
||||
commandPortWritten = true;
|
||||
|
||||
DebugLog("Real3D 88000000 written @ PC=%08X\n", ppc_get_pc());
|
||||
|
||||
// Upload textures (if any)
|
||||
if (fifoIdx > 0)
|
||||
{
|
||||
for (i = 0; i < fifoIdx; )
|
||||
for (size_t i = 0; i < fifoIdx; )
|
||||
{
|
||||
size = 2+textureFIFO[i+0]/2;
|
||||
size_t size = 2+textureFIFO[i+0]/2;
|
||||
size /= 4;
|
||||
header = textureFIFO[i+1]; // texture information header
|
||||
uint32_t header = textureFIFO[i+1]; // texture information header
|
||||
|
||||
// Spikeout seems to be uploading 0 length textures
|
||||
if (0 == size)
|
||||
|
@ -817,7 +806,7 @@ void CReal3D::Flush(void)
|
|||
break;
|
||||
}
|
||||
|
||||
UploadTexture(header,(UINT16 *)&textureFIFO[i+2]);
|
||||
UploadTexture(header,(uint16_t *)&textureFIFO[i+2]);
|
||||
DebugLog("Real3D: Texture upload completed: %X bytes (%X)\n", size*4, textureFIFO[i+0]);
|
||||
i += size;
|
||||
}
|
||||
|
@ -827,7 +816,7 @@ void CReal3D::Flush(void)
|
|||
fifoIdx = 0;
|
||||
}
|
||||
|
||||
void CReal3D::WriteTextureFIFO(UINT32 data)
|
||||
void CReal3D::WriteTextureFIFO(uint32_t data)
|
||||
{
|
||||
if (fifoIdx >= (0x100000/4))
|
||||
{
|
||||
|
@ -839,7 +828,7 @@ void CReal3D::WriteTextureFIFO(UINT32 data)
|
|||
textureFIFO[fifoIdx++] = data;
|
||||
}
|
||||
|
||||
void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
|
||||
void CReal3D::WriteTexturePort(unsigned reg, uint32_t data)
|
||||
{
|
||||
//printf("Texture Port: %X=%08X\n", reg, data);
|
||||
switch (reg)
|
||||
|
@ -854,7 +843,7 @@ void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
|
|||
break;
|
||||
case 0x8: // VROM texture length (also used to trigger uploads)
|
||||
case 0x14:
|
||||
UploadTexture(vromTextureHeader,(UINT16 *)&vrom[vromTextureAddr&0xFFFFFF]);
|
||||
UploadTexture(vromTextureHeader,(uint16_t *)&vrom[vromTextureAddr&0xFFFFFF]);
|
||||
//printf("texture upload: addr=%08X\n", vromTextureAddr);
|
||||
break;
|
||||
default:
|
||||
|
@ -863,21 +852,21 @@ void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
|
|||
}
|
||||
}
|
||||
|
||||
void CReal3D::WriteLowCullingRAM(UINT32 addr, UINT32 data)
|
||||
void CReal3D::WriteLowCullingRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(cullingRAMLoDirty, addr);
|
||||
cullingRAMLo[addr/4] = data;
|
||||
}
|
||||
|
||||
void CReal3D::WriteHighCullingRAM(UINT32 addr, UINT32 data)
|
||||
void CReal3D::WriteHighCullingRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(cullingRAMHiDirty, addr);
|
||||
cullingRAMHi[addr/4] = data;
|
||||
}
|
||||
|
||||
void CReal3D::WritePolygonRAM(UINT32 addr, UINT32 data)
|
||||
void CReal3D::WritePolygonRAM(uint32_t addr, uint32_t data)
|
||||
{
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
MARK_DIRTY(polyRAMDirty, addr);
|
||||
|
@ -885,21 +874,21 @@ void CReal3D::WritePolygonRAM(UINT32 addr, UINT32 data)
|
|||
}
|
||||
|
||||
// Registers seem to range from 0x00 to around 0x3C but they are not understood
|
||||
UINT32 CReal3D::ReadRegister(unsigned reg)
|
||||
uint32_t CReal3D::ReadRegister(unsigned reg)
|
||||
{
|
||||
DebugLog("Real3D: Read reg %X\n", reg);
|
||||
if (reg == 0)
|
||||
{
|
||||
UINT32 status = (ppc_total_cycles() >= statusChange ? 0x0 : 0x2);
|
||||
uint32_t status = (ppc_total_cycles() >= statusChange ? 0x0 : 0x2);
|
||||
return 0xFFFFFFFD|status;
|
||||
}
|
||||
else
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
UINT32 CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset)
|
||||
uint32_t CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset)
|
||||
{
|
||||
UINT32 d;
|
||||
uint32_t d;
|
||||
|
||||
if ((bits==8))
|
||||
{
|
||||
|
@ -935,7 +924,7 @@ UINT32 CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CReal3D::WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset, UINT32 data)
|
||||
void CReal3D::WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset, uint32_t data)
|
||||
{
|
||||
DebugLog("Real3D: PCI %d-bit write request for reg=%02X, data=%08X\n", bits, reg, data);
|
||||
}
|
||||
|
@ -1006,9 +995,9 @@ void CReal3D::SetStep(int stepID)
|
|||
DebugLog("Real3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF);
|
||||
}
|
||||
|
||||
bool CReal3D::Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit)
|
||||
bool CReal3D::Init(const uint8_t *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit)
|
||||
{
|
||||
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
size_t memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
|
||||
float memSizeMB = (float)memSize/(float)0x100000;
|
||||
|
||||
// IRQ and bus objects
|
||||
|
@ -1017,32 +1006,32 @@ bool CReal3D::Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr,
|
|||
dmaIRQ = dmaIRQBit;
|
||||
|
||||
// Allocate all Real3D RAM regions
|
||||
memoryPool = new(std::nothrow) UINT8[memSize];
|
||||
memoryPool = new(std::nothrow) uint8_t[memSize];
|
||||
if (NULL == memoryPool)
|
||||
return ErrorLog("Insufficient memory for Real3D object (needs %1.1f MB).", memSizeMB);
|
||||
|
||||
// Set up main pointers
|
||||
cullingRAMLo = (UINT32 *) &memoryPool[OFFSET_8C];
|
||||
cullingRAMHi = (UINT32 *) &memoryPool[OFFSET_8E];
|
||||
polyRAM = (UINT32 *) &memoryPool[OFFSET_98];
|
||||
textureRAM = (UINT16 *) &memoryPool[OFFSET_TEXRAM];
|
||||
textureFIFO = (UINT32 *) &memoryPool[OFFSET_TEXFIFO];
|
||||
cullingRAMLo = (uint32_t *) &memoryPool[OFFSET_8C];
|
||||
cullingRAMHi = (uint32_t *) &memoryPool[OFFSET_8E];
|
||||
polyRAM = (uint32_t *) &memoryPool[OFFSET_98];
|
||||
textureRAM = (uint16_t *) &memoryPool[OFFSET_TEXRAM];
|
||||
textureFIFO = (uint32_t *) &memoryPool[OFFSET_TEXFIFO];
|
||||
|
||||
// If multi-threaded, set up pointers for read-only snapshots and dirty page arrays too
|
||||
if (g_Config.gpuMultiThreaded)
|
||||
{
|
||||
cullingRAMLoRO = (UINT32 *) &memoryPool[OFFSET_8C_RO];
|
||||
cullingRAMHiRO = (UINT32 *) &memoryPool[OFFSET_8E_RO];
|
||||
polyRAMRO = (UINT32 *) &memoryPool[OFFSET_98_RO];
|
||||
textureRAMRO = (UINT16 *) &memoryPool[OFFSET_TEXRAM_RO];
|
||||
cullingRAMLoDirty = (UINT8 *) &memoryPool[OFFSET_8C_DIRTY];
|
||||
cullingRAMHiDirty = (UINT8 *) &memoryPool[OFFSET_8E_DIRTY];
|
||||
polyRAMDirty = (UINT8 *) &memoryPool[OFFSET_98_DIRTY];
|
||||
textureRAMDirty = (UINT8 *) &memoryPool[OFFSET_TEXRAM_DIRTY];
|
||||
cullingRAMLoRO = (uint32_t *) &memoryPool[OFFSET_8C_RO];
|
||||
cullingRAMHiRO = (uint32_t *) &memoryPool[OFFSET_8E_RO];
|
||||
polyRAMRO = (uint32_t *) &memoryPool[OFFSET_98_RO];
|
||||
textureRAMRO = (uint16_t *) &memoryPool[OFFSET_TEXRAM_RO];
|
||||
cullingRAMLoDirty = (uint8_t *) &memoryPool[OFFSET_8C_DIRTY];
|
||||
cullingRAMHiDirty = (uint8_t *) &memoryPool[OFFSET_8E_DIRTY];
|
||||
polyRAMDirty = (uint8_t *) &memoryPool[OFFSET_98_DIRTY];
|
||||
textureRAMDirty = (uint8_t *) &memoryPool[OFFSET_TEXRAM_DIRTY];
|
||||
}
|
||||
|
||||
// VROM pointer passed to us
|
||||
vrom = (UINT32 *) vromPtr;
|
||||
vrom = (uint32_t *) vromPtr;
|
||||
|
||||
DebugLog("Initialized Real3D (allocated %1.1f MB)\n", memSizeMB);
|
||||
return OKAY;
|
||||
|
@ -1080,7 +1069,7 @@ CReal3D::~CReal3D(void)
|
|||
fp = fopen("8c000000", "wb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
fwrite(cullingRAMLo, sizeof(UINT8), 0x400000, fp);
|
||||
fwrite(cullingRAMLo, sizeof(uint8_t), 0x400000, fp);
|
||||
fclose(fp);
|
||||
printf("dumped %s\n", "8c000000");
|
||||
}
|
||||
|
@ -1089,7 +1078,7 @@ CReal3D::~CReal3D(void)
|
|||
fp = fopen("8e000000", "wb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
fwrite(cullingRAMHi, sizeof(UINT8), 0x100000, fp);
|
||||
fwrite(cullingRAMHi, sizeof(uint8_t), 0x100000, fp);
|
||||
fclose(fp);
|
||||
printf("dumped %s\n", "8e000000");
|
||||
}
|
||||
|
@ -1098,7 +1087,7 @@ CReal3D::~CReal3D(void)
|
|||
fp = fopen("98000000", "wb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
fwrite(polyRAM, sizeof(UINT8), 0x400000, fp);
|
||||
fwrite(polyRAM, sizeof(uint8_t), 0x400000, fp);
|
||||
fclose(fp);
|
||||
printf("dumped %s\n", "98000000");
|
||||
}
|
||||
|
@ -1107,7 +1096,7 @@ CReal3D::~CReal3D(void)
|
|||
fp = fopen("texram", "wb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
fwrite(textureRAM, sizeof(UINT8), 0x800000, fp);
|
||||
fwrite(textureRAM, sizeof(uint8_t), 0x800000, fp);
|
||||
fclose(fp);
|
||||
printf("dumped %s\n", "texram");
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#ifndef INCLUDED_REAL3D_H
|
||||
#define INCLUDED_REAL3D_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/*
|
||||
* QueuedUploadTextures:
|
||||
*
|
||||
|
@ -98,7 +100,7 @@ public:
|
|||
* their work. If multi-threaded rendering is not enabled, then this method does
|
||||
* nothing.
|
||||
*/
|
||||
UINT32 SyncSnapshots(void);
|
||||
uint32_t SyncSnapshots(void);
|
||||
|
||||
/*
|
||||
* BeginFrame(void):
|
||||
|
@ -151,8 +153,8 @@ public:
|
|||
* Returns:
|
||||
* Data of the requested size, in little endian.
|
||||
*/
|
||||
UINT8 ReadDMARegister8(unsigned reg);
|
||||
UINT32 ReadDMARegister32(unsigned reg);
|
||||
uint8_t ReadDMARegister8(unsigned reg);
|
||||
uint32_t ReadDMARegister32(unsigned reg);
|
||||
|
||||
/*
|
||||
* WriteDMARegister8(reg, data):
|
||||
|
@ -165,8 +167,8 @@ public:
|
|||
* reg Register number to read from (0-0xFF only).
|
||||
* data Data to write.
|
||||
*/
|
||||
void WriteDMARegister8(unsigned reg, UINT8 data);
|
||||
void WriteDMARegister32(unsigned reg, UINT32 data);
|
||||
void WriteDMARegister8(unsigned reg, uint8_t data);
|
||||
void WriteDMARegister32(unsigned reg, uint32_t data);
|
||||
|
||||
/*
|
||||
* WriteLowCullingRAM(addr, data):
|
||||
|
@ -180,7 +182,7 @@ public:
|
|||
* User must ensure address is properly clamped.
|
||||
* data Data to write.
|
||||
*/
|
||||
void WriteLowCullingRAM(UINT32 addr, UINT32 data);
|
||||
void WriteLowCullingRAM(uint32_t addr, uint32_t data);
|
||||
|
||||
/*
|
||||
* WriteHighCullingRAM(addr, data):
|
||||
|
@ -194,7 +196,7 @@ public:
|
|||
* User must ensure address is properly clamped.
|
||||
* data Data to write.
|
||||
*/
|
||||
void WriteHighCullingRAM(UINT32 addr, UINT32 data);
|
||||
void WriteHighCullingRAM(uint32_t addr, uint32_t data);
|
||||
|
||||
/*
|
||||
* WriteTextureFIFO(data):
|
||||
|
@ -206,7 +208,7 @@ public:
|
|||
* Parameters:
|
||||
* data Data to write.
|
||||
*/
|
||||
void WriteTextureFIFO(UINT32 data);
|
||||
void WriteTextureFIFO(uint32_t data);
|
||||
|
||||
/*
|
||||
* WriteTexturePort(reg, data):
|
||||
|
@ -220,7 +222,7 @@ public:
|
|||
* data The 32-bit word to write to the register. A write to
|
||||
* register 8 triggers the upload.
|
||||
*/
|
||||
void WriteTexturePort(unsigned reg, UINT32 data);
|
||||
void WriteTexturePort(unsigned reg, uint32_t data);
|
||||
|
||||
/*
|
||||
* WritePolygonRAM(addr, data):
|
||||
|
@ -234,7 +236,7 @@ public:
|
|||
* User must ensure address is properly clamped.
|
||||
* data Data to write.
|
||||
*/
|
||||
void WritePolygonRAM(UINT32 addr, UINT32 data);
|
||||
void WritePolygonRAM(uint32_t addr, uint32_t data);
|
||||
|
||||
/*
|
||||
* ReadTAP(void):
|
||||
|
@ -272,7 +274,7 @@ public:
|
|||
* Returns:
|
||||
* The 32-bit status register.
|
||||
*/
|
||||
UINT32 ReadRegister(unsigned reg);
|
||||
uint32_t ReadRegister(unsigned reg);
|
||||
|
||||
/*
|
||||
* ReadPCIConfigSpace(device, reg, bits, offset):
|
||||
|
@ -291,7 +293,7 @@ public:
|
|||
* Returns:
|
||||
* Register data.
|
||||
*/
|
||||
UINT32 ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width);
|
||||
uint32_t ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width);
|
||||
|
||||
/*
|
||||
* WritePCIConfigSpace(device, reg, bits, offset, data):
|
||||
|
@ -308,7 +310,7 @@ public:
|
|||
* register number.
|
||||
* data Data.
|
||||
*/
|
||||
void WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width, UINT32 data);
|
||||
void WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width, uint32_t data);
|
||||
|
||||
/*
|
||||
* Reset(void):
|
||||
|
@ -359,13 +361,12 @@ public:
|
|||
* and DMA interrupts.
|
||||
* dmaIRQBit IRQ identifier bit to pass along to IRQ controller
|
||||
* when asserting interrupts.
|
||||
|
||||
*
|
||||
* Returns:
|
||||
* OKAY if successful otherwise FAIL (not enough memory). Prints own
|
||||
* errors.
|
||||
*/
|
||||
bool Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
|
||||
bool Init(const uint8_t *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
|
||||
|
||||
/*
|
||||
* CReal3D(void):
|
||||
|
@ -379,47 +380,47 @@ public:
|
|||
private:
|
||||
// Private member functions
|
||||
void DMACopy(void);
|
||||
void InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit);
|
||||
void InsertID(UINT32 id, unsigned startBit);
|
||||
unsigned Shift(UINT8 *data, unsigned numBits);
|
||||
void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, UINT16 *texData, unsigned bytesPerTexel);
|
||||
void UploadTexture(UINT32 header, UINT16 *texData);
|
||||
UINT32 UpdateSnapshots(bool copyWhole);
|
||||
UINT32 UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned size, UINT8 *dirty);
|
||||
void InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit);
|
||||
void InsertID(uint32_t id, unsigned startBit);
|
||||
unsigned Shift(uint8_t *data, unsigned numBits);
|
||||
void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header);
|
||||
void UploadTexture(uint32_t header, uint16_t *texData);
|
||||
uint32_t UpdateSnapshots(bool copyWhole);
|
||||
uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty);
|
||||
|
||||
// Renderer attached to the Real3D
|
||||
IRender3D *Render3D;
|
||||
|
||||
// Data passed from Model 3 object
|
||||
const UINT32 *vrom; // Video ROM
|
||||
const uint32_t *vrom; // Video ROM
|
||||
int step; // hardware stepping (as in GameInfo structure)
|
||||
UINT32 pciID; // PCI vendor and device ID
|
||||
uint32_t pciID; // PCI vendor and device ID
|
||||
|
||||
// Error flag (to limit errors to once per frame)
|
||||
bool error; // true if an error occurred this frame
|
||||
|
||||
// Real3D memory
|
||||
UINT8 *memoryPool; // all memory allocated here
|
||||
UINT32 *cullingRAMLo; // 4MB of culling RAM at 8C000000
|
||||
UINT32 *cullingRAMHi; // 1MB of culling RAM at 8E000000
|
||||
UINT32 *polyRAM; // 4MB of polygon RAM at 98000000
|
||||
UINT16 *textureRAM; // 8MB of internal texture RAM
|
||||
UINT32 *textureFIFO; // 1MB texture FIFO at 0x94000000
|
||||
unsigned fifoIdx; // index into texture FIFO
|
||||
UINT32 vromTextureAddr; // VROM texture port address data
|
||||
UINT32 vromTextureHeader; // VROM texture port header data
|
||||
uint8_t *memoryPool; // all memory allocated here
|
||||
uint32_t *cullingRAMLo; // 4MB of culling RAM at 8C000000
|
||||
uint32_t *cullingRAMHi; // 1MB of culling RAM at 8E000000
|
||||
uint32_t *polyRAM; // 4MB of polygon RAM at 98000000
|
||||
uint16_t *textureRAM; // 8MB of internal texture RAM
|
||||
uint32_t *textureFIFO; // 1MB texture FIFO at 0x94000000
|
||||
size_t fifoIdx; // index into texture FIFO
|
||||
uint32_t vromTextureAddr; // VROM texture port address data
|
||||
uint32_t vromTextureHeader; // VROM texture port header data
|
||||
|
||||
// Read-only snapshots
|
||||
UINT32 *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot]
|
||||
UINT32 *cullingRAMHiRO; // 1MB of culling RAM at 8E000000 [read-only snapshot]
|
||||
UINT32 *polyRAMRO; // 4MB of polygon RAM at 98000000 [read-only snapshot]
|
||||
UINT16 *textureRAMRO; // 8MB of internal texture RAM [read-only snapshot]
|
||||
uint32_t *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot]
|
||||
uint32_t *cullingRAMHiRO; // 1MB of culling RAM at 8E000000 [read-only snapshot]
|
||||
uint32_t *polyRAMRO; // 4MB of polygon RAM at 98000000 [read-only snapshot]
|
||||
uint16_t *textureRAMRO; // 8MB of internal texture RAM [read-only snapshot]
|
||||
|
||||
// Arrays to keep track of dirty pages in memory regions
|
||||
UINT8 *cullingRAMLoDirty;
|
||||
UINT8 *cullingRAMHiDirty;
|
||||
UINT8 *polyRAMDirty;
|
||||
UINT8 *textureRAMDirty;
|
||||
uint8_t *cullingRAMLoDirty;
|
||||
uint8_t *cullingRAMHiDirty;
|
||||
uint8_t *polyRAMDirty;
|
||||
uint8_t *textureRAMDirty;
|
||||
|
||||
// Queued texture uploads
|
||||
vector<QueuedUploadTextures> queuedUploadTextures;
|
||||
|
@ -430,31 +431,31 @@ private:
|
|||
|
||||
// IRQ handling
|
||||
CIRQ *IRQ; // IRQ controller
|
||||
unsigned dmaIRQ; // IRQ bit to use when calling IRQ handler
|
||||
size_t dmaIRQ; // IRQ bit to use when calling IRQ handler
|
||||
|
||||
// DMA device
|
||||
UINT32 dmaSrc;
|
||||
UINT32 dmaDest;
|
||||
UINT32 dmaLength;
|
||||
UINT32 dmaData;
|
||||
UINT32 dmaUnknownReg;
|
||||
UINT8 dmaStatus;
|
||||
UINT8 dmaConfig;
|
||||
uint32_t dmaSrc;
|
||||
uint32_t dmaDest;
|
||||
uint32_t dmaLength;
|
||||
uint32_t dmaData;
|
||||
uint32_t dmaUnknownReg;
|
||||
uint8_t dmaStatus;
|
||||
uint8_t dmaConfig;
|
||||
|
||||
// Command port
|
||||
bool commandPortWritten;
|
||||
bool commandPortWrittenRO; // Read-only copy of flag
|
||||
|
||||
// Status and command registers
|
||||
UINT64 statusChange;
|
||||
uint64_t statusChange;
|
||||
|
||||
// JTAG Test Access Port
|
||||
UINT64 tapCurrentInstruction; // latched IR (not always equal to IR)
|
||||
UINT64 tapIR; // instruction register (46 bits)
|
||||
UINT8 tapID[32]; // ASIC ID code data buffer
|
||||
uint64_t tapCurrentInstruction; // latched IR (not always equal to IR)
|
||||
uint64_t tapIR; // instruction register (46 bits)
|
||||
uint8_t tapID[32]; // ASIC ID code data buffer
|
||||
unsigned tapIDSize; // size of ID data in bits
|
||||
unsigned tapTDO; // bit shifted out to TDO
|
||||
int tapState; // current state
|
||||
unsigned tapState; // current state
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue