D3D: Fix bugs in the shader cache, fixes crashes on x64. added some debugging stuff (only active in debug builds). assorted code cleanup.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4145 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b15320bc02
commit
2599659022
|
@ -26,19 +26,18 @@ QUAD simulator
|
||||||
021231 243453
|
021231 243453
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void IndexGenerator::Start(unsigned short *startptr)
|
void IndexGenerator::Start(unsigned short *startptr)
|
||||||
{
|
{
|
||||||
ptr=startptr;
|
ptr = startptr;
|
||||||
index=0;
|
index = 0;
|
||||||
numPrims=0;
|
numPrims = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexGenerator::AddList(int numVerts)
|
void IndexGenerator::AddList(int numVerts)
|
||||||
{
|
{
|
||||||
int numTris = numVerts/3;
|
int numTris = numVerts / 3;
|
||||||
if (numTris<=0) return;
|
if (numTris <= 0) return;
|
||||||
for (int i=0; i<numTris; i++)
|
for (int i = 0; i < numTris; i++)
|
||||||
{
|
{
|
||||||
*ptr++ = index+i*3;
|
*ptr++ = index+i*3;
|
||||||
*ptr++ = index+i*3+1;
|
*ptr++ = index+i*3+1;
|
||||||
|
@ -50,10 +49,10 @@ void IndexGenerator::AddList(int numVerts)
|
||||||
|
|
||||||
void IndexGenerator::AddStrip(int numVerts)
|
void IndexGenerator::AddStrip(int numVerts)
|
||||||
{
|
{
|
||||||
int numTris = numVerts-2;
|
int numTris = numVerts - 2;
|
||||||
if (numTris<=0) return;
|
if (numTris <= 0) return;
|
||||||
bool wind = false;
|
bool wind = false;
|
||||||
for (int i=0; i<numTris; i++)
|
for (int i = 0; i < numTris; i++)
|
||||||
{
|
{
|
||||||
*ptr++ = index+i;
|
*ptr++ = index+i;
|
||||||
*ptr++ = index+i+(wind?2:1);
|
*ptr++ = index+i+(wind?2:1);
|
||||||
|
@ -66,9 +65,9 @@ void IndexGenerator::AddStrip(int numVerts)
|
||||||
|
|
||||||
void IndexGenerator::AddLineList(int numVerts)
|
void IndexGenerator::AddLineList(int numVerts)
|
||||||
{
|
{
|
||||||
int numLines= numVerts/2;
|
int numLines= numVerts / 2;
|
||||||
if (numLines<=0) return;
|
if (numLines <= 0) return;
|
||||||
for (int i=0; i<numLines; i++)
|
for (int i = 0; i < numLines; i++)
|
||||||
{
|
{
|
||||||
*ptr++ = index+i*2;
|
*ptr++ = index+i*2;
|
||||||
*ptr++ = index+i*2+1;
|
*ptr++ = index+i*2+1;
|
||||||
|
@ -79,9 +78,9 @@ void IndexGenerator::AddLineList(int numVerts)
|
||||||
|
|
||||||
void IndexGenerator::AddLineStrip(int numVerts)
|
void IndexGenerator::AddLineStrip(int numVerts)
|
||||||
{
|
{
|
||||||
int numLines = numVerts-1;
|
int numLines = numVerts - 1;
|
||||||
if (numLines<=0) return;
|
if (numLines <= 0) return;
|
||||||
for (int i=0; i<numLines; i++)
|
for (int i = 0; i < numLines; i++)
|
||||||
{
|
{
|
||||||
*ptr++ = index+i;
|
*ptr++ = index+i;
|
||||||
*ptr++ = index+i+1;
|
*ptr++ = index+i+1;
|
||||||
|
@ -93,9 +92,9 @@ void IndexGenerator::AddLineStrip(int numVerts)
|
||||||
|
|
||||||
void IndexGenerator::AddFan(int numVerts)
|
void IndexGenerator::AddFan(int numVerts)
|
||||||
{
|
{
|
||||||
int numTris = numVerts-2;
|
int numTris = numVerts - 2;
|
||||||
if (numTris<=0) return;
|
if (numTris <= 0) return;
|
||||||
for (int i=0; i<numTris; i++)
|
for (int i = 0; i < numTris; i++)
|
||||||
{
|
{
|
||||||
*ptr++ = index;
|
*ptr++ = index;
|
||||||
*ptr++ = index+i+1;
|
*ptr++ = index+i+1;
|
||||||
|
@ -108,15 +107,15 @@ void IndexGenerator::AddFan(int numVerts)
|
||||||
void IndexGenerator::AddQuads(int numVerts)
|
void IndexGenerator::AddQuads(int numVerts)
|
||||||
{
|
{
|
||||||
int numTris = (numVerts/4)*2;
|
int numTris = (numVerts/4)*2;
|
||||||
if (numTris<=0) return;
|
if (numTris <= 0) return;
|
||||||
for (int i=0; i<numTris/2; i++)
|
for (int i = 0; i < numTris / 2; i++)
|
||||||
{
|
{
|
||||||
*ptr++=index+i*4;
|
*ptr++ = index+i*4;
|
||||||
*ptr++=index+i*4+1;
|
*ptr++ = index+i*4+1;
|
||||||
*ptr++=index+i*4+3;
|
*ptr++ = index+i*4+3;
|
||||||
*ptr++=index+i*4+1;
|
*ptr++ = index+i*4+1;
|
||||||
*ptr++=index+i*4+2;
|
*ptr++ = index+i*4+2;
|
||||||
*ptr++=index+i*4+3;
|
*ptr++ = index+i*4+3;
|
||||||
}
|
}
|
||||||
index += numVerts;
|
index += numVerts;
|
||||||
numPrims += numTris;
|
numPrims += numTris;
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
|
|
||||||
class IndexGenerator
|
class IndexGenerator
|
||||||
{
|
{
|
||||||
unsigned short *ptr;
|
|
||||||
int numPrims;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Start(unsigned short *startptr);
|
void Start(unsigned short *startptr);
|
||||||
void AddList(int numVerts);
|
void AddList(int numVerts);
|
||||||
|
@ -38,6 +34,10 @@ public:
|
||||||
void AddQuads(int numVerts);
|
void AddQuads(int numVerts);
|
||||||
int GetNumPrims() {return numPrims;} //returns numprimitives
|
int GetNumPrims() {return numPrims;} //returns numprimitives
|
||||||
int GetNumVerts() {return index;} //returns numprimitives
|
int GetNumVerts() {return index;} //returns numprimitives
|
||||||
|
private:
|
||||||
|
unsigned short *ptr;
|
||||||
|
int numPrims;
|
||||||
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _INDEXGENERATOR_H
|
#endif // _INDEXGENERATOR_H
|
|
@ -398,7 +398,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
|
||||||
for (int i = 0; i < numStages; ++i)
|
for (int i = 0; i < numStages; ++i)
|
||||||
{
|
{
|
||||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||||
nIndirectStagesUsed |= 1<<bpmem.tevind[i].bt;
|
nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,13 +410,14 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
|
||||||
else
|
else
|
||||||
WRITE(p, "uniform samplerRECT ");
|
WRITE(p, "uniform samplerRECT ");
|
||||||
bool bfirst = true;
|
bool bfirst = true;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
if (texture_mask & (1<<i))
|
if (texture_mask & (1<<i))
|
||||||
{
|
{
|
||||||
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i);
|
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i);
|
||||||
bfirst = false;
|
bfirst = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
WRITE(p, ";\n");
|
WRITE(p, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,44 +92,17 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
||||||
|
|
||||||
char *p = text;
|
char *p = text;
|
||||||
WRITE(p, "//Vertex Shader: comp:%x, \n", components);
|
WRITE(p, "//Vertex Shader: comp:%x, \n", components);
|
||||||
WRITE(p, "typedef struct {\n"
|
WRITE(p, "typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_"I_POSNORMALMATRIX";\n"
|
||||||
" float4 T0, T1, T2;\n"
|
"typedef struct { float4 t; } FLT4;\n"
|
||||||
" float4 N0, N1, N2;\n"
|
"typedef struct { FLT4 T[24]; } s_"I_TEXMATRICES";\n"
|
||||||
"} s_"I_POSNORMALMATRIX";\n\n"
|
"typedef struct { FLT4 T[64]; } s_"I_TRANSFORMMATRICES";\n"
|
||||||
"typedef struct {\n"
|
"typedef struct { FLT4 T[32]; } s_"I_NORMALMATRICES";\n"
|
||||||
" float4 t;\n"
|
"typedef struct { FLT4 T[64]; } s_"I_POSTTRANSFORMMATRICES";\n"
|
||||||
"} FLT4;\n"
|
"typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n"
|
||||||
"typedef struct {\n"
|
"typedef struct { Light lights[8]; } s_"I_LIGHTS";\n"
|
||||||
" FLT4 T[24];\n"
|
"typedef struct { float4 C0,C1,C2,C3; } s_"I_MATERIALS";\n"
|
||||||
"} s_"I_TEXMATRICES";\n\n"
|
"typedef struct { float4 T0,T1,T2,T3; } s_"I_PROJECTION";\n"
|
||||||
"typedef struct {\n"
|
"typedef struct { float4 params; } s_"I_FOGPARAMS";\n"); // a, b, c, b_shift
|
||||||
" FLT4 T[64];\n"
|
|
||||||
"} s_"I_TRANSFORMMATRICES";\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" FLT4 T[32];\n"
|
|
||||||
"} s_"I_NORMALMATRICES";\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" FLT4 T[64];\n"
|
|
||||||
"} s_"I_POSTTRANSFORMMATRICES";\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" float4 col;\n"
|
|
||||||
" float4 cosatt;\n"
|
|
||||||
" float4 distatt;\n"
|
|
||||||
" float4 pos;\n"
|
|
||||||
" float4 dir;\n"
|
|
||||||
"} Light;\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" Light lights[8];\n"
|
|
||||||
"} s_"I_LIGHTS";\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" float4 C0, C1, C2, C3;\n"
|
|
||||||
"} s_"I_MATERIALS";\n\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" float4 T0,T1,T2,T3;\n"
|
|
||||||
"} s_"I_PROJECTION";\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" float4 params;\n" // a, b, c, b_shift
|
|
||||||
"} s_"I_FOGPARAMS";\n\n");
|
|
||||||
|
|
||||||
WRITE(p, "struct VS_OUTPUT {\n");
|
WRITE(p, "struct VS_OUTPUT {\n");
|
||||||
WRITE(p, " float4 pos : POSITION;\n");
|
WRITE(p, " float4 pos : POSITION;\n");
|
||||||
|
@ -143,13 +116,10 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
||||||
// clip position is in w of first 4 texcoords
|
// clip position is in w of first 4 texcoords
|
||||||
for (int i = 0; i < xfregs.numTexGens; ++i)
|
for (int i = 0; i < xfregs.numTexGens; ++i)
|
||||||
WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i<4?4:3, i, i);
|
WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i<4?4:3, i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE(p, "};\n");
|
WRITE(p, "};\n");
|
||||||
WRITE(p, "\n");
|
|
||||||
|
|
||||||
// uniforms
|
// uniforms
|
||||||
|
|
||||||
// bool bTexMtx = ((components & VB_HAS_TEXMTXIDXALL)<<VB_HAS_UVTEXMTXSHIFT)!=0; unused TODO: keep?
|
// bool bTexMtx = ((components & VB_HAS_TEXMTXIDXALL)<<VB_HAS_UVTEXMTXSHIFT)!=0; unused TODO: keep?
|
||||||
|
|
||||||
WRITE(p, "uniform s_"I_TRANSFORMMATRICES" "I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES);
|
WRITE(p, "uniform s_"I_TRANSFORMMATRICES" "I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES);
|
||||||
|
@ -201,8 +171,8 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
||||||
if (components & VB_HAS_POSMTXIDX) {
|
if (components & VB_HAS_POSMTXIDX) {
|
||||||
if (D3D)
|
if (D3D)
|
||||||
{
|
{
|
||||||
WRITE(p,"int4 indices = D3DCOLORtoUBYTE4(blend_indices);\n"
|
WRITE(p, "int4 indices = D3DCOLORtoUBYTE4(blend_indices);\n"
|
||||||
"int posmtx = indices.x;\n");
|
"int posmtx = indices.x;\n");
|
||||||
}
|
}
|
||||||
WRITE(p, "float4 pos = float4(dot("I_TRANSFORMMATRICES".T[posmtx].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+1].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+2].t, rawpos),1);\n");
|
WRITE(p, "float4 pos = float4(dot("I_TRANSFORMMATRICES".T[posmtx].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+1].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+2].t, rawpos),1);\n");
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt)
|
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt)
|
||||||
{
|
{
|
||||||
u32* pBuffer = (u32*)buffer;
|
u32* pBuffer = (u32*)buffer;
|
||||||
LPDIRECT3DTEXTURE9 pTexture;
|
LPDIRECT3DTEXTURE9 pTexture;
|
||||||
|
@ -30,7 +30,7 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
|
||||||
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
||||||
bool bExpand = false;
|
bool bExpand = false;
|
||||||
|
|
||||||
if(fmt == D3DFMT_A8P8) {
|
if (fmt == D3DFMT_A8P8) {
|
||||||
fmt = D3DFMT_A8L8;
|
fmt = D3DFMT_A8L8;
|
||||||
bExpand = true;
|
bExpand = true;
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,16 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
|
||||||
case D3DFMT_L8:
|
case D3DFMT_L8:
|
||||||
case D3DFMT_A8:
|
case D3DFMT_A8:
|
||||||
case D3DFMT_A4L4:
|
case D3DFMT_A4L4:
|
||||||
{
|
|
||||||
const u8 *pIn = buffer;
|
|
||||||
for (int y = 0; y < height; y++)
|
|
||||||
{
|
{
|
||||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
const u8 *pIn = buffer;
|
||||||
memcpy(pBits, pIn, width);
|
for (int y = 0; y < height; y++)
|
||||||
pIn += pitch;
|
{
|
||||||
|
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
|
memcpy(pBits, pIn, width);
|
||||||
|
pIn += pitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
case D3DFMT_R5G6B5:
|
case D3DFMT_R5G6B5:
|
||||||
{
|
{
|
||||||
const u16 *pIn = (u16*)buffer;
|
const u16 *pIn = (u16*)buffer;
|
||||||
|
@ -78,9 +78,8 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
|
||||||
break;
|
break;
|
||||||
case D3DFMT_A8L8:
|
case D3DFMT_A8L8:
|
||||||
{
|
{
|
||||||
if(bExpand) { // I8
|
if (bExpand) { // I8
|
||||||
const u8 *pIn = buffer;
|
const u8 *pIn = buffer;
|
||||||
|
|
||||||
// TODO(XK): Find a better way that does not involve either unpacking
|
// TODO(XK): Find a better way that does not involve either unpacking
|
||||||
// or downsampling (i.e. A4L4)
|
// or downsampling (i.e. A4L4)
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
|
@ -118,6 +117,8 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
|
||||||
case D3DFMT_DXT1:
|
case D3DFMT_DXT1:
|
||||||
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
|
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
PanicAlert("D3D: Invalid texture format %i", fmt);
|
||||||
}
|
}
|
||||||
pTexture->UnlockRect(level);
|
pTexture->UnlockRect(level);
|
||||||
return pTexture;
|
return pTexture;
|
||||||
|
@ -128,7 +129,7 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w
|
||||||
u32* pBuffer = (u32*)buffer;
|
u32* pBuffer = (u32*)buffer;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
D3DLOCKED_RECT Lock;
|
D3DLOCKED_RECT Lock;
|
||||||
pTexture->LockRect(level, &Lock, NULL, 0 );
|
pTexture->LockRect(level, &Lock, NULL, 0);
|
||||||
u32* pIn = pBuffer;
|
u32* pIn = pBuffer;
|
||||||
switch(fmt)
|
switch(fmt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -215,9 +215,8 @@ namespace D3D
|
||||||
|
|
||||||
dev->SetPixelShader(0);
|
dev->SetPixelShader(0);
|
||||||
dev->SetVertexShader(0);
|
dev->SetVertexShader(0);
|
||||||
dev->SetVertexDeclaration(0);
|
// dev->SetVertexDeclaration(0);
|
||||||
|
|
||||||
// dev->SetFVF(D3DFVF_FONT2DVERTEX);
|
|
||||||
Renderer::SetFVF(D3DFVF_FONT2DVERTEX);
|
Renderer::SetFVF(D3DFVF_FONT2DVERTEX);
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
|
@ -380,9 +379,8 @@ namespace D3D
|
||||||
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
||||||
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
||||||
};
|
};
|
||||||
dev->SetPixelShader(0);
|
dev->SetPixelShader(NULL);
|
||||||
dev->SetVertexShader(0);
|
dev->SetVertexShader(NULL);
|
||||||
dev->SetVertexDeclaration(0);
|
|
||||||
|
|
||||||
Renderer::SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
Renderer::SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
||||||
|
|
|
@ -163,5 +163,8 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
|
|
||||||
void D3DVertexFormat::SetupVertexPointers() const
|
void D3DVertexFormat::SetupVertexPointers() const
|
||||||
{
|
{
|
||||||
D3D::dev->SetVertexDeclaration(d3d_decl);
|
if (d3d_decl)
|
||||||
|
D3D::dev->SetVertexDeclaration(d3d_decl);
|
||||||
|
else
|
||||||
|
ERROR_LOG(VIDEO, "invalid d3d decl");
|
||||||
}
|
}
|
|
@ -32,6 +32,7 @@
|
||||||
#include <Cg/cgD3D9.h>
|
#include <Cg/cgD3D9.h>
|
||||||
|
|
||||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||||
|
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
||||||
|
|
||||||
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
|
@ -59,10 +60,7 @@ void PixelShaderCache::Shutdown()
|
||||||
|
|
||||||
void PixelShaderCache::SetShader()
|
void PixelShaderCache::SetShader()
|
||||||
{
|
{
|
||||||
if (D3D::GetShaderVersion() < 2)
|
static LPDIRECT3DPIXELSHADER9 last_shader = NULL;
|
||||||
return; // we are screwed
|
|
||||||
|
|
||||||
static LPDIRECT3DPIXELSHADER9 lastShader = NULL;
|
|
||||||
|
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
|
@ -75,11 +73,12 @@ void PixelShaderCache::SetShader()
|
||||||
if (iter != PixelShaders.end())
|
if (iter != PixelShaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
PSCacheEntry &entry = iter->second;
|
const PSCacheEntry &entry = iter->second;
|
||||||
if (!lastShader || entry.shader != lastShader)
|
last_entry = &entry;
|
||||||
|
if (!last_shader || entry.shader != last_shader)
|
||||||
{
|
{
|
||||||
D3D::dev->SetPixelShader(entry.shader);
|
D3D::dev->SetPixelShader(entry.shader);
|
||||||
lastShader = entry.shader;
|
last_shader = entry.shader;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -93,10 +92,15 @@ void PixelShaderCache::SetShader()
|
||||||
PSCacheEntry newentry;
|
PSCacheEntry newentry;
|
||||||
newentry.shader = shader;
|
newentry.shader = shader;
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
newentry.code = code;
|
||||||
|
#endif
|
||||||
PixelShaders[uid] = newentry;
|
PixelShaders[uid] = newentry;
|
||||||
|
last_entry = &PixelShaders[uid];
|
||||||
|
|
||||||
Renderer::SetFVF(NULL);
|
Renderer::SetFVF(NULL);
|
||||||
D3D::dev->SetPixelShader(shader);
|
D3D::dev->SetPixelShader(shader);
|
||||||
|
last_shader = shader;
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
||||||
|
@ -134,7 +138,7 @@ void PixelShaderCache::Cleanup()
|
||||||
while (iter != PixelShaders.end())
|
while (iter != PixelShaders.end())
|
||||||
{
|
{
|
||||||
PSCacheEntry &entry = iter->second;
|
PSCacheEntry &entry = iter->second;
|
||||||
if (entry.frameCount < frameCount-400)
|
if (entry.frameCount < frameCount - 400)
|
||||||
{
|
{
|
||||||
entry.Destroy();
|
entry.Destroy();
|
||||||
iter = PixelShaders.erase(iter);
|
iter = PixelShaders.erase(iter);
|
||||||
|
@ -145,4 +149,14 @@ void PixelShaderCache::Cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::string PixelShaderCache::GetCurrentShaderCode()
|
||||||
|
{
|
||||||
|
if (last_entry)
|
||||||
|
return last_entry->code;
|
||||||
|
else
|
||||||
|
return "(no shader)\n";
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -31,11 +31,14 @@ tevhash GetCurrentTEV();
|
||||||
|
|
||||||
class PixelShaderCache
|
class PixelShaderCache
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
{
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 shader;
|
LPDIRECT3DPIXELSHADER9 shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::string code;
|
||||||
|
#endif
|
||||||
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
|
@ -47,12 +50,16 @@ class PixelShaderCache
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
||||||
static PSCache PixelShaders;
|
static PSCache PixelShaders;
|
||||||
|
static const PSCacheEntry *last_entry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void SetShader();
|
static void SetShader();
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static std::string GetCurrentShaderCode();
|
||||||
|
#endif
|
||||||
static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram);
|
static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
|
||||||
|
@ -81,6 +82,8 @@ bool Init()
|
||||||
collection = C_NOTHING;
|
collection = C_NOTHING;
|
||||||
fakeVBuffer = new u8[MAXVBUFFERSIZE];
|
fakeVBuffer = new u8[MAXVBUFFERSIZE];
|
||||||
fakeIBuffer = new u16[MAXIBUFFERSIZE];
|
fakeIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
|
memset(fakeVBuffer, 0, MAXVBUFFERSIZE);
|
||||||
|
memset(fakeIBuffer, 0, MAXIBUFFERSIZE * 2);
|
||||||
CreateDeviceObjects();
|
CreateDeviceObjects();
|
||||||
VertexManager::s_pCurBufferPointer = fakeVBuffer;
|
VertexManager::s_pCurBufferPointer = fakeVBuffer;
|
||||||
return true;
|
return true;
|
||||||
|
@ -143,9 +146,6 @@ void AddVertices(int _primitive, int _numVertices)
|
||||||
//We are NOT collecting the right type.
|
//We are NOT collecting the right type.
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
// Copy the extra verts that we lost.
|
|
||||||
memcpy(s_pCurBufferPointer, fakeVBuffer, _numVertices * g_nativeVertexFmt->GetVertexStride());
|
|
||||||
|
|
||||||
collection = type;
|
collection = type;
|
||||||
u16 *ptr = 0;
|
u16 *ptr = 0;
|
||||||
if (type != C_POINTS)
|
if (type != C_POINTS)
|
||||||
|
@ -247,14 +247,23 @@ void Flush()
|
||||||
if (collection != C_POINTS)
|
if (collection != C_POINTS)
|
||||||
{
|
{
|
||||||
int numPrimitives = indexGen.GetNumPrims();
|
int numPrimitives = indexGen.GetNumPrims();
|
||||||
D3D::dev->DrawIndexedPrimitiveUP(pts[(int)collection],
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
0,
|
pts[(int)collection],
|
||||||
numVertices,
|
0,
|
||||||
numPrimitives,
|
numVertices,
|
||||||
fakeIBuffer,
|
numPrimitives,
|
||||||
D3DFMT_INDEX16,
|
fakeIBuffer,
|
||||||
fakeVBuffer,
|
D3DFMT_INDEX16,
|
||||||
stride);
|
fakeVBuffer,
|
||||||
|
stride))) {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::string error_shaders;
|
||||||
|
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
|
||||||
|
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
|
||||||
|
File::WriteStringToFile(true, error_shaders, "bad_shader_combo.txt");
|
||||||
|
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to shaders.txt.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <Cg/cgD3D9.h>
|
#include <Cg/cgD3D9.h>
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
|
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||||
|
|
||||||
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +50,6 @@ void VertexShaderCache::Init()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VertexShaderCache::Shutdown()
|
void VertexShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
VSCache::iterator iter = vshaders.begin();
|
VSCache::iterator iter = vshaders.begin();
|
||||||
|
@ -61,10 +61,7 @@ void VertexShaderCache::Shutdown()
|
||||||
|
|
||||||
void VertexShaderCache::SetShader(u32 components)
|
void VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
if (D3D::GetShaderVersion() < 2)
|
static LPDIRECT3DVERTEXSHADER9 last_shader = NULL;
|
||||||
return; // we are screwed
|
|
||||||
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 lastShader = NULL;
|
|
||||||
|
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
|
@ -76,11 +73,12 @@ void VertexShaderCache::SetShader(u32 components)
|
||||||
if (iter != vshaders.end())
|
if (iter != vshaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
VSCacheEntry &entry = iter->second;
|
const VSCacheEntry &entry = iter->second;
|
||||||
if (!lastShader || entry.shader != lastShader)
|
last_entry = &entry;
|
||||||
|
if (!last_shader || entry.shader != last_shader)
|
||||||
{
|
{
|
||||||
D3D::dev->SetVertexShader(entry.shader);
|
D3D::dev->SetVertexShader(entry.shader);
|
||||||
lastShader = entry.shader;
|
last_shader = entry.shader;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +92,12 @@ void VertexShaderCache::SetShader(u32 components)
|
||||||
VSCacheEntry entry;
|
VSCacheEntry entry;
|
||||||
entry.shader = shader;
|
entry.shader = shader;
|
||||||
entry.frameCount = frameCount;
|
entry.frameCount = frameCount;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
entry.code = code;
|
||||||
|
#endif
|
||||||
vshaders[uid] = entry;
|
vshaders[uid] = entry;
|
||||||
|
last_entry = &vshaders[uid];
|
||||||
|
last_shader = entry.shader;
|
||||||
|
|
||||||
D3D::dev->SetVertexShader(shader);
|
D3D::dev->SetVertexShader(shader);
|
||||||
|
|
||||||
|
@ -145,4 +148,14 @@ void VertexShaderCache::Cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::string VertexShaderCache::GetCurrentShaderCode()
|
||||||
|
{
|
||||||
|
if (last_entry)
|
||||||
|
return last_entry->code;
|
||||||
|
else
|
||||||
|
return "(no shader)\n";
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -21,16 +21,21 @@
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
class VertexShaderCache
|
class VertexShaderCache
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
struct VSCacheEntry
|
struct VSCacheEntry
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 shader;
|
LPDIRECT3DVERTEXSHADER9 shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::string code;
|
||||||
|
#endif
|
||||||
VSCacheEntry() : shader(NULL), frameCount(0) {}
|
VSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
|
@ -42,12 +47,16 @@ class VertexShaderCache
|
||||||
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
||||||
|
|
||||||
static VSCache vshaders;
|
static VSCache vshaders;
|
||||||
|
static const VSCacheEntry *last_entry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void SetShader(u32 components);
|
static void SetShader(u32 components);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static std::string GetCurrentShaderCode();
|
||||||
|
#endif
|
||||||
static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram);
|
static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue