pushbufferz

This commit is contained in:
Aaron Robinson 2004-01-28 01:53:12 +00:00
parent abb7c73a5b
commit d4c0d58709
2 changed files with 101 additions and 70 deletions

BIN
Cxbx.opt

Binary file not shown.

View File

@ -66,92 +66,123 @@ void XTL::EmuExecutePushBuffer
D3DPRIMITIVETYPE PCPrimitiveType = (D3DPRIMITIVETYPE)-1; D3DPRIMITIVETYPE PCPrimitiveType = (D3DPRIMITIVETYPE)-1;
X_D3DPRIMITIVETYPE XBPrimitiveType = -1; X_D3DPRIMITIVETYPE XBPrimitiveType = -1;
// TODO: keep track of which # crashes
//_asm int 3
while((DWORD)pdwPushData < ((DWORD)pPushBuffer->Data + pPushBuffer->Size)) while((DWORD)pdwPushData < ((DWORD)pPushBuffer->Data + pPushBuffer->Size))
{ {
// NVPB_DrawVertices // Interpret GPU Instruction
if(*pdwPushData++ == 0x000417FC) switch(*pdwPushData++)
{ {
// Render Indexed Vertices // NVPB_Unknown
if(*pdwPushData == 0) default:
{ {
pdwPushData++; // return;
EmuCleanup("GPU Instruction Mask 0x%.08X Unhandled", *(pdwPushData-1));
if( (*pdwPushData & 0x40000100) == 0x40000100)
{
DWORD dwSkipBytes = (*pdwPushData & 0x0FFF0000) >> 16;
// advance to argument
pdwPushData++;
// argument doesnt matter
pdwPushData++;
// skip over given data
pdwPushData += dwSkipBytes/4;
}
LPDIRECT3DINDEXBUFFER8 pIndexBuffer=0;
HRESULT hRet = g_pD3DDevice8->CreateIndexBuffer(dwBytes, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pIndexBuffer);
if(FAILED(hRet))
EmuCleanup("Unable to create index buffer for PushBuffer emulation\n");
// copy index data
{
WORD *pData=0;
pIndexBuffer->Lock(0, dwBytes, (UCHAR**)&pData, NULL);
memcpy(pData, pIndexData, dwBytes);
pIndexBuffer->Unlock();
}
// render indexed vertices
{
g_pD3DDevice8->SetIndices(pIndexBuffer, 0);
g_pD3DDevice8->DrawIndexedPrimitive
(
PCPrimitiveType, 0, dwIndices, 0, EmuD3DVertex2PrimitiveCount(XBPrimitiveType, dwIndices)
);
}
// cleanup
pIndexBuffer->Release();
} }
// Set Indexed Vertices break;
else
// NVPB_Unknown
case 0x00041808:
{ {
XBPrimitiveType = *pdwPushData++; //_asm int 3
PCPrimitiveType = EmuPrimitiveType(XBPrimitiveType); WORD wUnknown = (WORD)*pdwPushData++;
// Parse Index Data // !?
if( (*pdwPushData & 0x40001800) == 0x40001800)
// EmuCleanup("GPU Instruction Mask 0x00041808 Unhandled (D3DDevice_DrawIndexedVertices)");
}
break;
// NVPB_DrawVertices
case 0x000417FC:
{
// Render Indexed Vertices
if(*pdwPushData == 0)
{ {
dwBytes = ((*pdwPushData & 0x0FFF0000) >> 16) - 4;
if(PCPrimitiveType == D3DPT_TRIANGLESTRIP)
dwIndices = dwBytes/2;
// advance to argument
pdwPushData++; pdwPushData++;
// argument doesnt matter // Null instruction
pdwPushData++; if( (*pdwPushData) == 0x00000000)
{
pdwPushData++;
}
else
// Skip Bytes
if( (*pdwPushData & 0x40000100) == 0x40000100)
{
DWORD dwSkipBytes = (*pdwPushData & 0x0FFF0000) >> 16;
// assign index data buffer // advance to argument
pIndexData = (PVOID)pdwPushData; pdwPushData++;
// argument doesnt matter
pdwPushData++;
// skip over given data
pdwPushData += dwSkipBytes/4;
}
LPDIRECT3DINDEXBUFFER8 pIndexBuffer=0;
HRESULT hRet = g_pD3DDevice8->CreateIndexBuffer(dwBytes, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pIndexBuffer);
if(FAILED(hRet))
EmuCleanup("Unable to create index buffer for PushBuffer emulation\n");
// copy index data
{
WORD *pData=0;
pIndexBuffer->Lock(0, dwBytes, (UCHAR**)&pData, NULL);
memcpy(pData, pIndexData, dwBytes);
pIndexBuffer->Unlock();
}
// render indexed vertices
{
g_pD3DDevice8->SetIndices(pIndexBuffer, 0);
g_pD3DDevice8->DrawIndexedPrimitive
(
PCPrimitiveType, 0, dwIndices, 0, EmuD3DVertex2PrimitiveCount(XBPrimitiveType, dwIndices)
);
}
// cleanup
pIndexBuffer->Release();
} }
// Set Indexed Vertices
else else
{ {
EmuCleanup("Error in PushBuffer interpretter"); XBPrimitiveType = *pdwPushData++;
} PCPrimitiveType = EmuPrimitiveType(XBPrimitiveType);
// advance past index data // Parse Index Data
pdwPushData += dwBytes/4; if( (*pdwPushData & 0x40001800) == 0x40001800)
{
dwBytes = ((*pdwPushData & 0x0FFF0000) >> 16);
if(PCPrimitiveType == D3DPT_TRIANGLESTRIP)
dwIndices = dwBytes/2;
// argument doesnt matter
pdwPushData++;
// assign index data buffer
pIndexData = (PVOID)pdwPushData;
// advance past index data
pdwPushData += dwBytes/4;
}
else
{
EmuCleanup("Error in PushBuffer interpretter");
}
}
} }
break;
} }
} }
} }