From 5230146c7341eec2e541405043a2aa385d206a12 Mon Sep 17 00:00:00 2001 From: "rodolfoosvaldobogado@gmail.com" Date: Sat, 20 Oct 2012 10:22:15 -0300 Subject: [PATCH] Hey, long time no commits :). So to compensate lets bring back some speed to the emulation. change a little the way the vertex are send to the gpu, This first implementation changes dx9 a lot and dx11 a little to increase the parallelism between the cpu and gpu. ogl: is my next step in ogl is a little more trickier so i have to take a little more time. the original concept is Marcos idea, with my little touch to make it even more faster. what to look for: SPEEEEEDDD :). please test it a lot and let me know if you see any problem. in dx9 the code is prepared to fall back to the previous implementation if your card does not support the amount of buffers needed. So if you did not experience any speed gains you know where is the problem :). for the ones with more experience and compression of the code please test changing the amount and size of the buffers to tune this for your specific machine. The current values are the sweet spot for my machine. All must Thanks Marcos, I hate him for giving good ideas when I'm full of work. --- .../Core/VideoCommon/Src/VertexManagerBase.h | 5 +- .../Plugin_VideoDX11/Src/VertexManager.cpp | 96 +++--- .../Plugin_VideoDX11/Src/VertexManager.h | 16 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 15 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 298 +++++++++++++++--- .../Plugin_VideoDX9/Src/VertexManager.h | 17 + Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 6 +- .../Plugin_VideoOGL/Src/VertexManager.cpp | 10 + .../Plugin_VideoOGL/Src/VertexManager.h | 3 +- 9 files changed, 377 insertions(+), 89 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index bc30fa3fba..f3a4aa72e3 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -21,7 +21,7 @@ public: // values from DX11 backend MAXVBUFFERSIZE = 0x50000, - MAXIBUFFERSIZE = 0x10000, + MAXIBUFFERSIZE = 0xFFFF, }; VertexManager(); @@ -46,7 +46,8 @@ public: static u8* GetVertexBuffer() { return LocalVBuffer; } static void DoState(PointerWrap& p); - + virtual void CreateDeviceObjects(){}; + virtual void DestroyDeviceObjects(){}; protected: // TODO: make private after Flush() is merged static void ResetBuffer(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 58bad98cc6..e2a8f4a547 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -39,32 +39,47 @@ namespace DX11 { // TODO: Find sensible values for these two -const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE*2 * 16; -const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; +const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 12; +const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 8; +const UINT MAXVBUFFER_COUNT = 4; void VertexManager::CreateDeviceObjects() { D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffer)), - "Failed to create index buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffer, "index buffer of VertexManager"); - - bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufdesc.ByteWidth = VBUFFER_SIZE; - - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffer)), - "Failed to create vertex buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffer, "vertex buffer of VertexManager"); - m_indexBufferCursor = 0; m_vertexBufferCursor = 0; m_vertexDrawOffset = 0; - m_triangleDrawIndex = 0; m_lineDrawIndex = 0; m_pointDrawIndex = 0; + m_indexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; + m_vertexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; + bool Fail = false; + for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + { + m_indexBuffers[m_activeVertexBuffer] = NULL; + m_vertexBuffers[m_activeVertexBuffer] = NULL; + } + for (m_activeIndexBuffer = 0; m_activeIndexBuffer < MAXVBUFFER_COUNT; m_activeIndexBuffer++) + { + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffers[m_activeIndexBuffer])), + "Failed to create index buffer."); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffers[m_activeIndexBuffer], "index buffer of VertexManager"); + } + bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufdesc.ByteWidth = VBUFFER_SIZE; + for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + { + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffers[m_activeVertexBuffer])), + "Failed to create vertex buffer."); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffers[m_activeVertexBuffer], "Vertex buffer of VertexManager"); + } + m_activeVertexBuffer = 0; + m_activeIndexBuffer = 0; + m_LastVertexBuffer = MAXVBUFFER_COUNT; + m_LastIndexBuffer = MAXVBUFFER_COUNT; m_lineShader.Init(); m_pointShader.Init(); @@ -74,9 +89,12 @@ void VertexManager::DestroyDeviceObjects() { m_pointShader.Shutdown(); m_lineShader.Shutdown(); - - SAFE_RELEASE(m_vertexBuffer); - SAFE_RELEASE(m_indexBuffer); + for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + { + SAFE_RELEASE(m_vertexBuffers[m_activeVertexBuffer]); + SAFE_RELEASE(m_indexBuffers[m_activeVertexBuffer]); + } + } VertexManager::VertexManager() @@ -94,42 +112,41 @@ void VertexManager::LoadBuffers() D3D11_MAPPED_SUBRESOURCE map; UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer); - if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) + D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE; + if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE || m_activeVertexBuffer != m_LastVertexBuffer) { // Wrap around - D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + m_activeVertexBuffer = (m_activeVertexBuffer + 1) % MAXVBUFFER_COUNT; m_vertexBufferCursor = 0; + MapType = D3D11_MAP_WRITE_DISCARD; } - else - { - // Append data - D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); - } + + D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map); + memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); - D3D::context->Unmap(m_vertexBuffer, 0); + D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0); m_vertexDrawOffset = m_vertexBufferCursor; m_vertexBufferCursor += vSize; UINT iCount = IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2) + MapType = D3D11_MAP_WRITE_NO_OVERWRITE; + if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2 || m_activeIndexBuffer != m_LastIndexBuffer) { // Wrap around - D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + m_activeIndexBuffer = (m_activeIndexBuffer + 1) % MAXVBUFFER_COUNT; m_indexBufferCursor = 0; + MapType = D3D11_MAP_WRITE_DISCARD; } - else - { - // Append data - D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); - } + D3D::context->Map(m_indexBuffers[m_activeIndexBuffer], 0, MapType, 0, &map); + m_triangleDrawIndex = m_indexBufferCursor; m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen(); memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, 2*IndexGenerator::GetTriangleindexLen()); memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, 2*IndexGenerator::GetLineindexLen()); memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, 2*IndexGenerator::GetPointindexLen()); - D3D::context->Unmap(m_indexBuffer, 0); + D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); m_indexBufferCursor += iCount; } @@ -139,9 +156,11 @@ static const float LINE_PT_TEX_OFFSETS[8] = { void VertexManager::Draw(UINT stride) { - D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset); - D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); - + D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffers[m_activeVertexBuffer], &stride, &m_vertexDrawOffset); + D3D::context->IASetIndexBuffer(m_indexBuffers[m_activeIndexBuffer], DXGI_FORMAT_R16_UINT, 0); + m_LastIndexBuffer = m_activeIndexBuffer; + m_LastVertexBuffer = m_activeVertexBuffer; + if (IndexGenerator::GetNumTriangles() > 0) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -260,12 +279,11 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; } - + LoadBuffers(); unsigned int stride = g_nativeVertexFmt->GetVertexStride(); g_nativeVertexFmt->SetupVertexPointers(); - g_renderer->ApplyState(useDstAlpha); - LoadBuffers(); + Draw(stride); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h index a387be5155..2e8cfaa388 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h @@ -32,10 +32,11 @@ public: ~VertexManager(); NativeVertexFormat* CreateNativeVertexFormat(); - -private: void CreateDeviceObjects(); void DestroyDeviceObjects(); + +private: + void LoadBuffers(); void Draw(UINT stride); // temp @@ -46,9 +47,14 @@ private: UINT m_vertexDrawOffset; UINT m_triangleDrawIndex; UINT m_lineDrawIndex; - UINT m_pointDrawIndex; - ID3D11Buffer* m_indexBuffer; - ID3D11Buffer* m_vertexBuffer; + UINT m_pointDrawIndex; + UINT m_activeVertexBuffer; + UINT m_activeIndexBuffer; + UINT m_LastVertexBuffer; + UINT m_LastIndexBuffer; + typedef ID3D11Buffer* PID3D11Buffer; + PID3D11Buffer* m_indexBuffers; + PID3D11Buffer* m_vertexBuffers; LineGeometryShader m_lineShader; PointGeometryShader m_pointShader; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 45030c48df..653e387192 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -225,6 +225,7 @@ void SetupDeviceObjects() // To avoid shader compilation stutters, read back all shaders from cache. VertexShaderCache::Init(); PixelShaderCache::Init(); + g_vertex_manager->CreateDeviceObjects(); // Texture cache will recreate themselves over time. } @@ -243,6 +244,7 @@ void TeardownDeviceObjects() VertexShaderCache::Shutdown(); PixelShaderCache::Shutdown(); TextureConverter::Shutdown(); + g_vertex_manager->DestroyDeviceObjects(); } // Init functions @@ -1198,6 +1200,12 @@ void Renderer::ApplyState(bool bUseDstAlpha) { D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + } } } @@ -1205,7 +1213,12 @@ void Renderer::RestoreState() { D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); - + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + D3D::RefreshRenderState(D3DRS_ZENABLE); + D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ZFUNC); + } // TODO: Enable this code. Caused glitches for me however (neobrain) // for (unsigned int i = 0; i < 8; ++i) // D3D::dev->SetTexture(i, NULL); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 9f55da15fa..e8e425cc96 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -39,7 +39,6 @@ // internal state for loading vertices extern NativeVertexFormat *g_nativeVertexFmt; - namespace DX9 { @@ -62,49 +61,259 @@ inline void DumpBadShaders() #endif } +void VertexManager::CreateDeviceObjects() +{ + NumVBuffers = 0; + CurrentIBufferIndex = 0; + CurrentVBufferIndex = 0; + CurrentVBufferSize = 8 * MAXVBUFFERSIZE; + CurrentIBufferSize = 12 * MAXIBUFFERSIZE; + D3DCAPS9 DeviceCaps = D3D::GetCaps(); + int maxdevicevbuffersize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; + if (CurrentVBufferSize > maxdevicevbuffersize) + { + CurrentVBufferSize = maxdevicevbuffersize; + } + if (CurrentIBufferSize > DeviceCaps.MaxVertexIndex) + { + CurrentIBufferSize = DeviceCaps.MaxVertexIndex; + } + if (CurrentIBufferSize < MAXIBUFFERSIZE) + { + return; + } + if (CurrentVBufferSize < MAXVBUFFERSIZE) + { + return; + } + VBuffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBufferCount]; + IBuffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBufferCount]; + bool Fail = false; + for (CurrentVBuffer = 0; CurrentVBuffer < MAX_VBufferCount; CurrentVBuffer++) + { + VBuffers[CurrentVBuffer] = NULL; + IBuffers[CurrentVBuffer] = NULL; + } + for (CurrentVBuffer = 0; CurrentVBuffer < MAX_VBufferCount; CurrentVBuffer++) + { + if(FAILED( D3D::dev->CreateVertexBuffer( CurrentVBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &VBuffers[CurrentVBuffer], NULL ) ) ) + { + Fail = true; + break; + } + if( FAILED( D3D::dev->CreateIndexBuffer( CurrentIBufferSize * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IBuffers[CurrentVBuffer], NULL ) ) ) + { + Fail = true; + return; + } + } + NumVBuffers = CurrentVBuffer; + CurrentVBuffer = 0; + CurrentIBuffer = 0; + LastVBuffer = NumVBuffers; + LastIBuffer = NumVBuffers; + if (Fail) + { + NumVBuffers--; + if (NumVBuffers < 2) + { + NumVBuffers = MAX_VBufferCount; + DestroyDeviceObjects(); + } + } + +} +void VertexManager::DestroyDeviceObjects() +{ + D3D::dev->SetStreamSource( 0, NULL, 0, 0); + D3D::dev->SetIndices(NULL); + for (int i = 0; i < MAX_VBufferCount; i++) + { + if(VBuffers) + { + if (VBuffers[i]) + { + VBuffers[i]->Release(); + VBuffers[i] = NULL; + } + } + + if (IBuffers[i]) + { + IBuffers[i]->Release(); + IBuffers[i] = NULL; + } + } + if(VBuffers) + delete [] VBuffers; + if(IBuffers) + delete [] IBuffers; + VBuffers = NULL; + IBuffers = NULL; +} + +VertexManager::VertexManager() +{ + //CreateDeviceObjects(); +} + +VertexManager::~VertexManager() +{ + //DestroyDeviceObjects(); +} + +void VertexManager::PrepareVBuffers(int stride) +{ + if (!NumVBuffers) + { + return; + } + u8* pVertices; + u16* pIndices; + int datasize = IndexGenerator::GetNumVerts() * stride; + int TdataSize = IndexGenerator::GetTriangleindexLen(); + int LDataSize = IndexGenerator::GetLineindexLen(); + int PDataSize = IndexGenerator::GetPointindexLen(); + int IndexDataSize = TdataSize + LDataSize + PDataSize; + DWORD LockMode = D3DLOCK_NOOVERWRITE; + + if (CurrentVBufferIndex > CurrentVBufferSize - datasize || LastVBuffer != CurrentVBuffer) + { + LockMode = D3DLOCK_DISCARD; + CurrentVBufferIndex = 0; + CurrentVBuffer = (CurrentVBuffer + 1) % NumVBuffers; + } + + if(FAILED(VBuffers[CurrentVBuffer]->Lock(CurrentVBufferIndex, datasize,(VOID**)(&pVertices), LockMode))) + { + DestroyDeviceObjects(); + return; + } + memcpy(pVertices, LocalVBuffer, datasize); + VBuffers[CurrentVBuffer]->Unlock(); + + LockMode = D3DLOCK_NOOVERWRITE; + + if (CurrentIBufferIndex > CurrentIBufferSize - IndexDataSize || LastIBuffer != CurrentIBuffer) + { + LockMode = D3DLOCK_DISCARD; + CurrentIBufferIndex = 0; + CurrentIBuffer = (CurrentIBuffer + 1) % NumVBuffers; + } + + if(FAILED(IBuffers[CurrentIBuffer]->Lock(CurrentIBufferIndex * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + { + DestroyDeviceObjects(); + return; + } + if(TdataSize) + { + memcpy(pIndices, TIBuffer, TdataSize * sizeof(u16)); + pIndices += TdataSize; + } + if(LDataSize) + { + memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); + pIndices += LDataSize; + } + if(PDataSize) + { + memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); + } + IBuffers[CurrentIBuffer]->Unlock(); +} + void VertexManager::Draw(int stride) { - if (IndexGenerator::GetNumTriangles() > 0) + if(NumVBuffers) { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), - TIBuffer, - D3DFMT_INDEX16, - LocalVBuffer, - stride))) + if (IndexGenerator::GetNumTriangles() > 0) { - DumpBadShaders(); + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_TRIANGLELIST, + 0, + 0, + IndexGenerator::GetNumVerts(), + CurrentIBufferIndex, + IndexGenerator::GetNumTriangles()))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (IndexGenerator::GetNumLines() > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_LINELIST, + 0, + 0, + IndexGenerator::GetNumVerts(), + CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen(), + IndexGenerator::GetNumLines()))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (IndexGenerator::GetNumPoints() > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_POINTLIST, + 0, + 0, + IndexGenerator::GetNumVerts(), + CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), + IndexGenerator::GetNumPoints()))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + else { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_LINELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), - LIBuffer, - D3DFMT_INDEX16, - LocalVBuffer, - stride))) + if (IndexGenerator::GetNumTriangles() > 0) { - DumpBadShaders(); + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_TRIANGLELIST, + 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), + TIBuffer, + D3DFMT_INDEX16, + LocalVBuffer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (IndexGenerator::GetNumPoints() > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_POINTLIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), - PIBuffer, - D3DFMT_INDEX16, - LocalVBuffer, - stride))) + if (IndexGenerator::GetNumLines() > 0) { - DumpBadShaders(); + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_LINELIST, + 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), + LIBuffer, + D3DFMT_INDEX16, + LocalVBuffer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (IndexGenerator::GetNumPoints() > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_POINTLIST, + 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), + PIBuffer, + D3DFMT_INDEX16, + LocalVBuffer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); } } @@ -153,7 +362,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - + int stride = g_nativeVertexFmt->GetVertexStride(); if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); @@ -165,10 +374,18 @@ void VertexManager::vFlush() goto shader_fail; } - - int stride = g_nativeVertexFmt->GetVertexStride(); - g_nativeVertexFmt->SetupVertexPointers(); - + PrepareVBuffers(stride); + if (NumVBuffers) + { + D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride); + if(LastIBuffer != CurrentIBuffer) + { + LastIBuffer = CurrentIBuffer; + D3D::dev->SetIndices(IBuffers[CurrentIBuffer]); + } + LastVBuffer = CurrentVBuffer; + } + g_nativeVertexFmt->SetupVertexPointers(); Draw(stride); bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && @@ -189,6 +406,11 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); shader_fail: + if(NumVBuffers) + { + CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride; + } ResetBuffer(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index 0d12616ac5..a80f12276d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -23,6 +23,7 @@ #include "VertexManagerBase.h" +#define MAX_VBufferCount 4 namespace DX9 { @@ -31,8 +32,24 @@ class VertexManager : public ::VertexManager public: NativeVertexFormat* CreateNativeVertexFormat(); void GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num); + void CreateDeviceObjects(); + void DestroyDeviceObjects(); + VertexManager(); + ~VertexManager(); private: + u32 CurrentVBufferIndex; + u32 CurrentVBufferSize; + u32 CurrentIBufferIndex; + u32 CurrentIBufferSize; + u32 NumVBuffers; + u32 CurrentVBuffer; + u32 CurrentIBuffer; + u32 LastVBuffer; + u32 LastIBuffer; + LPDIRECT3DVERTEXBUFFER9 *VBuffers; + LPDIRECT3DINDEXBUFFER9 *IBuffers; + void PrepareVBuffers(int stride); void Draw(int stride); // temp void vFlush(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 5aeca6751d..d3fd6050bf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -168,9 +168,9 @@ void VideoBackend::Video_Prepare() s_swapRequested = FALSE; // internal interfaces - g_renderer = new Renderer; - g_texture_cache = new TextureCache; g_vertex_manager = new VertexManager; + g_renderer = new Renderer; + g_texture_cache = new TextureCache; // VideoCommon BPInit(); Fifo_Init(); @@ -208,9 +208,9 @@ void VideoBackend::Shutdown() // internal interfaces PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); - delete g_vertex_manager; delete g_texture_cache; delete g_renderer; + delete g_vertex_manager; g_renderer = NULL; g_texture_cache = NULL; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 0a37b0e654..501c4969e5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -69,6 +69,16 @@ VertexManager::VertexManager() GL_REPORT_ERRORD(); } +void VertexManager::CreateDeviceObjects() +{ + + +} +void VertexManager::DestroyDeviceObjects() +{ + +} + void VertexManager::Draw() { if (IndexGenerator::GetNumTriangles() > 0) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 0f22054855..5cec1bf97e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -33,7 +33,8 @@ public: VertexManager(); NativeVertexFormat* CreateNativeVertexFormat(); - + void CreateDeviceObjects(); + void DestroyDeviceObjects(); private: void Draw(); // temp