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:
hrydgard 2009-09-19 13:14:55 +00:00
parent dae1a68bfc
commit 7a8f6bdd6d
17 changed files with 259 additions and 170 deletions

View File

@ -31,6 +31,8 @@ void IndexGenerator::Start(unsigned short *startptr)
ptr = startptr;
index = 0;
numPrims = 0;
adds = 0;
onlyLists = true;
}
void IndexGenerator::AddList(int numVerts)
@ -45,6 +47,7 @@ void IndexGenerator::AddList(int numVerts)
}
index += numVerts;
numPrims += numTris;
adds++;
}
void IndexGenerator::AddStrip(int numVerts)
@ -61,6 +64,8 @@ void IndexGenerator::AddStrip(int numVerts)
}
index += numVerts;
numPrims += numTris;
adds++;
onlyLists = false;
}
void IndexGenerator::AddLineList(int numVerts)
@ -74,6 +79,7 @@ void IndexGenerator::AddLineList(int numVerts)
}
index += numVerts;
numPrims += numLines;
adds++;
}
void IndexGenerator::AddLineStrip(int numVerts)
@ -87,9 +93,10 @@ void IndexGenerator::AddLineStrip(int numVerts)
}
index += numVerts;
numPrims += numLines;
adds++;
onlyLists = false;
}
void IndexGenerator::AddFan(int numVerts)
{
int numTris = numVerts - 2;
@ -102,6 +109,8 @@ void IndexGenerator::AddFan(int numVerts)
}
index += numVerts;
numPrims += numTris;
adds++;
onlyLists = false;
}
void IndexGenerator::AddQuads(int numVerts)
@ -119,10 +128,13 @@ void IndexGenerator::AddQuads(int numVerts)
}
index += numVerts;
numPrims += numTris;
adds++;
onlyLists = false;
}
void IndexGenerator::AddPointList(int numVerts)
void IndexGenerator::AddPoints(int numVerts)
{
index += numVerts;
numPrims += numVerts;
adds++;
}

View File

@ -28,16 +28,20 @@ public:
void AddList(int numVerts);
void AddStrip(int numVerts);
void AddLineList(int numVerts);
void AddPointList(int numVerts); //dummy for counting vertices
void AddLineStrip(int numVerts);
void AddFan(int numVerts);
void AddQuads(int numVerts);
void AddPoints(int numVerts);
int GetNumPrims() {return numPrims;} //returns numprimitives
int GetNumVerts() {return index;} //returns numprimitives
int GetNumAdds() {return adds;}
bool GetOnlyLists() {return onlyLists;}
private:
unsigned short *ptr;
int numPrims;
int index;
int adds;
bool onlyLists;
};
#endif // _INDEXGENERATOR_H

View File

@ -57,6 +57,7 @@ char *Statistics::ToString(char *ptr)
p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"draw calls: %i\n",stats.thisFrame.numDrawCalls);
p+=sprintf(p,"indexed draw calls: %i\n",stats.thisFrame.numIndexedDrawCalls);
p+=sprintf(p,"buffer splits: %i\n",stats.thisFrame.numBufferSplits);
p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);

View File

@ -67,6 +67,7 @@ struct Statistics
int numPrimitiveJoins;
int numDrawCalls;
int numIndexedDrawCalls;
int numBufferSplits;
int numDListsCalled;

View File

@ -142,6 +142,12 @@ struct TargetRectangle : public MathUtil::Rectangle<int>
#define LOG_VTX()
#ifdef _WIN32
#define ERASE_THROUGH_ITERATOR(container, iterator) iterator = container.erase(iterator)
#else
#define ERASE_THROUGH_ITERATOR(container, iterator) container.erase(iterator++)
#endif
bool IsD3D();
#endif // _VIDEOCOMMON_H

View File

@ -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,6 +148,57 @@ 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);
break;

View File

@ -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;
}

View File

@ -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)

View File

