dolphin/Source/Plugins/Plugin_VideoDX9/Src/DLCompiler.cpp
Soren Jorvang 30e437f9e3 Fix some cases of variables being used uninitialized. Also some unused
variables, writeable strings and dangerously shadowed variables.

index(), gamma(), exp() and y0() are POSIX functions and using those
names can cause namespace confusion.

A number of C files were missing the final newline required by ANSI C
and some versions of GCC are pedantic enough to complain about this.

These changes simply the scons build, allowing us to get rid of
filterWarnings which is simply more trouble than it's worth.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5574 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-06-02 20:35:12 +00:00

468 lines
10 KiB
C++

#include "stdafx.h"
#if 0
#include "OpcodeDecoding.h"
#include "VertexLoader.h"
#include "VertexHandler.h"
#include "DataReader.h"
#include "BPStructs.h"
#include "CPStructs.h"
#include "XFStructs.h"
#include "DLCompiler.h"
#include "x86.h"
#include "main.h"
#include "Utils.h"
CompiledDList::CompiledDList(u32 _addr, u32 _size)
{
dataSize = 0;
data = 0;
code = 0;
addr = _addr;
size = _size;
pass = 0;
numBatches = 0;
batches = 0;
}
CompiledDList::~CompiledDList()
{
if (data)
delete [] data;
if (code)
delete [] code;
if (batches)
delete [] batches;
}
bool CompiledDList::Call()
{
switch(pass) {
case 0: // First compiling pass : find data size
if (Pass1())
{
pass = 1;
return true;
}
else
return false;
case 1: // Second compiling pass : actually compile
//if pass1 succeeded, pass2 will too
Pass2();
pass = 2;
return true;
case 2: // Run pass - we have a compiled dlist, just call it
Run();
return true;
default:
//ERROR
return false;
}
}
bool CompiledDList::Pass1()
{
/* //find the size of code + data, if the dlist is worth recompiling etc
// at the same time, do the ordinary stuff
g_pDataReader = &dlistReader;
OpcodeReaders::SetDListReader(addr, addr+size);
dataSize = 0;
codeSize = 0;
numBatches = 0;
bool lastIsPrim = false;
while (OpcodeReaders::IsDListOKToRead())
{
int Cmd = g_pDataReader->Read8();
switch(Cmd)
{
case GX_LOAD_CP_REG: //0x08
{
u32 SubCmd = g_pDataReader->Read8();
u32 Value = g_pDataReader->Read32();
LoadCPReg(SubCmd,Value);
//COMPILER
codeSize+=13;
}
break;
case GX_LOAD_XF_REG:
{
u32 Cmd2 = g_pDataReader->Read32();
int dwTransferSize = ((Cmd2>>16)&15) + 1;
DWORD dwAddress = Cmd2 & 0xFFFF;
static u32 pData[16];
for (int i=0; i<dwTransferSize; i++)
pData[i] = g_pDataReader->Read32();
LoadXFReg(dwTransferSize,dwAddress,pData);
//COMPILER
dataSize+=dwTransferSize;
codeSize+=17;
}
break;
case GX_LOAD_BP_REG: //0x61
{
u32 cmd=g_pDataReader->Read32();
LoadBPReg(cmd);
codeSize+=9;
}
break;
case GX_LOAD_INDX_A: //used for position matrices
LoadIndexedXF(g_pDataReader->Read32(),0xC);
codeSize+=13;
break;
case GX_LOAD_INDX_B: //used for normal matrices
LoadIndexedXF(g_pDataReader->Read32(),0xD);
codeSize+=13;
break;
case GX_LOAD_INDX_C: //used for postmatrices
LoadIndexedXF(g_pDataReader->Read32(),0xE);
codeSize+=13;
break;
case GX_LOAD_INDX_D: //used for lights
LoadIndexedXF(g_pDataReader->Read32(),0xF);
codeSize+=13;
break;
case GX_CMD_CALL_DL:
MessageBox(0,"Display lists can't recurse!!","error",0);
break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
break;
case GX_NOP:
break;
default:
if (Cmd&0x80)
{
int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
if (lastIsPrim)
{
//join to last
}
else
{
//finish up last and commit
}
u16 numVertices = g_pDataReader->Read16();
tempvarray.Reset();
VertexLoader::SetVArray(&tempvarray);
VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK];
loader->Setup();
loader->PrepareRun();
int vsize = loader->GetVertexSize();
loader->RunVertices(numVertices);
CVertexHandler::DrawVertices(primitive, numVertices, &tempvarray);
CVertexHandler::Flush();
//COMPILER
codeSize+=21;
numBatches++;
lastIsPrim = true;
}
break;
}
}
if (lastIsPrim)
{
//finish up last and commit
}
codeSize*=2;*/
return true;
}
void CompiledDList::Pass2()
{
/* OpcodeReaders::SetDListReader(addr, addr+size);
data = new u32[dataSize];
code = new u8[codeSize]; //at least
batches = new Batch[numBatches];
int batchCount = 0;
u32 *dataptr = data;
x86Init();
x86SetPtr((s8*)code);
//WC8(0xCC);
//actually do the recompiling, emit code and data, protect the memory
// but again, at the same time do the ordinary stuff
// so the compiled display list won't be run until the third time actually
bool dump = false,lastIsGeom=false;
FILE *f;
#ifndef TEASER
if (dump)
{
f=fopen("D:\\dlistlogs.txt","a");
fprintf(f,"===========================================\n");
}
#endif
while (OpcodeReaders::IsDListOKToRead())
{
int Cmd = g_pDataReader->Read8();
switch(Cmd)
{
case GX_LOAD_CP_REG: //0x08
{
lastIsGeom = false;
u32 SubCmd = g_pDataReader->Read8();
u32 Value = g_pDataReader->Read32();
if (dump)
fprintf(f,"CP | %02x %08x\n",SubCmd,Value);
LoadCPReg(SubCmd,Value);
//COMPILER
PUSH_WordToStack(Value);
PUSH_WordToStack(SubCmd);
CALLFunc((u32)LoadCPReg);
}
break;
case GX_LOAD_XF_REG:
{
lastIsGeom = false;
u32 Cmd2 = g_pDataReader->Read32();
int dwTransferSize = ((Cmd2>>16)&15) + 1;
u32 dwAddress = Cmd2 & 0xFFFF;
static u32 pData[16];
u32 *oldDataPtr = dataptr;
if (dump)
{
fprintf(f,"XF | %01xx %04x\n",dwTransferSize,dwAddress);
for (int i=0; i<dwTransferSize; i++)
fprintf(f, "%08x | %f\n",oldDataPtr[i], *((float*)oldDataPtr+i));
}
for (int i=0; i<dwTransferSize; i++) // a little compiler here too
*dataptr++ = g_pDataReader->Read32();
LoadXFReg(dwTransferSize,dwAddress,oldDataPtr);
//COMPILER
PUSH_WordToStack((u32)oldDataPtr);
PUSH_WordToStack(dwAddress);
PUSH_WordToStack(dwTransferSize);
CALLFunc((u32)LoadXFReg);
}
break;
case GX_LOAD_BP_REG: //0x61
{
lastIsGeom = false;
u32 cmd=g_pDataReader->Read32();
if (dump)
fprintf(f,"BP | %08x\n",cmd);
LoadBPReg(cmd);
//COMPILER
PUSH_WordToStack(cmd);
CALLFunc((u32)LoadBPReg);
}
break;
case GX_LOAD_INDX_A: //usually used for position matrices
{
lastIsGeom = false;
u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xC);
//COMPILER
PUSH_WordToStack(0xC);
PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF);
if (dump)
fprintf(f,"LOADINDEXA | pos matrix\n");
}
break;
case GX_LOAD_INDX_B: //usually used for normal matrices
{
lastIsGeom = false;
u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xD);
//COMPILER
PUSH_WordToStack(0xD);
PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF);
if (dump)
fprintf(f,"LOADINDEXB | nrm matrix\n");
}
break;
case GX_LOAD_INDX_C: //usually used for postmatrices
{
lastIsGeom = false;
u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xE);
//COMPILER
PUSH_WordToStack(0xE);
PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF);
if (dump)
fprintf(f,"LOADINDEXC | post matrix\n");
}
break;
case GX_LOAD_INDX_D: //usually used for lights
{
lastIsGeom = false;
u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xF);
//COMPILER
PUSH_WordToStack(0xF);
PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF);
if (dump)
fprintf(f,"LOADINDEXD | light\n");
}
break;
case GX_CMD_CALL_DL:
// ERORRR
break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
if (dump)
fprintf(f,"invalidate vc\n");
break;
case GX_NOP:
if (dump)
fprintf(f,"nop\n");
break;
default:
if (Cmd&0x80)
{
int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
//if (lastIsGeom) INCSTAT(stats.numJoins);
u16 numVertices = g_pDataReader->Read16();
if (dump)
fprintf(f,"DP: prim=%02x numv=%i\n",primitive,numVertices);
DecodedVArray &va = batches[batchCount].varray;
VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK];
TVtxDesc &vd = loader->GetVtxDesc();
VertexLoader::SetVArray(&va);
loader->Setup();
loader->PrepareRun();
// va.numColors = loader->GetNumColors();
// va.numUVs = loader->GetNumTCs();
// va.numNormals = loader->GetNumNormals();
//va.num
va.Create(numVertices,vd.PosMatIdx,
vd.Tex0MatIdx+vd.Tex1MatIdx+vd.Tex2MatIdx+vd.Tex3MatIdx+
vd.Tex4MatIdx+vd.Tex5MatIdx+vd.Tex6MatIdx+vd.Tex7MatIdx,
va.numNormals, va.numColors, va.numTCs);
int vsize = loader->GetVertexSize();
loader->RunVertices(numVertices);
CVertexHandler::DrawVertices(primitive, numVertices, &va);
CVertexHandler::Flush();
// YES we have now filled our varray
//LETS COMPILE
PUSH_WordToStack(primitive);
PUSH_WordToStack(batchCount);
PUSH_WordToStack((u32)this);
CALLFunc((u32)DrawHelperHelper);
batchCount++;
lastIsGeom = true;
if (dump)
fprintf(f,"DRAW PRIMITIVE: prim=%02x numv=%i\n",primitive,numVertices);
}
break;
}
}
if (dump)
{
fprintf(f,"***************************************\n\n\n");
}
RET();
if (dump)
fclose(f);*/
//we're done, next time just kick the compiled list off, much much faster than interpreting!
}
void CompiledDList::DrawHelperHelper(CompiledDList *dl, int vno, int prim)
{
Batch &b = dl->batches[vno];
CVertexHandler::DrawVertices(prim, b.varray.GetSize(), &b.varray);
}
void CompiledDList::Run()
{
//run the code
((void (*)())(code))();
CVertexHandler::Flush();
}
DListCache::DLCache DListCache::dlists;
void DListCache::Init()
{
}
void DListCache::Shutdown()
{
DLCache::iterator iter = dlists.begin();
for (;iter!=dlists.end();iter++)
iter->second.Destroy();
dlists.clear();
}
void DListCache::Call(u32 _addr, u32 _size)
{
DLCache::iterator iter;
iter = dlists.find(_addr);
if (iter != dlists.end())
{
if (iter->second.size == _size)
{
iter->second.dlist->Call();
return;
}
else // wrong size, need to recompile
{
iter->second.Destroy();
iter=dlists.erase(iter);
}
}
//Make an entry in the table
DLCacheEntry entry;
entry.dlist = new CompiledDList(_addr, _size);
entry.dlist->Call();
entry.frameCount = frameCount;
entry.size = _size;
dlists[_addr] = entry;
INCSTAT(stats.numDListsCreated);
SETSTAT(stats.numDListsAlive,(int)dlists.size());
}
void DListCache::Cleanup()
{
for (DLCache::iterator iter=dlists.begin(); iter!=dlists.end();iter++)
{
DLCacheEntry &entry = iter->second;
if (entry.frameCount<frameCount-80)
{
entry.Destroy();
iter = dlists.erase(iter);
}
}
SETSTAT(stats.numDListsAlive,(int)dlists.size());
}
#endif