From 7a8f6bdd6dd4d6aaa101f0d935a021b8ad327e92 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 19 Sep 2009 13:14:55 +0000 Subject: [PATCH] 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 --- .../Core/VideoCommon/Src/IndexGenerator.cpp | 20 ++- Source/Core/VideoCommon/Src/IndexGenerator.h | 6 +- Source/Core/VideoCommon/Src/Statistics.cpp | 1 + Source/Core/VideoCommon/Src/Statistics.h | 1 + Source/Core/VideoCommon/Src/VideoCommon.h | 6 + .../Plugin_VideoDX9/Src/D3DTexture.cpp | 60 ++++++- .../Plugin_VideoDX9/Src/DlgSettings.cpp | 4 + .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 2 + .../Plugin_VideoDX9/Src/TextureCache.cpp | 117 +++++++------ .../Plugin_VideoDX9/Src/VertexManager.cpp | 157 ++++++++++-------- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 4 +- Source/Plugins/Plugin_VideoDX9/Src/resource.h | 4 +- .../Plugins/Plugin_VideoDX9/Src/resource.rc | 16 +- .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 2 + .../Plugin_VideoOGL/Src/TextureMngr.cpp | 26 +-- .../Plugins/Plugin_VideoOGL/Src/TextureMngr.h | 1 - .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 2 + 17 files changed, 259 insertions(+), 170 deletions(-) diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index f18356f8e7..b2dd3efd49 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -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; -} \ No newline at end of file + numPrims += numVerts; + adds++; +} diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.h b/Source/Core/VideoCommon/Src/IndexGenerator.h index 36fc3e2bbf..537b71d9a2 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.h +++ b/Source/Core/VideoCommon/Src/IndexGenerator.h @@ -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 \ No newline at end of file diff --git a/Source/Core/VideoCommon/Src/Statistics.cpp b/Source/Core/VideoCommon/Src/Statistics.cpp index c7cde6d408..9ad39621b0 100644 --- a/Source/Core/VideoCommon/Src/Statistics.cpp +++ b/Source/Core/VideoCommon/Src/Statistics.cpp @@ -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); diff --git a/Source/Core/VideoCommon/Src/Statistics.h b/Source/Core/VideoCommon/Src/Statistics.h index c6329f4059..658101b6f1 100644 --- a/Source/Core/VideoCommon/Src/Statistics.h +++ b/Source/Core/VideoCommon/Src/Statistics.h @@ -67,6 +67,7 @@ struct Statistics int numPrimitiveJoins; int numDrawCalls; + int numIndexedDrawCalls; int numBufferSplits; int numDListsCalled; diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 9e800f887e..8922d75b95 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -142,6 +142,12 @@ struct TargetRectangle : public MathUtil::Rectangle #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 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp index ed1d982f98..bbf3633344 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp @@ -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); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp index 29c75fc108..54f5208a10 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp @@ -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; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 299f779ad0..dafed61dfb 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 1dd9d65cde..8141c37651 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -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; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 516bcb0be5..b19ddf5c06 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 5409c217b3..6a09e86fc9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.h b/Source/Plugins/Plugin_VideoDX9/Src/resource.h index 8cd042fa2c..3450e15fdf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.h @@ -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 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc index f6d618b33d..c51ad5849f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc @@ -2,15 +2,6 @@ // #include "resource.h" #include - -#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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 14273ee66c..929247c7da 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index 00e54d7d11..61fee0aaf4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -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); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h index 174df84e12..7779f97383 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h @@ -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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index 2d6cb30ddf..a2553e4037 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -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)