@ -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)
{
// 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)
{
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 hash_value;
u32 texID = address;
u32 texHash;
if (g_ActiveConfig.bDumpTextures || g_ActiveConfig.bSafeTextureCache)
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bDumpTextures)
{
tex_hash = hash_value;
if ((format == GX_TF_C4) || (format == GX_TF_C8) || (format == GX_TF_C14X2))
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))
{
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)));
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;
}

View File

@ -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.
@ -77,6 +86,19 @@ const Collection collectionTypeLUT[8] =
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,6 +151,7 @@ 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)
@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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.
//
À
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -222,6 +222,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
void PixelShaderCache::ProgressiveCleanup()
{
/*
PSCache::iterator iter = pshaders.begin();
while (iter != pshaders.end()) {
PSCacheEntry &entry = iter->second;
@ -237,6 +238,7 @@ void PixelShaderCache::ProgressiveCleanup()
iter++;
}
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
*/
}
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)

View File

@ -148,7 +148,7 @@ void TextureMngr::TCacheEntry::Destroy(bool shutdown)
return;
glDeleteTextures(1, &texture);
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache) {
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset * 4);
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
if (ptr && *ptr == hash)
*ptr = oldpixel;
}
@ -183,12 +183,6 @@ void TextureMngr::Shutdown()
temp = NULL;
}
#ifdef _WIN32
#define ERASE_THROUGH_ITERATOR(container, iterator) iterator = container.erase(iterator)
#else
#define ERASE_THROUGH_ITERATOR(container, iterator) container.erase(iterator++)
#endif
void TextureMngr::ProgressiveCleanup()
{
TexCache::iterator iter = textures.begin();
@ -210,7 +204,8 @@ void TextureMngr::ProgressiveCleanup()
}
}
void TextureMngr::InvalidateRange(u32 start_address, u32 size) {
void TextureMngr::InvalidateRange(u32 start_address, u32 size)
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end())
{
@ -291,11 +286,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
bool skip_texture_create = false;
TexCache::iterator iter = textures.find(texID);
if (iter != textures.end()) {
if (iter != textures.end())
{
TCacheEntry &entry = iter->second;
if (!g_ActiveConfig.bSafeTextureCache)
hash_value = ((u32 *)ptr)[entry.hashoffset];
hash_value = ((u32 *)ptr)[0];
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash)))
{
@ -355,20 +351,15 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
if (dfmt == PC_TEX_FMT_NONE)
dfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
entry.hashoffset = 0;
//entry.paletteHash = hashseed;
entry.oldpixel = ((u32 *)ptr)[entry.hashoffset];
entry.oldpixel = ((u32 *)ptr)[0];
if (g_ActiveConfig.bSafeTextureCache)
entry.hash = hash_value;
else
{
entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF);
((u32 *)ptr)[entry.hashoffset] = entry.hash;
((u32 *)ptr)[0] = entry.hash;
}
//DebugLog("%c addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_ActiveConfig.bSafeTextureCache ? 'S' : 'U'
// , address, tex_format, entry.hash, width, height);
entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format);
@ -511,7 +502,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
TCacheEntry& entry = textures[address];
entry.hash = 0;
entry.hashoffset = 0;
entry.frameCount = frameCount;
int w = (abs(source_rect.GetWidth()) >> bScaleByHalf);

View File

@ -36,7 +36,6 @@ public:
u32 size_in_bytes;
u32 hash;
u32 paletteHash;
u32 hashoffset;
u32 oldpixel; // used for simple cleanup
TexMode0 mode; // current filter and clamp modes that texture is set to

View File

@ -182,6 +182,7 @@ VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
void VertexShaderCache::ProgressiveCleanup()
{
/*
VSCache::iterator iter = vshaders.begin();
while (iter != vshaders.end()) {
VSCacheEntry &entry = iter->second;
@ -199,6 +200,7 @@ void VertexShaderCache::ProgressiveCleanup()
}
SETSTAT(stats.numVertexShadersAlive, vshaders.size());
*/
}
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)