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)