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:
hrydgard
2009-09-01 19:48:45 +00:00
parent b15320bc02
commit 2599659022
12 changed files with 151 additions and 127 deletions

View File

@ -21,7 +21,7 @@
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;
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 bExpand = false;
if(fmt == D3DFMT_A8P8) {
if (fmt == D3DFMT_A8P8) {
fmt = D3DFMT_A8L8;
bExpand = true;
}
@ -55,16 +55,16 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
case D3DFMT_L8:
case D3DFMT_A8:
case D3DFMT_A4L4:
{
const u8 *pIn = buffer;
for (int y = 0; y < height; y++)
{
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
memcpy(pBits, pIn, width);
pIn += pitch;
const u8 *pIn = buffer;
for (int y = 0; y < height; y++)
{
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
memcpy(pBits, pIn, width);
pIn += pitch;
}
}
}
break;
break;
case D3DFMT_R5G6B5:
{
const u16 *pIn = (u16*)buffer;
@ -78,9 +78,8 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
break;
case D3DFMT_A8L8:
{
if(bExpand) { // I8
if (bExpand) { // I8
const u8 *pIn = buffer;
// TODO(XK): Find a better way that does not involve either unpacking
// or downsampling (i.e. A4L4)
for (int y = 0; y < height; y++)
@ -118,6 +117,8 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
case D3DFMT_DXT1:
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
break;
default:
PanicAlert("D3D: Invalid texture format %i", fmt);
}
pTexture->UnlockRect(level);
return pTexture;
@ -128,7 +129,7 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w
u32* pBuffer = (u32*)buffer;
int level = 0;
D3DLOCKED_RECT Lock;
pTexture->LockRect(level, &Lock, NULL, 0 );
pTexture->LockRect(level, &Lock, NULL, 0);
u32* pIn = pBuffer;
switch(fmt)
{

View File

@ -215,9 +215,8 @@ namespace D3D
dev->SetPixelShader(0);
dev->SetVertexShader(0);
dev->SetVertexDeclaration(0);
// dev->SetVertexDeclaration(0);
// dev->SetFVF(D3DFVF_FONT2DVERTEX);
Renderer::SetFVF(D3DFVF_FONT2DVERTEX);
for (int i = 0; i < 6; i++) {
@ -380,9 +379,8 @@ namespace D3D
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
};
dev->SetPixelShader(0);
dev->SetVertexShader(0);
dev->SetVertexDeclaration(0);
dev->SetPixelShader(NULL);
dev->SetVertexShader(NULL);
Renderer::SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));

View File

@ -163,5 +163,8 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
void D3DVertexFormat::SetupVertexPointers() const
{
D3D::dev->SetVertexDeclaration(d3d_decl);
if (d3d_decl)
D3D::dev->SetVertexDeclaration(d3d_decl);
else
ERROR_LOG(VIDEO, "invalid d3d decl");
}

View File

@ -32,6 +32,7 @@
#include <Cg/cgD3D9.h>
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
@ -59,10 +60,7 @@ void PixelShaderCache::Shutdown()
void PixelShaderCache::SetShader()
{
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
static LPDIRECT3DPIXELSHADER9 lastShader = NULL;
static LPDIRECT3DPIXELSHADER9 last_shader = NULL;
DVSTARTPROFILE();
@ -75,11 +73,12 @@ void PixelShaderCache::SetShader()
if (iter != PixelShaders.end())
{
iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
const PSCacheEntry &entry = iter->second;
last_entry = &entry;
if (!last_shader || entry.shader != last_shader)
{
D3D::dev->SetPixelShader(entry.shader);
lastShader = entry.shader;
last_shader = entry.shader;
}
return;
}
@ -93,10 +92,15 @@ void PixelShaderCache::SetShader()
PSCacheEntry newentry;
newentry.shader = shader;
newentry.frameCount = frameCount;
#ifdef _DEBUG
newentry.code = code;
#endif
PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid];
Renderer::SetFVF(NULL);
D3D::dev->SetPixelShader(shader);
last_shader = shader;
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
@ -134,7 +138,7 @@ void PixelShaderCache::Cleanup()
while (iter != PixelShaders.end())
{
PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount-400)
if (entry.frameCount < frameCount - 400)
{
entry.Destroy();
iter = PixelShaders.erase(iter);
@ -145,4 +149,14 @@ void PixelShaderCache::Cleanup()
}
}
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

View File

@ -31,11 +31,14 @@ tevhash GetCurrentTEV();
class PixelShaderCache
{
private:
struct PSCacheEntry
{
LPDIRECT3DPIXELSHADER9 shader;
int frameCount;
#ifdef _DEBUG
std::string code;
#endif
PSCacheEntry() : shader(NULL), frameCount(0) {}
void Destroy()
{
@ -47,12 +50,16 @@ class PixelShaderCache
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
static PSCache PixelShaders;
static const PSCacheEntry *last_entry;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
#ifdef _DEBUG
static std::string GetCurrentShaderCode();
#endif
static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram);
};

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "FileUtil.h"
#include "D3DBase.h"
@ -81,6 +82,8 @@ bool Init()
collection = C_NOTHING;
fakeVBuffer = new u8[MAXVBUFFERSIZE];
fakeIBuffer = new u16[MAXIBUFFERSIZE];
memset(fakeVBuffer, 0, MAXVBUFFERSIZE);
memset(fakeIBuffer, 0, MAXIBUFFERSIZE * 2);
CreateDeviceObjects();
VertexManager::s_pCurBufferPointer = fakeVBuffer;
return true;
@ -143,9 +146,6 @@ void AddVertices(int _primitive, int _numVertices)
//We are NOT collecting the right type.
Flush();
// Copy the extra verts that we lost.
memcpy(s_pCurBufferPointer, fakeVBuffer, _numVertices * g_nativeVertexFmt->GetVertexStride());
collection = type;
u16 *ptr = 0;
if (type != C_POINTS)
@ -247,14 +247,23 @@ void Flush()
if (collection != C_POINTS)
{
int numPrimitives = indexGen.GetNumPrims();
D3D::dev->DrawIndexedPrimitiveUP(pts[(int)collection],
0,
numVertices,
numPrimitives,
fakeIBuffer,
D3DFMT_INDEX16,
fakeVBuffer,
stride);
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
pts[(int)collection],
0,
numVertices,
numPrimitives,
fakeIBuffer,
D3DFMT_INDEX16,
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
{

View File

@ -32,6 +32,7 @@
#include <Cg/cgD3D9.h>
VertexShaderCache::VSCache VertexShaderCache::vshaders;
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
@ -49,7 +50,6 @@ void VertexShaderCache::Init()
}
void VertexShaderCache::Shutdown()
{
VSCache::iterator iter = vshaders.begin();
@ -61,10 +61,7 @@ void VertexShaderCache::Shutdown()
void VertexShaderCache::SetShader(u32 components)
{
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
static LPDIRECT3DVERTEXSHADER9 lastShader = NULL;
static LPDIRECT3DVERTEXSHADER9 last_shader = NULL;
DVSTARTPROFILE();
@ -76,11 +73,12 @@ void VertexShaderCache::SetShader(u32 components)
if (iter != vshaders.end())
{
iter->second.frameCount = frameCount;
VSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
const VSCacheEntry &entry = iter->second;
last_entry = &entry;
if (!last_shader || entry.shader != last_shader)
{
D3D::dev->SetVertexShader(entry.shader);
lastShader = entry.shader;
last_shader = entry.shader;
}
return;
}
@ -94,7 +92,12 @@ void VertexShaderCache::SetShader(u32 components)
VSCacheEntry entry;
entry.shader = shader;
entry.frameCount = frameCount;
#ifdef _DEBUG
entry.code = code;
#endif
vshaders[uid] = entry;
last_entry = &vshaders[uid];
last_shader = entry.shader;
D3D::dev->SetVertexShader(shader);
@ -145,4 +148,14 @@ void VertexShaderCache::Cleanup()
}
}
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

View File

@ -21,16 +21,21 @@
#include "D3DBase.h"
#include <map>
#include <string>
#include "D3DBase.h"
#include "VertexShaderGen.h"
class VertexShaderCache
{
private:
struct VSCacheEntry
{
LPDIRECT3DVERTEXSHADER9 shader;
int frameCount;
#ifdef _DEBUG
std::string code;
#endif
VSCacheEntry() : shader(NULL), frameCount(0) {}
void Destroy()
{
@ -42,12 +47,16 @@ class VertexShaderCache
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
static VSCache vshaders;
static const VSCacheEntry *last_entry;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader(u32 components);
#ifdef _DEBUG
static std::string GetCurrentShaderCode();
#endif
static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram);
};