mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 15:49:50 -06:00
D3D various: "Safe texture cache" option, texture replace instead of destroy/create when possible, a commented out "optimization" that didn't speed things up (use DrawPrimitive instead of DrawIndexedPrimitive when possible), reduce code duplication in Flush(), don't periodically clean out the shader caches since it's not really beneficial - shaders are cheap to keep. some code cleanup.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4302 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -129,6 +129,13 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w
|
||||
D3DLOCKED_RECT Lock;
|
||||
pTexture->LockRect(level, &Lock, NULL, 0);
|
||||
u32* pIn = pBuffer;
|
||||
|
||||
bool bExpand = false;
|
||||
|
||||
if (fmt == D3DFMT_A8P8) {
|
||||
fmt = D3DFMT_A8L8;
|
||||
bExpand = true;
|
||||
}
|
||||
switch(fmt)
|
||||
{
|
||||
case D3DFMT_A8R8G8B8:
|
||||
@ -141,8 +148,59 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case D3DFMT_R5G6B5:
|
||||
{
|
||||
const u16 *pIn = (u16*)buffer;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||
memcpy(pBits, pIn, width * 2);
|
||||
pIn += pitch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case D3DFMT_A8L8:
|
||||
{
|
||||
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++)
|
||||
{
|
||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||
for(int i = 0; i < width * 2; i += 2) {
|
||||
pBits[i] = pIn[i / 2];
|
||||
pBits[i + 1] = pIn[i / 2];
|
||||
}
|
||||
pIn += pitch;
|
||||
}
|
||||
} else { // IA8
|
||||
const u16 *pIn = (u16*)buffer;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||
memcpy(pBits, pIn, width * 2);
|
||||
pIn += pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case D3DFMT_DXT1:
|
||||
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
|
||||
memcpy(Lock.pBits, buffer, (width/4) * (height/4) * 8);
|
||||
break;
|
||||
}
|
||||
pTexture->UnlockRect(level);
|
||||
|
@ -92,6 +92,7 @@ struct TabDirect3D : public W32Util::Tab
|
||||
CheckDlgButton(hDlg, IDC_ASPECT_16_9, g_Config.bKeepAR169 ? TRUE : FALSE);
|
||||
CheckDlgButton(hDlg, IDC_ASPECT_4_3, g_Config.bKeepAR43 ? TRUE : FALSE);
|
||||
CheckDlgButton(hDlg, IDC_WIDESCREEN_HACK, g_Config.bWidescreenHack ? TRUE : FALSE);
|
||||
CheckDlgButton(hDlg, IDC_SAFE_TEXTURE_CACHE, g_Config.bSafeTextureCache ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void Command(HWND hDlg,WPARAM wParam)
|
||||
@ -114,6 +115,9 @@ struct TabDirect3D : public W32Util::Tab
|
||||
case IDC_WIREFRAME:
|
||||
g_Config.bWireFrame = Button_GetCheck(GetDlgItem(hDlg,IDC_WIREFRAME)) ? true : false;
|
||||
break;
|
||||
case IDC_SAFE_TEXTURE_CACHE:
|
||||
g_Config.bSafeTextureCache = Button_GetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha)
|
||||
|
||||
void PixelShaderCache::Cleanup()
|
||||
{
|
||||
/*
|
||||
PSCache::iterator iter;
|
||||
iter = PixelShaders.begin();
|
||||
while (iter != PixelShaders.end())
|
||||
@ -167,6 +168,7 @@ void PixelShaderCache::Cleanup()
|
||||
}
|
||||
}
|
||||
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
||||
*/
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
|
@ -49,7 +49,7 @@ void TextureCache::TCacheEntry::Destroy(bool shutdown)
|
||||
if (texture)
|
||||
texture->Release();
|
||||
texture = 0;
|
||||
if (!isRenderTarget && !shutdown)
|
||||
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
|
||||
{
|
||||
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
|
||||
if (ptr && *ptr == hash)
|
||||
@ -103,88 +103,78 @@ void TextureCache::Cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt)
|
||||
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt)
|
||||
{
|
||||
if (address == 0)
|
||||
return NULL;
|
||||
|
||||
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
||||
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
|
||||
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
|
||||
int expandedWidth = (width + bsw) & (~bsw);
|
||||
int expandedHeight = (height + bsh) & (~bsh);
|
||||
|
||||
int palSize = TexDecoder_GetPaletteSize(format);
|
||||
u32 palhash = 0xc0debabe;
|
||||
if (palSize)
|
||||
u32 hash_value;
|
||||
u32 texID = address;
|
||||
u32 texHash;
|
||||
|
||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bDumpTextures)
|
||||
{
|
||||
// TODO: Share this code with the GL plugin.
|
||||
if (palSize > 32)
|
||||
palSize = 32; //let's not do excessive amount of checking
|
||||
u8 *pal = g_VideoInitialize.pGetMemoryPointer(tlutaddr);
|
||||
if (pal != 0)
|
||||
texHash = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, expandedHeight, tex_format, 0);
|
||||
if (g_ActiveConfig.bSafeTextureCache)
|
||||
hash_value = texHash;
|
||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||
{
|
||||
for (int i = 0; i < palSize; i++)
|
||||
{
|
||||
palhash = _rotl(palhash,13);
|
||||
palhash ^= pal[i];
|
||||
palhash += 31;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LPDIRECT3DTEXTURE9 lastTexture[8] = {0,0,0,0,0,0,0,0};
|
||||
|
||||
int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16;
|
||||
int expandedWidth = (width+bs) & (~bs);
|
||||
u32 hash_value = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, height, format, 0);
|
||||
u32 tex_hash = 0;
|
||||
u32 texID = address;
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures || g_ActiveConfig.bSafeTextureCache)
|
||||
{
|
||||
tex_hash = hash_value;
|
||||
if ((format == GX_TF_C4) || (format == GX_TF_C8) || (format == GX_TF_C14X2))
|
||||
{
|
||||
u32 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], (format == GX_TF_C4) ? 32 : 128);
|
||||
tex_hash ^= tlutHash;
|
||||
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
||||
// tlut size can be up to 32768B (GX_TF_C14X2) but Safer == Slower.
|
||||
// This trick (to change the texID depending on the TLUT addr) is a trick to get around
|
||||
// an issue with metroid prime's fonts, where it has multiple sets of fonts on top of
|
||||
// each other stored in a single texture, and uses the palette to make different characters
|
||||
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
||||
// we must make sure that texture with different tluts get different IDs.
|
||||
u32 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], (tex_format == GX_TF_C4) ? 32 : 128);
|
||||
texHash ^= tlutHash;
|
||||
if (g_ActiveConfig.bSafeTextureCache)
|
||||
texID ^= tlutHash;
|
||||
}
|
||||
}
|
||||
|
||||
bool skip_texture_create = false;
|
||||
TexCache::iterator iter = textures.find(texID);
|
||||
|
||||
if (iter != textures.end())
|
||||
{
|
||||
TCacheEntry &entry = iter->second;
|
||||
|
||||
if (!g_ActiveConfig.bSafeTextureCache)
|
||||
hash_value = ((u32 *)ptr)[0];
|
||||
|
||||
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash)))
|
||||
{
|
||||
entry.frameCount = frameCount;
|
||||
if (lastTexture[stage] == entry.texture)
|
||||
{
|
||||
return &entry;
|
||||
}
|
||||
lastTexture[stage] = entry.texture;
|
||||
D3D::SetTexture(stage, entry.texture);
|
||||
return &entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if (width == iter->second.w && height==entry.h && format==entry.fmt)
|
||||
// Let's reload the new texture data into the same texture,
|
||||
// instead of destroying it and having to create a new one.
|
||||
// Might speed up movie playback very, very slightly.
|
||||
|
||||
if (width == entry.w && height==entry.h && tex_format == entry.fmt)
|
||||
{
|
||||
LPDIRECT3DTEXTURE9 tex = entry.texture;
|
||||
int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16;
|
||||
int expandedWidth = (width+bs) & (~bs);
|
||||
D3DFORMAT dfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt);
|
||||
D3D::ReplaceTexture2D(tex,temp,width,height,expandedWidth,dfmt);
|
||||
D3D::dev->SetTexture(stage,tex);
|
||||
return;
|
||||
skip_texture_create = true;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
{
|
||||
entry.Destroy(false);
|
||||
textures.erase(iter);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PC_TexFormat pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, height, format, tlutaddr, tlutfmt);
|
||||
PC_TexFormat pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, height, tex_format, tlutaddr, tlutfmt);
|
||||
|
||||
D3DFORMAT d3d_fmt;
|
||||
switch (pcfmt) {
|
||||
case PC_TEX_FMT_BGRA32:
|
||||
@ -213,23 +203,32 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||
//Make an entry in the table
|
||||
TCacheEntry& entry = textures[texID];
|
||||
|
||||
entry.hash = hash_value;
|
||||
//entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF);
|
||||
entry.paletteHash = palhash;
|
||||
entry.oldpixel = ((u32 *)ptr)[0];
|
||||
//((u32 *)ptr)[entry.hashoffset] = entry.hash;
|
||||
if (g_ActiveConfig.bSafeTextureCache)
|
||||
entry.hash = hash_value;
|
||||
else
|
||||
{
|
||||
entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF);
|
||||
((u32 *)ptr)[0] = entry.hash;
|
||||
}
|
||||
|
||||
entry.addr = address;
|
||||
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format);
|
||||
entry.isRenderTarget = false;
|
||||
entry.isNonPow2 = ((width & (width - 1)) || (height & (height - 1)));
|
||||
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt);
|
||||
if (!skip_texture_create) {
|
||||
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt);
|
||||
} else {
|
||||
D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt);
|
||||
}
|
||||
entry.frameCount = frameCount;
|
||||
entry.w = width;
|
||||
entry.h = height;
|
||||
entry.fmt = format;
|
||||
entry.fmt = tex_format;
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures)
|
||||
{ // dump texture to file
|
||||
{
|
||||
// dump texture to file
|
||||
char szTemp[MAX_PATH];
|
||||
char szDir[MAX_PATH];
|
||||
const char* uniqueId = globals->unique_id;
|
||||
@ -242,7 +241,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||
|
||||
bCheckedDumpDir = true;
|
||||
}
|
||||
sprintf(szTemp, "%s/%s_%08x_%i.png", szDir, uniqueId, tex_hash, format);
|
||||
sprintf(szTemp, "%s/%s_%08x_%i.png", szDir, uniqueId, texHash, tex_format);
|
||||
//sprintf(szTemp, "%s\\txt_%04i_%i.png", g_Config.texDumpPath.c_str(), counter++, format); <-- Old method
|
||||
if (!File::Exists(szTemp))
|
||||
D3DXSaveTextureToFileA(szTemp,D3DXIFF_BMP,entry.texture,0);
|
||||
@ -254,8 +253,6 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||
//Set the texture!
|
||||
D3D::SetTexture(stage, entry.texture);
|
||||
|
||||
lastTexture[stage] = entry.texture;
|
||||
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_NEW_TEXTURE,true,{printf("A new texture (%d x %d) is loaded", width, height);});
|
||||
return &entry;
|
||||
}
|
||||
|
@ -56,9 +56,18 @@ enum Collection
|
||||
C_POINTS,
|
||||
};
|
||||
|
||||
const D3DPRIMITIVETYPE pts[3] =
|
||||
{
|
||||
D3DPT_POINTLIST, //DUMMY
|
||||
D3DPT_TRIANGLELIST,
|
||||
D3DPT_LINELIST,
|
||||
};
|
||||
|
||||
static IndexGenerator indexGen;
|
||||
static Collection collection;
|
||||
|
||||
int lastPrimitive;
|
||||
|
||||
static u8 *fakeVBuffer; // format undefined - NativeVertexFormat takes care of the declaration.
|
||||
static u16 *fakeIBuffer; // These are just straightforward 16-bit indices.
|
||||
|
||||
@ -67,16 +76,29 @@ static u16 *fakeIBuffer; // These are just straightforward 16-bit indices.
|
||||
|
||||
const Collection collectionTypeLUT[8] =
|
||||
{
|
||||
C_TRIANGLES,//quads
|
||||
C_NOTHING, //nothing
|
||||
C_TRIANGLES,//triangles
|
||||
C_TRIANGLES,//strip
|
||||
C_TRIANGLES,//fan
|
||||
C_LINES, //lines
|
||||
C_LINES, //linestrip
|
||||
C_POINTS //guess :P
|
||||
C_TRIANGLES, //quads
|
||||
C_NOTHING, //nothing
|
||||
C_TRIANGLES, //triangles
|
||||
C_TRIANGLES, //strip
|
||||
C_TRIANGLES, //fan
|
||||
C_LINES, //lines
|
||||
C_LINES, //linestrip
|
||||
C_POINTS //guess :P
|
||||
};
|
||||
|
||||
const D3DPRIMITIVETYPE gxPrimToD3DPrim[8] = {
|
||||
(D3DPRIMITIVETYPE)0, // not supported
|
||||
(D3DPRIMITIVETYPE)0, // nothing
|
||||
|
||||
D3DPT_TRIANGLELIST,
|
||||
D3DPT_TRIANGLESTRIP,
|
||||
D3DPT_TRIANGLEFAN,
|
||||
|
||||
D3DPT_LINELIST,
|
||||
D3DPT_LINESTRIP,
|
||||
};
|
||||
|
||||
|
||||
void CreateDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
@ -116,7 +138,7 @@ void AddIndices(int _primitive, int _numVertices)
|
||||
case GX_DRAW_TRIANGLE_FAN: indexGen.AddFan(_numVertices); return;
|
||||
case GX_DRAW_LINE_STRIP: indexGen.AddLineStrip(_numVertices); return;
|
||||
case GX_DRAW_LINES: indexGen.AddLineList(_numVertices); return;
|
||||
case GX_DRAW_POINTS: indexGen.AddPointList(_numVertices); return;
|
||||
case GX_DRAW_POINTS: indexGen.AddPoints(_numVertices); return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +151,8 @@ void AddVertices(int _primitive, int _numVertices)
|
||||
{
|
||||
if (_numVertices <= 0) //This check is pretty stupid...
|
||||
return;
|
||||
|
||||
lastPrimitive = _primitive;
|
||||
|
||||
Collection type = collectionTypeLUT[_primitive];
|
||||
if (type == C_NOTHING)
|
||||
return;
|
||||
@ -166,12 +189,55 @@ void AddVertices(int _primitive, int _numVertices)
|
||||
}
|
||||
}
|
||||
|
||||
const D3DPRIMITIVETYPE pts[3] =
|
||||
inline void Draw(int numVertices, int stride)
|
||||
{
|
||||
D3DPT_POINTLIST, //DUMMY
|
||||
D3DPT_TRIANGLELIST,
|
||||
D3DPT_LINELIST,
|
||||
};
|
||||
if (collection != C_POINTS)
|
||||
{
|
||||
int numPrimitives = indexGen.GetNumPrims();
|
||||
/* For some reason, this makes things slower!
|
||||
if ((indexGen.GetNumAdds() == 1 || indexGen.GetOnlyLists()) && lastPrimitive != GX_DRAW_QUADS && gxPrimToD3DPrim[lastPrimitive])
|
||||
{
|
||||
if (FAILED(D3D::dev->DrawPrimitiveUP(
|
||||
gxPrimToD3DPrim[lastPrimitive],
|
||||
numPrimitives,
|
||||
fakeVBuffer,
|
||||
stride))) {
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
std::string error_shaders;
|
||||
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
|
||||
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
|
||||
File::WriteStringToFile(true, error_shaders, "bad_shader_combo.txt");
|
||||
PanicAlert("DrawPrimitiveUP failed. Shaders written to bad_shader_combo.txt.");
|
||||
#endif
|
||||
}
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
} else*/ {
|
||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||
pts[(int)collection],
|
||||
0, numVertices, numPrimitives,
|
||||
fakeIBuffer,
|
||||
D3DFMT_INDEX16,
|
||||
fakeVBuffer,
|
||||
stride))) {
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
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 bad_shader_combo.txt.");
|
||||
#endif
|
||||
}
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::dev->SetIndices(0);
|
||||
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
@ -219,73 +285,26 @@ void Flush()
|
||||
VertexShaderManager::SetConstants();
|
||||
PixelShaderManager::SetConstants();
|
||||
|
||||
if (!PixelShaderCache::SetShader(false))
|
||||
goto shader_fail;
|
||||
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
|
||||
goto shader_fail;
|
||||
if (!PixelShaderCache::SetShader(false))
|
||||
goto shader_fail;
|
||||
|
||||
int stride = g_nativeVertexFmt->GetVertexStride();
|
||||
g_nativeVertexFmt->SetupVertexPointers();
|
||||
if (collection != C_POINTS)
|
||||
{
|
||||
int numPrimitives = indexGen.GetNumPrims();
|
||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||
pts[(int)collection],
|
||||
0, numVertices, numPrimitives,
|
||||
fakeIBuffer,
|
||||
D3DFMT_INDEX16,
|
||||
fakeVBuffer,
|
||||
stride))) {
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
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 bad_shader_combo.txt.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::dev->SetIndices(0);
|
||||
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
|
||||
}
|
||||
|
||||
Draw(numVertices, stride);
|
||||
|
||||
if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||
{
|
||||
DWORD write = 0;
|
||||
if (!PixelShaderCache::SetShader(true))
|
||||
goto shader_fail;
|
||||
|
||||
// update alpha only
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
|
||||
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
|
||||
g_nativeVertexFmt->SetupVertexPointers();
|
||||
if (collection != C_POINTS)
|
||||
{
|
||||
int numPrimitives = indexGen.GetNumPrims();
|
||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||
pts[(int)collection],
|
||||
0, numVertices, numPrimitives,
|
||||
fakeIBuffer,
|
||||
D3DFMT_INDEX16,
|
||||
fakeVBuffer,
|
||||
stride))) {
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
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 (dstalpha). Shaders written to bad_shader_combo.txt.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::dev->SetIndices(0);
|
||||
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
|
||||
}
|
||||
Draw(numVertices, stride);
|
||||
|
||||
if (bpmem.blendmode.alphaupdate)
|
||||
write = D3DCOLORWRITEENABLE_ALPHA;
|
||||
@ -295,11 +314,7 @@ void Flush()
|
||||
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true);
|
||||
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, write);
|
||||
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
}
|
||||
|
||||
INCSTAT(stats.thisFrame.numDrawCalls);
|
||||
}
|
||||
shader_fail:
|
||||
collection = C_NOTHING;
|
||||
|
@ -203,6 +203,7 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||
|
||||
void VertexShaderCache::Cleanup()
|
||||
{
|
||||
/*
|
||||
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end();)
|
||||
{
|
||||
VSCacheEntry &entry = iter->second;
|
||||
@ -216,7 +217,8 @@ void VertexShaderCache::Cleanup()
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());*/
|
||||
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
|
@ -1224,6 +1224,8 @@
|
||||
#define IDC_WIDESCREEN_HACK 1036
|
||||
#define IDC_DUMPFRAMES 1037
|
||||
#define psh14 0x040d
|
||||
#define IDC_ASPECT_16_10 1037
|
||||
#define IDC_SAFE_TEXTURE_CACHE 1037
|
||||
#define psh15 0x040e
|
||||
#define psh16 0x040f
|
||||
#define _WIN32_WINDOWS 0x0410
|
||||
@ -1532,8 +1534,8 @@
|
||||
#define SPVERSION_MASK 0x0000FF00
|
||||
#define HTERROR -2
|
||||
#define IDC_STATIC -1
|
||||
#define PWR_FAIL -1
|
||||
#define UNICODE_NOCHAR 0xFFFF
|
||||
#define PWR_FAIL -1
|
||||
#define HTTRANSPARENT -1
|
||||
|
||||
// Next default values for new objects
|
||||
|
@ -2,15 +2,6 @@
|
||||
//
|
||||
#include "resource.h"
|
||||
#include <windows.h>
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
@ -36,7 +27,7 @@ BEGIN
|
||||
LTEXT "Will not work correctly on older GPU:s.",IDC_STATIC,7,47,170,8
|
||||
END
|
||||
|
||||
IDD_SETTINGS DIALOGEX 0, 0, 231, 174
|
||||
IDD_SETTINGS DIALOGEX 0, 0, 231, 194
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
@ -57,6 +48,7 @@ BEGIN
|
||||
CONTROL "4:3",IDC_ASPECT_4_3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,66,59,11
|
||||
CONTROL "16:9",IDC_ASPECT_16_9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,80,49,11
|
||||
CONTROL "&Widescreen Hack",IDC_WIDESCREEN_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,128,81,73,10
|
||||
CONTROL "&Safe Texture Cache",IDC_SAFE_TEXTURE_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,172,85,11
|
||||
END
|
||||
|
||||
IDD_DEBUGGER DIALOGEX 0, 0, 234, 254
|
||||
@ -128,7 +120,7 @@ BEGIN
|
||||
VERTGUIDE, 81
|
||||
VERTGUIDE, 87
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 167
|
||||
BOTTOMMARGIN, 187
|
||||
END
|
||||
|
||||
IDD_DEBUGGER, DIALOG
|
||||
@ -198,7 +190,7 @@ END
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
<EFBFBD>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
Reference in New Issue
Block a user