From eaa1ea71c1b5abda68ab46d1039b06b56a0bd074 Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Fri, 26 Oct 2012 11:34:02 -0300 Subject: [PATCH 1/7] Implement the new buffer approach in opengl. sadly in my machine it gives my only 2 more fps and if your hardware does not support ARB_map_buffer_range is even slower than plain vertex arrays. change naming in all the backends vertex managers to make more easy to continue with the merge an some future improvements. please test this as i'm interested in knowing the performance in linux and windows with the different hardware platforms. --- .../VideoCommon/Src/LightingShaderGen.cpp | 2 +- .../Core/VideoCommon/Src/NativeVertexFormat.h | 2 +- .../Core/VideoCommon/Src/OpcodeDecoding.cpp | 4 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 4 +- .../Plugin_VideoDX11/Src/VertexManager.cpp | 98 +++---- .../Plugin_VideoDX11/Src/VertexManager.h | 24 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 128 ++++----- .../Plugin_VideoDX9/Src/VertexManager.h | 24 +- .../Src/NativeVertexFormat.cpp | 60 +++-- .../Plugin_VideoOGL/Src/VertexManager.cpp | 248 +++++++++++++++--- .../Plugin_VideoOGL/Src/VertexManager.h | 30 ++- 11 files changed, 431 insertions(+), 193 deletions(-) diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index a506acadfc..f32e5dfeee 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -23,7 +23,7 @@ int GetLightingShaderId(u32* out) { - for (int i = 0; i < xfregs.numChan.numColorChans; ++i) + for (u32 i = 0; i < xfregs.numChan.numColorChans; ++i) { out[i] = xfregs.color[i].enablelighting ? (u32)xfregs.color[i].hex : diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index 02184fde1c..1340991b21 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -102,7 +102,7 @@ public: virtual void SetupVertexPointers() = 0; virtual void EnableComponents(u32 components) {} - int GetVertexStride() const { return vertex_stride; } + u32 GetVertexStride() const { return vertex_stride; } // TODO: move this under private: u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. diff --git a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp index 4f7f86d655..a1ff1a9985 100644 --- a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp @@ -346,7 +346,7 @@ static void Decode() // Display lists get added directly into the FIFO stream if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) - FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); + FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart)); } static void DecodeSemiNop() @@ -429,7 +429,7 @@ static void DecodeSemiNop() } if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) - FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); + FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart)); } void OpcodeDecoder_Init() diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index bc7a12304f..3d5e676c61 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -196,7 +196,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo *ptr++ = components; } - uid->num_values = ptr - uid->values; + uid->num_values = int(ptr - uid->values); } void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components) @@ -229,7 +229,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.tevindref.hex; // 32 - for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times + for (u32 i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times { *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 7026522cf6..48f84b9aca 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -41,39 +41,39 @@ namespace DX11 // TODO: Find sensible values for these two const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; -const UINT MAXVBUFFER_COUNT = 2; +const UINT MAX_VBUFFER_COUNT = 2; void VertexManager::CreateDeviceObjects() { D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_vertexDrawOffset = 0; - m_triangleDrawIndex = 0; - m_lineDrawIndex = 0; - m_pointDrawIndex = 0; - m_indexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; - m_vertexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; - for (m_activeIndexBuffer = 0; m_activeIndexBuffer < MAXVBUFFER_COUNT; m_activeIndexBuffer++) + m_vertex_draw_offset = 0; + m_triangle_draw_index = 0; + m_line_draw_index = 0; + m_point_draw_index = 0; + m_index_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT]; + m_vertex_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT]; + for (m_current_index_buffer = 0; m_current_index_buffer < MAX_VBUFFER_COUNT; m_current_index_buffer++) { - m_indexBuffers[m_activeIndexBuffer] = NULL; - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffers[m_activeIndexBuffer])), + m_index_buffers[m_current_index_buffer] = NULL; + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_index_buffers[m_current_index_buffer])), "Failed to create index buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffers[m_activeIndexBuffer], "index buffer of VertexManager"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_index_buffers[m_current_index_buffer], "index buffer of VertexManager"); } bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufdesc.ByteWidth = VBUFFER_SIZE; - for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - m_vertexBuffers[m_activeVertexBuffer] = NULL; - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffers[m_activeVertexBuffer])), + m_vertex_buffers[m_current_vertex_buffer] = NULL; + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertex_buffers[m_current_vertex_buffer])), "Failed to create vertex buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffers[m_activeVertexBuffer], "Vertex buffer of VertexManager"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertex_buffers[m_current_vertex_buffer], "Vertex buffer of VertexManager"); } - m_activeVertexBuffer = 0; - m_activeIndexBuffer = 0; - m_indexBufferCursor = IBUFFER_SIZE; - m_vertexBufferCursor = VBUFFER_SIZE; + m_current_vertex_buffer = 0; + m_current_index_buffer = 0; + m_index_buffer_cursor = IBUFFER_SIZE; + m_vertex_buffer_cursor = VBUFFER_SIZE; m_lineShader.Init(); m_pointShader.Init(); } @@ -82,10 +82,10 @@ void VertexManager::DestroyDeviceObjects() { m_pointShader.Shutdown(); m_lineShader.Shutdown(); - for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - SAFE_RELEASE(m_vertexBuffers[m_activeVertexBuffer]); - SAFE_RELEASE(m_indexBuffers[m_activeVertexBuffer]); + SAFE_RELEASE(m_vertex_buffers[m_current_vertex_buffer]); + SAFE_RELEASE(m_index_buffers[m_current_vertex_buffer]); } } @@ -100,47 +100,47 @@ VertexManager::~VertexManager() DestroyDeviceObjects(); } -void VertexManager::LoadBuffers() +void VertexManager::PrepareDrawBuffers() { D3D11_MAPPED_SUBRESOURCE map; UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer); D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE; - if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) + if (m_vertex_buffer_cursor + vSize >= VBUFFER_SIZE) { // Wrap around - m_activeVertexBuffer = (m_activeVertexBuffer + 1) % MAXVBUFFER_COUNT; - m_vertexBufferCursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % MAX_VBUFFER_COUNT; + m_vertex_buffer_cursor = 0; MapType = D3D11_MAP_WRITE_DISCARD; } - D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map); + D3D::context->Map(m_vertex_buffers[m_current_vertex_buffer], 0, MapType, 0, &map); - memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); - D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0); - m_vertexDrawOffset = m_vertexBufferCursor; - m_vertexBufferCursor += vSize; + memcpy((u8*)map.pData + m_vertex_buffer_cursor, LocalVBuffer, vSize); + D3D::context->Unmap(m_vertex_buffers[m_current_vertex_buffer], 0); + m_vertex_draw_offset = m_vertex_buffer_cursor; + m_vertex_buffer_cursor += vSize; UINT iCount = IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); MapType = D3D11_MAP_WRITE_NO_OVERWRITE; - if (m_indexBufferCursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) + if (m_index_buffer_cursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) { // Wrap around - m_activeIndexBuffer = (m_activeIndexBuffer + 1) % MAXVBUFFER_COUNT; - m_indexBufferCursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % MAX_VBUFFER_COUNT; + m_index_buffer_cursor = 0; MapType = D3D11_MAP_WRITE_DISCARD; } - D3D::context->Map(m_indexBuffers[m_activeIndexBuffer], 0, MapType, 0, &map); + D3D::context->Map(m_index_buffers[m_current_index_buffer], 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, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); - memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); - memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); - D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); - m_indexBufferCursor += iCount; + m_triangle_draw_index = m_index_buffer_cursor; + m_line_draw_index = m_triangle_draw_index + IndexGenerator::GetTriangleindexLen(); + m_point_draw_index = m_line_draw_index + IndexGenerator::GetLineindexLen(); + memcpy((u16*)map.pData + m_triangle_draw_index, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); + memcpy((u16*)map.pData + m_line_draw_index, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); + memcpy((u16*)map.pData + m_point_draw_index, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); + D3D::context->Unmap(m_index_buffers[m_current_index_buffer], 0); + m_index_buffer_cursor += iCount; } static const float LINE_PT_TEX_OFFSETS[8] = { @@ -149,13 +149,13 @@ static const float LINE_PT_TEX_OFFSETS[8] = { void VertexManager::Draw(UINT stride) { - D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffers[m_activeVertexBuffer], &stride, &m_vertexDrawOffset); - D3D::context->IASetIndexBuffer(m_indexBuffers[m_activeIndexBuffer], DXGI_FORMAT_R16_UINT, 0); + D3D::context->IASetVertexBuffers(0, 1, &m_vertex_buffers[m_current_vertex_buffer], &stride, &m_vertex_draw_offset); + D3D::context->IASetIndexBuffer(m_index_buffers[m_current_index_buffer], DXGI_FORMAT_R16_UINT, 0); if (IndexGenerator::GetNumTriangles() > 0) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangle_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } // Disable culling for lines and points @@ -177,7 +177,7 @@ void VertexManager::Draw(UINT stride) texOffset, vpWidth, vpHeight, texOffsetEnable)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_line_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); @@ -199,7 +199,7 @@ void VertexManager::Draw(UINT stride) texOffset, vpWidth, vpHeight, texOffsetEnable)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_point_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); @@ -270,7 +270,7 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; } - LoadBuffers(); + PrepareDrawBuffers(); unsigned int stride = g_nativeVertexFmt->GetVertexStride(); g_nativeVertexFmt->SetupVertexPointers(); g_renderer->ApplyState(useDstAlpha); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h index 9e6b7f2dca..b5d0d21757 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h @@ -37,22 +37,22 @@ public: private: - void LoadBuffers(); - void Draw(UINT stride); + void PrepareDrawBuffers(); + void Draw(u32 stride); // temp void vFlush(); - UINT m_indexBufferCursor; - UINT m_vertexBufferCursor; - UINT m_vertexDrawOffset; - UINT m_triangleDrawIndex; - UINT m_lineDrawIndex; - UINT m_pointDrawIndex; - UINT m_activeVertexBuffer; - UINT m_activeIndexBuffer; + u32 m_vertex_buffer_cursor; + u32 m_vertex_draw_offset; + u32 m_index_buffer_cursor; + u32 m_current_vertex_buffer; + u32 m_current_index_buffer; + u32 m_triangle_draw_index; + u32 m_line_draw_index; + u32 m_point_draw_index; typedef ID3D11Buffer* PID3D11Buffer; - PID3D11Buffer* m_indexBuffers; - PID3D11Buffer* m_vertexBuffers; + PID3D11Buffer* m_index_buffers; + PID3D11Buffer* m_vertex_buffers; LineGeometryShader m_lineShader; PointGeometryShader m_pointShader; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 17a7aa1498..884f16f826 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -44,7 +44,7 @@ namespace DX9 //This are the initially requeted size for the buffers expresed in elements const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16; const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; -const u32 MAXVBUFFER_COUNT = 2; +const u32 MAX_VBUFFER_COUNT = 2; inline void DumpBadShaders() { @@ -67,52 +67,52 @@ inline void DumpBadShaders() void VertexManager::CreateDeviceObjects() { - NumVBuffers = 0; - VBuffers = NULL; - IBuffers = NULL; + m_buffers_count = 0; + m_vertex_buffers = NULL; + m_index_buffers = NULL; D3DCAPS9 DeviceCaps = D3D::GetCaps(); u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; //Calculate Device Dependant size - CurrentVBufferSize = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; - CurrentIBufferSize = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; + m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; + m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; //if device caps are not enough for Vbuffer fall back to vertex arrays - if (CurrentIBufferSize < MAXIBUFFERSIZE || CurrentVBufferSize < MAXVBUFFERSIZE) return; + if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - VBuffers = new LPDIRECT3DVERTEXBUFFER9[MAXVBUFFER_COUNT]; - IBuffers = new LPDIRECT3DINDEXBUFFER9[MAXVBUFFER_COUNT]; + m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; + m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; bool Fail = false; - for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - VBuffers[CurrentVBuffer] = NULL; - IBuffers[CurrentVBuffer] = NULL; + m_vertex_buffers[m_current_vertex_buffer] = NULL; + m_index_buffers[m_current_vertex_buffer] = NULL; } - for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - if(FAILED( D3D::dev->CreateVertexBuffer( CurrentVBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &VBuffers[CurrentVBuffer], NULL ) ) ) + if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) { Fail = true; break; } - if( FAILED( D3D::dev->CreateIndexBuffer( CurrentIBufferSize * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IBuffers[CurrentVBuffer], NULL ) ) ) + if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) { Fail = true; return; } } - NumVBuffers = CurrentVBuffer; - CurrentVBuffer = 0; - CurrentIBuffer = 0; - CurrentIBufferIndex = CurrentIBufferSize; - CurrentVBufferIndex = CurrentVBufferSize; + m_buffers_count = m_current_vertex_buffer; + m_current_vertex_buffer = 0; + m_current_index_buffer = 0; + m_index_buffer_cursor = m_index_buffer_size; + m_vertex_buffer_cursor = m_vertex_buffer_size; if (Fail) { - NumVBuffers--; - if (NumVBuffers < 2) + m_buffers_count--; + if (m_buffers_count < 2) { //Error creating Vertex buffers. clean and fall to Vertex arrays - NumVBuffers = MAXVBUFFER_COUNT; + m_buffers_count = MAX_VBUFFER_COUNT; DestroyDeviceObjects(); } } @@ -121,34 +121,34 @@ void VertexManager::DestroyDeviceObjects() { D3D::dev->SetStreamSource( 0, NULL, 0, 0); D3D::dev->SetIndices(NULL); - for (int i = 0; i < MAXVBUFFER_COUNT; i++) + for (int i = 0; i < MAX_VBUFFER_COUNT; i++) { - if(VBuffers) + if(m_vertex_buffers) { - if (VBuffers[i]) + if (m_vertex_buffers[i]) { - VBuffers[i]->Release(); - VBuffers[i] = NULL; + m_vertex_buffers[i]->Release(); + m_vertex_buffers[i] = NULL; } } - if (IBuffers[i]) + if (m_index_buffers[i]) { - IBuffers[i]->Release(); - IBuffers[i] = NULL; + m_index_buffers[i]->Release(); + m_index_buffers[i] = NULL; } } - if(VBuffers) - delete [] VBuffers; - if(IBuffers) - delete [] IBuffers; - VBuffers = NULL; - IBuffers = NULL; + if(m_vertex_buffers) + delete [] m_vertex_buffers; + if(m_index_buffers) + delete [] m_index_buffers; + m_vertex_buffers = NULL; + m_index_buffers = NULL; } -void VertexManager::PrepareVBuffers(int stride) +void VertexManager::PrepareDrawBuffers(u32 stride) { - if (!NumVBuffers) + if (!m_buffers_count) { return; } @@ -161,31 +161,31 @@ void VertexManager::PrepareVBuffers(int stride) int IndexDataSize = TdataSize + LDataSize + PDataSize; DWORD LockMode = D3DLOCK_NOOVERWRITE; - if (CurrentVBufferIndex > CurrentVBufferSize - datasize) + if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) { LockMode = D3DLOCK_DISCARD; - CurrentVBufferIndex = 0; - CurrentVBuffer = (CurrentVBuffer + 1) % NumVBuffers; + m_vertex_buffer_cursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; } - if(FAILED(VBuffers[CurrentVBuffer]->Lock(CurrentVBufferIndex, datasize,(VOID**)(&pVertices), LockMode))) + if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) { DestroyDeviceObjects(); return; } memcpy(pVertices, LocalVBuffer, datasize); - VBuffers[CurrentVBuffer]->Unlock(); + m_vertex_buffers[m_current_vertex_buffer]->Unlock(); LockMode = D3DLOCK_NOOVERWRITE; - if (CurrentIBufferIndex > CurrentIBufferSize - IndexDataSize) + if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) { LockMode = D3DLOCK_DISCARD; - CurrentIBufferIndex = 0; - CurrentIBuffer = (CurrentIBuffer + 1) % NumVBuffers; + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; } - if(FAILED(IBuffers[CurrentIBuffer]->Lock(CurrentIBufferIndex * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) { DestroyDeviceObjects(); return; @@ -204,15 +204,15 @@ void VertexManager::PrepareVBuffers(int stride) { memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); } - IBuffers[CurrentIBuffer]->Unlock(); - D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride); - if(CurrentIBufferIndex == 0) + m_index_buffers[m_current_index_buffer]->Unlock(); + D3D::dev->SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], m_vertex_buffer_cursor, stride); + if(m_index_buffer_cursor == 0) { - D3D::dev->SetIndices(IBuffers[CurrentIBuffer]); + D3D::dev->SetIndices(m_index_buffers[m_current_index_buffer]); } } -void VertexManager::DrawVB(int stride) +void VertexManager::DrawVertexBuffer(int stride) { if (IndexGenerator::GetNumTriangles() > 0) { @@ -221,7 +221,7 @@ void VertexManager::DrawVB(int stride) 0, 0, IndexGenerator::GetNumVerts(), - CurrentIBufferIndex, + m_index_buffer_cursor, IndexGenerator::GetNumTriangles()))) { DumpBadShaders(); @@ -235,7 +235,7 @@ void VertexManager::DrawVB(int stride) 0, 0, IndexGenerator::GetNumVerts(), - CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen(), + m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen(), IndexGenerator::GetNumLines()))) { DumpBadShaders(); @@ -249,7 +249,7 @@ void VertexManager::DrawVB(int stride) 0, 0, IndexGenerator::GetNumVerts(), - CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), + m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), IndexGenerator::GetNumPoints()))) { DumpBadShaders(); @@ -259,7 +259,7 @@ void VertexManager::DrawVB(int stride) } -void VertexManager::DrawVA(int stride) +void VertexManager::DrawVertexArray(int stride) { if (IndexGenerator::GetNumTriangles() > 0) { @@ -350,7 +350,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - int stride = g_nativeVertexFmt->GetVertexStride(); + u32 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");}); @@ -362,9 +362,9 @@ void VertexManager::vFlush() goto shader_fail; } - PrepareVBuffers(stride); + PrepareDrawBuffers(stride); g_nativeVertexFmt->SetupVertexPointers(); - if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} + if(m_buffers_count){ DrawVertexBuffer(stride);} else { DrawVertexArray(stride);} bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; @@ -377,16 +377,16 @@ void VertexManager::vFlush() } // update alpha only g_renderer->ApplyState(true); - if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} + if(m_buffers_count){ DrawVertexBuffer(stride);} else { DrawVertexArray(stride);} g_renderer->RestoreState(); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); shader_fail: - if(NumVBuffers) + if(m_buffers_count) { - CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride; + m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; } ResetBuffer(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index aa4e9ed57b..51cf9b953d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -34,18 +34,18 @@ public: void CreateDeviceObjects(); void DestroyDeviceObjects(); private: - u32 CurrentVBufferIndex; - u32 CurrentVBufferSize; - u32 CurrentIBufferIndex; - u32 CurrentIBufferSize; - u32 NumVBuffers; - u32 CurrentVBuffer; - u32 CurrentIBuffer; - LPDIRECT3DVERTEXBUFFER9 *VBuffers; - LPDIRECT3DINDEXBUFFER9 *IBuffers; - void PrepareVBuffers(int stride); - void DrawVB(int stride); - void DrawVA(int stride); + u32 m_vertex_buffer_cursor; + u32 m_vertex_buffer_size; + u32 m_index_buffer_cursor; + u32 m_index_buffer_size; + u32 m_buffers_count; + u32 m_current_vertex_buffer; + u32 m_current_index_buffer; + LPDIRECT3DVERTEXBUFFER9 *m_vertex_buffers; + LPDIRECT3DINDEXBUFFER9 *m_index_buffers; + void PrepareDrawBuffers(u32 stride); + void DrawVertexBuffer(int stride); + void DrawVertexArray(int stride); // temp void vFlush(); }; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index ae20649433..3a98332562 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -53,20 +53,6 @@ DECLARE_IMPORT(glColorPointer); DECLARE_IMPORT(glTexCoordPointer); #endif -class GLVertexFormat : public NativeVertexFormat -{ - u8 *m_compiledCode; - PortableVertexDeclaration vtx_decl; - -public: - GLVertexFormat(); - ~GLVertexFormat(); - - virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); - virtual void SetupVertexPointers(); - virtual void EnableComponents(u32 components); -}; - namespace OGL { @@ -75,8 +61,6 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat() return new GLVertexFormat(); } -} - GLVertexFormat::GLVertexFormat() { #ifdef USE_JIT @@ -221,6 +205,46 @@ void GLVertexFormat::SetupVertexPointers() { #endif } +void GLVertexFormat::SetupVertexPointersOffset(u32 offset) { + // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to + // get around type checking errors, and call it. +#ifdef USE_JIT + ((void (*)())(void*)m_compiledCode)(); +#else + glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (GLvoid*)offset); + if (vtx_decl.num_normals >= 1) { + glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[0])); + if (vtx_decl.num_normals == 3) { + glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[1])); + glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[2])); + } + } + + for (int i = 0; i < 2; i++) { + if (vtx_decl.color_offset[i] != -1) { + if (i == 0) + glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.color_offset[i])); + else { + glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.color_offset[i])); + } + } + } + + for (int i = 0; i < 8; i++) { + if (vtx_decl.texcoord_offset[i] != -1) { + int id = GL_TEXTURE0 + i; + glClientActiveTexture(id); + glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), + vtx_decl.stride, (GLvoid*)(offset + vtx_decl.texcoord_offset[i])); + } + } + + if (vtx_decl.posmtx_offset != -1) { + glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.posmtx_offset)); + } +#endif +} + void GLVertexFormat::EnableComponents(u32 components) { if (s_prevcomponents != components) @@ -284,3 +308,7 @@ void GLVertexFormat::EnableComponents(u32 components) s_prevcomponents = components; } } + + +} + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 501c4969e5..03927413d8 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -48,38 +48,194 @@ extern NativeVertexFormat *g_nativeVertexFmt; namespace OGL { - -//static GLint max_Index_size = 0; - -//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0}; -//static int s_nCurVBOIndex = 0; // current free buffer +//This are the initially requeted size for the buffers expresed in bytes +const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); +const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; +const u32 MAX_VBUFFER_COUNT = 2; VertexManager::VertexManager() { - // TODO: doesn't seem to be used anywhere + CreateDeviceObjects(); +} - //glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); - // - //if (max_Index_size > MAXIBUFFERSIZE) - // max_Index_size = MAXIBUFFERSIZE; - // - //GL_REPORT_ERRORD(); - - glEnableClientState(GL_VERTEX_ARRAY); - GL_REPORT_ERRORD(); +VertexManager::~VertexManager() +{ + DestroyDeviceObjects(); } void VertexManager::CreateDeviceObjects() { - + m_buffers_count = 0; + m_vertex_buffers = NULL; + m_index_buffers = NULL; + glEnableClientState(GL_VERTEX_ARRAY); + GL_REPORT_ERRORD(); + int max_Index_size = 0; + int max_Vertex_size = 0; + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); + glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*)&max_Vertex_size); + max_Index_size *= sizeof(u16); + GL_REPORT_ERROR(); + m_index_buffer_size = IBUFFER_SIZE; + if (max_Index_size > 0 && max_Index_size < m_index_buffer_size) + m_index_buffer_size = max_Index_size; + + m_vertex_buffer_size = VBUFFER_SIZE; + if (max_Vertex_size > 0 && max_Vertex_size < m_vertex_buffer_size) + m_vertex_buffer_size = max_Vertex_size; + + if (m_index_buffer_size < VertexManager::MAXIBUFFERSIZE || m_vertex_buffer_size < VertexManager::MAXVBUFFERSIZE) + { + return; + } + + m_vertex_buffers = new GLuint[MAX_VBUFFER_COUNT]; + m_index_buffers = new GLuint[MAX_VBUFFER_COUNT]; + + glGenBuffers(MAX_VBUFFER_COUNT, m_vertex_buffers); + GL_REPORT_ERROR(); + glGenBuffers(MAX_VBUFFER_COUNT, m_index_buffers); + GL_REPORT_ERROR(); + for (u32 i = 0; i < MAX_VBUFFER_COUNT; i++) + { + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[i] ); + GL_REPORT_ERROR(); + glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + } + for (u32 i = 0; i < MAX_VBUFFER_COUNT; i++) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[i] ); + GL_REPORT_ERROR(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + } + m_buffers_count = MAX_VBUFFER_COUNT; + m_current_index_buffer = 0; + m_current_vertex_buffer = 0; + m_index_buffer_cursor = 0; + m_vertex_buffer_cursor = 0; } void VertexManager::DestroyDeviceObjects() { - + glDisableClientState(GL_VERTEX_ARRAY); + GL_REPORT_ERRORD(); + glBindBuffer(GL_ARRAY_BUFFER, NULL ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL ); + GL_REPORT_ERROR(); + if(m_vertex_buffers) + { + glDeleteBuffers(MAX_VBUFFER_COUNT, m_vertex_buffers); + GL_REPORT_ERROR(); + delete [] m_vertex_buffers; + } + if(m_index_buffers) + { + glDeleteBuffers(MAX_VBUFFER_COUNT, m_index_buffers); + GL_REPORT_ERROR(); + delete [] m_index_buffers; + } + m_vertex_buffers = NULL; + m_index_buffers = NULL; } -void VertexManager::Draw() +void VertexManager::PrepareDrawBuffers(u32 stride) +{ + if (!m_buffers_count) + { + return; + } + u8* pVertices = NULL; + u16* pIndices = NULL; + int vertex_data_size = IndexGenerator::GetNumVerts() * stride; + int triangle_index_size = IndexGenerator::GetTriangleindexLen() * sizeof(u16); + int line_index_size = IndexGenerator::GetLineindexLen() * sizeof(u16); + int point_index_size = IndexGenerator::GetPointindexLen() * sizeof(u16); + int index_data_size = triangle_index_size + line_index_size + point_index_size; + GLbitfield LockMode = GL_MAP_WRITE_BIT; + if (m_vertex_buffer_cursor > m_vertex_buffer_size - vertex_data_size) + { + LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; + m_vertex_buffer_cursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + } + else + { + LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + } + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]); + if(GLEW_ARB_map_buffer_range) + { + pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); + if(pVertices) + { + memcpy(pVertices, LocalVBuffer, vertex_data_size); + glUnmapBuffer(GL_ARRAY_BUFFER); + } + else + { + glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer); + } + } + else + { + glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer); + } + + LockMode = GL_MAP_WRITE_BIT; + + if (m_index_buffer_cursor > m_index_buffer_size - index_data_size) + { + LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } + else + { + LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]); + if(GLEW_ARB_map_buffer_range) + { + pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode); + if(pIndices) + { + if(triangle_index_size) + { + memcpy(pIndices, TIBuffer, triangle_index_size); + pIndices += triangle_index_size; + } + if(line_index_size) + { + memcpy(pIndices, LIBuffer, line_index_size); + pIndices += line_index_size; + } + if(point_index_size) + { + memcpy(pIndices, PIBuffer, point_index_size); + } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + } + else + { + if(triangle_index_size) + { + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer); + } + if(line_index_size) + { + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer); + } + if(point_index_size) + { + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer); + } + } + } +} + +void VertexManager::DrawVertexArray() { if (IndexGenerator::GetNumTriangles() > 0) { @@ -98,6 +254,31 @@ void VertexManager::Draw() } } +void VertexManager::DrawVertexBufferObject() +{ + int triangle_index_size = IndexGenerator::GetTriangleindexLen(); + int line_index_size = IndexGenerator::GetLineindexLen(); + int point_index_size = IndexGenerator::GetPointindexLen(); + int StartIndex = m_index_buffer_cursor; + if (triangle_index_size > 0) + { + glDrawElements(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (line_index_size > 0) + { + StartIndex += triangle_index_size * sizeof(u16); + glDrawElements(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (point_index_size > 0) + { + StartIndex += line_index_size * sizeof(u16); + glDrawElements(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } +} + void VertexManager::vFlush() { if (LocalVBuffer == s_pCurBufferPointer) return; @@ -134,13 +315,17 @@ void VertexManager::vFlush() (void)GL_REPORT_ERROR(); - //glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); - //glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW); - GL_REPORT_ERRORD(); + u32 stride = g_nativeVertexFmt->GetVertexStride(); - // setup the pointers - if (g_nativeVertexFmt) + PrepareDrawBuffers(stride); + if(m_buffers_count) + { + ((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(m_vertex_buffer_cursor); + } + else + { g_nativeVertexFmt->SetupVertexPointers(); + } GL_REPORT_ERRORD(); u32 usedtextures = 0; @@ -153,7 +338,7 @@ void VertexManager::vFlush() if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); - for (int i = 0; i < 8; i++) + for (u32 i = 0; i < 8; i++) { if (usedtextures & (1 << i)) { @@ -217,7 +402,7 @@ void VertexManager::vFlush() if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); - Draw(); + if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();}; // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) @@ -230,7 +415,7 @@ void VertexManager::vFlush() glDisable(GL_BLEND); - Draw(); + if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();}; // restore color mask g_renderer->SetColorMask(); @@ -238,11 +423,12 @@ void VertexManager::vFlush() glEnable(GL_BLEND); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); - - //s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers); - s_pCurBufferPointer = LocalVBuffer; - IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); - + if(m_buffers_count) + { + m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + } + ResetBuffer(); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 5cec1bf97e..ac45151999 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -24,6 +24,20 @@ namespace OGL { + class GLVertexFormat : public NativeVertexFormat + { + u8 *m_compiledCode; + PortableVertexDeclaration vtx_decl; + + public: + GLVertexFormat(); + ~GLVertexFormat(); + + virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); + virtual void SetupVertexPointers(); + virtual void SetupVertexPointersOffset(u32 offset); + virtual void EnableComponents(u32 components); + }; // Handles the OpenGL details of drawing lots of vertices quickly. // Other functionality is moving out. @@ -31,14 +45,24 @@ class VertexManager : public ::VertexManager { public: VertexManager(); - + ~VertexManager(); NativeVertexFormat* CreateNativeVertexFormat(); void CreateDeviceObjects(); void DestroyDeviceObjects(); private: - void Draw(); - // temp + void DrawVertexArray(); + void DrawVertexBufferObject(); void vFlush(); + void PrepareDrawBuffers(u32 stride); + u32 m_vertex_buffer_cursor; + u32 m_vertex_buffer_size; + u32 m_index_buffer_cursor; + u32 m_index_buffer_size; + u32 m_buffers_count; + u32 m_current_vertex_buffer; + u32 m_current_index_buffer; + GLuint* m_vertex_buffers; + GLuint* m_index_buffers; }; } From ee72852491dfa2c6246d9e2808b782444e2ce4ca Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Fri, 26 Oct 2012 23:18:09 -0300 Subject: [PATCH 2/7] implement some code to reduce the amounts of calls to setup vertex format, in d3d9 it gives no noticeable speedup, in opengl it still does not work right. thanks to neobrain for the idea --- .../VideoCommon/Src/VertexManagerBase.cpp | 3 + .../Plugin_VideoDX11/Src/VertexManager.cpp | 3 - .../Plugins/Plugin_VideoDX9/Src/D3DBase.cpp | 226 +++++++++++++----- Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h | 11 + .../Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp | 30 ++- .../Plugin_VideoDX9/Src/VertexManager.cpp | 43 ++-- .../Plugin_VideoDX9/Src/VertexManager.h | 1 + .../Plugin_VideoOGL/Src/VertexManager.cpp | 96 ++++++-- .../Plugin_VideoOGL/Src/VertexManager.h | 2 + 9 files changed, 305 insertions(+), 110 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 4118e3dcbd..7c1fe9ff6c 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -159,6 +159,9 @@ void VertexManager::AddVertices(int primitive, int numVertices) void VertexManager::Flush() { + if (LocalVBuffer == s_pCurBufferPointer) return; + if (Flushed) return; + Flushed = true; g_vertex_manager->vFlush(); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 48f84b9aca..347d294eb7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -211,9 +211,6 @@ void VertexManager::Draw(UINT stride) void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed=true; VideoFifo_CheckEFBAccess(); u32 usedtextures = 0; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp index ff3f68a6cd..31466d1c84 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp @@ -66,6 +66,7 @@ static int numAdapters; static int cur_adapter; // Value caches for state filtering +const int MaxStreamSources = 16; const int MaxTextureStages = 9; const int MaxRenderStates = 210 + 46; const int MaxTextureTypes = 33; @@ -83,10 +84,23 @@ static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes]; static bool m_SamplerStatesSet[MaxSamplerSize][MaxSamplerTypes]; static bool m_SamplerStatesChanged[MaxSamplerSize][MaxSamplerTypes]; -LPDIRECT3DBASETEXTURE9 m_Textures[16]; -LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl; -LPDIRECT3DPIXELSHADER9 m_PixelShader; -LPDIRECT3DVERTEXSHADER9 m_VertexShader; +static LPDIRECT3DBASETEXTURE9 m_Textures[16]; +static LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl; +static bool m_VtxDeclChanged; +static LPDIRECT3DPIXELSHADER9 m_PixelShader; +static bool m_PixelShaderChanged; +static LPDIRECT3DVERTEXSHADER9 m_VertexShader; +static bool m_VertexShaderChanged; +struct StreamSourceDescriptor +{ + LPDIRECT3DVERTEXBUFFER9 pStreamData; + UINT OffsetInBytes; + UINT Stride; +}; +static StreamSourceDescriptor m_stream_sources[MaxStreamSources]; +static bool m_stream_sources_Changed[MaxStreamSources]; +static LPDIRECT3DINDEXBUFFER9 m_index_buffer; +static bool m_index_buffer_Changed; // Z buffer formats to be used for EFB depth surface D3DFORMAT DepthFormats[] = { @@ -170,9 +184,9 @@ void EnableAlphaToCoverage() { // Each vendor has their own specific little hack. if (GetCurAdapter().ident.VendorId == VENDOR_ATI) - D3D::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1')); + SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1')); else - D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); + SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); } void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) @@ -215,14 +229,14 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) void Enumerate() { - numAdapters = D3D::D3D->GetAdapterCount(); + numAdapters = D3D->GetAdapterCount(); for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++) { Adapter &a = adapters[i]; a.aa_levels.clear(); a.resolutions.clear(); - D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident); + D3D->GetAdapterIdentifier(i, 0, &a.ident); bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA; // Add SuperSamples modes @@ -233,17 +247,17 @@ void Enumerate() //disable them will they are not implemnted /* DWORD qlevels = 0; - if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( + if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) if (qlevels > 0) a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0)); - if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( + if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) if (qlevels > 0) a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0)); - if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( + if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) if (qlevels > 0) a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); @@ -251,7 +265,7 @@ void Enumerate() if (isNvidia) { // CSAA support - if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( + if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels)) { if (qlevels > 2) @@ -262,7 +276,7 @@ void Enumerate() a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); } } - if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( + if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) { if (qlevels > 2) @@ -296,11 +310,11 @@ void Enumerate() { strcpy(a.aa_levels[0].name, "(Not supported on this device)"); } - int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8); + int numModes = D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8); for (int m = 0; m < numModes; m++) { D3DDISPLAYMODE mode; - D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode); + D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode); int found = -1; for (int x = 0; x < (int)a.resolutions.size(); x++) @@ -440,8 +454,8 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de dev->GetRenderTarget(0, &back_buffer); if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) back_buffer_z = NULL; - D3D::SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE ); - D3D::SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); + SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE ); + SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); memset(m_Textures, 0, sizeof(m_Textures)); memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet)); memset(m_RenderStatesSet, 0, sizeof(m_RenderStatesSet)); @@ -452,6 +466,15 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de m_VtxDecl = NULL; m_PixelShader = NULL; m_VertexShader = NULL; + m_index_buffer = NULL; + memset(m_stream_sources, 0, sizeof(m_stream_sources)); + m_index_buffer = NULL; + + m_VtxDeclChanged = false; + m_PixelShaderChanged = false; + m_VertexShaderChanged = false; + memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed)); + m_index_buffer_Changed = false; // Device state would normally be set here return S_OK; } @@ -516,7 +539,7 @@ bool CheckDepthStencilSupport(D3DFORMAT target_format, D3DFORMAT depth_format) D3DFORMAT GetSupportedDepthTextureFormat() { for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) - if (D3D::CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i])) + if (CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i])) return DepthFormats[i]; return D3DFMT_UNKNOWN; @@ -525,7 +548,7 @@ D3DFORMAT GetSupportedDepthTextureFormat() D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format) { for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) - if (D3D::CheckDepthStencilSupport(target_format, DepthFormats[i])) + if (CheckDepthStencilSupport(target_format, DepthFormats[i])) return DepthFormats[i]; return D3DFMT_UNKNOWN; @@ -533,13 +556,13 @@ D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format) const char *VertexShaderVersionString() { - int version = ((D3D::caps.VertexShaderVersion >> 8) & 0xFF); + int version = ((caps.VertexShaderVersion >> 8) & 0xFF); return vsVersions[std::min(4, version)]; } const char *PixelShaderVersionString() { - int version = ((D3D::caps.PixelShaderVersion >> 8) & 0xFF); + int version = ((caps.PixelShaderVersion >> 8) & 0xFF); return psVersions[std::min(4, version)]; } @@ -653,14 +676,14 @@ void ApplyCachedState() for (int type = 0; type < MaxSamplerTypes; type++) { if(m_SamplerStatesSet[sampler][type]) - D3D::dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]); + dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]); } } for (int rs = 0; rs < MaxRenderStates; rs++) { if (m_RenderStatesSet[rs]) - D3D::dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]); + dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]); } // We don't bother restoring these so let's just wipe the state copy @@ -671,6 +694,13 @@ void ApplyCachedState() m_VtxDecl = NULL; m_PixelShader = NULL; m_VertexShader = NULL; + memset(m_stream_sources, 0, sizeof(m_stream_sources)); + m_index_buffer = NULL; + m_VtxDeclChanged = false; + m_PixelShaderChanged = false; + m_VertexShaderChanged = false; + memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed)); + m_index_buffer_Changed = false; } void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) @@ -678,7 +708,7 @@ void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) if (m_Textures[Stage] != pTexture) { m_Textures[Stage] = pTexture; - D3D::dev->SetTexture(Stage, pTexture); + dev->SetTexture(Stage, pTexture); } } @@ -686,7 +716,7 @@ void RefreshRenderState(D3DRENDERSTATETYPE State) { if(m_RenderStatesSet[State] && m_RenderStatesChanged[State]) { - D3D::dev->SetRenderState(State, m_RenderStates[State]); + dev->SetRenderState(State, m_RenderStates[State]); m_RenderStatesChanged[State] = false; } } @@ -698,7 +728,7 @@ void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) m_RenderStates[State] = Value; m_RenderStatesSet[State] = true; m_RenderStatesChanged[State] = false; - D3D::dev->SetRenderState(State, Value); + dev->SetRenderState(State, Value); } } @@ -707,7 +737,7 @@ void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value) if (m_RenderStates[State] != Value || !m_RenderStatesSet[State]) { m_RenderStatesChanged[State] = m_RenderStatesSet[State]; - D3D::dev->SetRenderState(State, Value); + dev->SetRenderState(State, Value); } else { @@ -722,7 +752,7 @@ void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Valu m_TextureStageStates[Stage][Type] = Value; m_TextureStageStatesSet[Stage][Type]=true; m_TextureStageStatesChanged[Stage][Type]=false; - D3D::dev->SetTextureStageState(Stage, Type, Value); + dev->SetTextureStageState(Stage, Type, Value); } } @@ -730,7 +760,7 @@ void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type) { if(m_TextureStageStatesSet[Stage][Type] && m_TextureStageStatesChanged[Stage][Type]) { - D3D::dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]); + dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]); m_TextureStageStatesChanged[Stage][Type] = false; } } @@ -740,7 +770,7 @@ void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD V if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type]) { m_TextureStageStatesChanged[Stage][Type] = m_TextureStageStatesSet[Stage][Type]; - D3D::dev->SetTextureStageState(Stage, Type, Value); + dev->SetTextureStageState(Stage, Type, Value); } else { @@ -755,7 +785,7 @@ void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) m_SamplerStates[Sampler][Type] = Value; m_SamplerStatesSet[Sampler][Type] = true; m_SamplerStatesChanged[Sampler][Type] = false; - D3D::dev->SetSamplerState(Sampler, Type, Value); + dev->SetSamplerState(Sampler, Type, Value); } } @@ -763,7 +793,7 @@ void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type) { if(m_SamplerStatesSet[Sampler][Type] && m_SamplerStatesChanged[Sampler][Type]) { - D3D::dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]); + dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]); m_SamplerStatesChanged[Sampler][Type] = false; } } @@ -773,7 +803,7 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type]) { m_SamplerStatesChanged[Sampler][Type] = m_SamplerStatesSet[Sampler][Type]; - D3D::dev->SetSamplerState(Sampler, Type, Value); + dev->SetSamplerState(Sampler, Type, Value); } else { @@ -783,67 +813,155 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) void RefreshVertexDeclaration() { - if (m_VtxDecl) + if (m_VtxDeclChanged) { - D3D::dev->SetVertexDeclaration(m_VtxDecl); + dev->SetVertexDeclaration(m_VtxDecl); + m_VtxDeclChanged = false; } } void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl) { - if (!decl) { - m_VtxDecl = NULL; - return; - } if (decl != m_VtxDecl) { - D3D::dev->SetVertexDeclaration(decl); + dev->SetVertexDeclaration(decl); m_VtxDecl = decl; + m_VtxDeclChanged = false; + } +} + +void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl) +{ + if (decl != m_VtxDecl) { + dev->SetVertexDeclaration(decl); + m_VtxDeclChanged = true; + } +} + +void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader) +{ + if (shader != m_VertexShader) + { + dev->SetVertexShader(shader); + m_VertexShaderChanged = true; } } void RefreshVertexShader() { - if (m_VertexShader) + if (m_VertexShaderChanged) { - D3D::dev->SetVertexShader(m_VertexShader); + dev->SetVertexShader(m_VertexShader); + m_VertexShaderChanged = false; } } void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader) { - if (!shader) { - m_VertexShader = NULL; - return; - } if (shader != m_VertexShader) { - D3D::dev->SetVertexShader(shader); + dev->SetVertexShader(shader); m_VertexShader = shader; + m_VertexShaderChanged = false; } } void RefreshPixelShader() { - if (m_PixelShader) + if (m_PixelShaderChanged) { - D3D::dev->SetPixelShader(m_PixelShader); + dev->SetPixelShader(m_PixelShader); + m_PixelShaderChanged = false; } } void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader) { - if (!shader) { - m_PixelShader = NULL; - return; - } if (shader != m_PixelShader) { - D3D::dev->SetPixelShader(shader); + dev->SetPixelShader(shader); m_PixelShader = shader; + m_PixelShaderChanged = false; } } +void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader) +{ + if (shader != m_PixelShader) + { + dev->SetPixelShader(shader); + m_PixelShaderChanged = true; + } +} + +void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) +{ + if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes + || m_stream_sources[StreamNumber].pStreamData != pStreamData + || m_stream_sources[StreamNumber].Stride != Stride) + { + m_stream_sources[StreamNumber].OffsetInBytes = OffsetInBytes; + m_stream_sources[StreamNumber].pStreamData = pStreamData; + m_stream_sources[StreamNumber].Stride = Stride; + dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); + m_stream_sources_Changed[StreamNumber] = false; + } +} + +void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) +{ + if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes + || m_stream_sources[StreamNumber].pStreamData != pStreamData + || m_stream_sources[StreamNumber].Stride != Stride) + { + dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); + m_stream_sources_Changed[StreamNumber] = true; + } + +} + +void RefreshStreamSource(UINT StreamNumber) +{ + if (m_PixelShaderChanged) + { + dev->SetStreamSource( + StreamNumber, + m_stream_sources[StreamNumber].pStreamData, + m_stream_sources[StreamNumber].OffsetInBytes, + m_stream_sources[StreamNumber].Stride); + m_stream_sources_Changed[StreamNumber] = false; + } +} + +void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData) +{ + if(pIndexData != m_index_buffer) + { + m_index_buffer = pIndexData; + dev->SetIndices(pIndexData); + m_index_buffer_Changed = false; + } +} + +void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData) +{ + if(pIndexData != m_index_buffer) + { + dev->SetIndices(pIndexData); + m_index_buffer_Changed = true; + } +} + +void RefreshIndices() +{ + if (m_index_buffer_Changed) + { + dev->SetIndices(m_index_buffer); + m_index_buffer_Changed = false; + } +} + + } // namespace diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h index d1e7eeaa91..7be482a55f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h @@ -100,12 +100,23 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); void RefreshVertexDeclaration(); void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl); +void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl); void RefreshVertexShader(); void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader); +void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader); void RefreshPixelShader(); void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader); +void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader); + +void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); +void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); +void RefreshStreamSource(UINT StreamNumber); + +void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData); +void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData); +void RefreshIndices(); void ApplyCachedState(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp index 9510ad444c..222d7849d0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp @@ -198,6 +198,8 @@ const int TS[6][2] = void RestoreShaders() { D3D::SetTexture(0, 0); + D3D::RefreshStreamSource(0); + D3D::RefreshIndices(); D3D::RefreshVertexDeclaration(); D3D::RefreshPixelShader(); D3D::RefreshVertexShader(); @@ -217,9 +219,9 @@ void CD3DFont::SetRenderStates() { D3D::SetTexture(0, m_pTexture); - dev->SetPixelShader(0); - dev->SetVertexShader(0); - + D3D::ChangePixelShader(0); + D3D::ChangeVertexShader(0); + D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_FONT2DVERTEX); for (int i = 0; i < 6; i++) @@ -236,7 +238,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo return 0; SetRenderStates(); - dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); + D3D::SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); float vpWidth = 1; float vpHeight = 1; @@ -389,9 +391,10 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture, { 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g}, { 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g} }; - dev->SetVertexShader(Vshader); - dev->SetPixelShader(PShader); + D3D::ChangeVertexShader(Vshader); + D3D::ChangePixelShader(PShader); D3D::SetTexture(0, texture); + D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); @@ -424,9 +427,10 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture, { rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g}, { rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g} }; - dev->SetVertexShader(Vshader); - dev->SetPixelShader(PShader); + D3D::ChangeVertexShader(Vshader); + D3D::ChangePixelShader(PShader); D3D::SetTexture(0, texture); + D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); @@ -442,8 +446,9 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2) { x1, y1, 0.f, 1.f, Color }, { x2, y1, 0.f, 1.f, Color }, }; - dev->SetVertexShader(VertexShaderCache::GetClearVertexShader()); - dev->SetPixelShader(PixelShaderCache::GetClearProgram()); + D3D::ChangeVertexShader(VertexShaderCache::GetClearVertexShader()); + D3D::ChangePixelShader(PixelShaderCache::GetClearProgram()); + D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex)); RestoreShaders(); @@ -457,8 +462,9 @@ void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVer { 1.0f, -1.0f, z, 1.0f, Color}, {-1.0f, -1.0f, z, 1.0f, Color} }; - dev->SetVertexShader(Vshader); - dev->SetPixelShader(PShader); + D3D::ChangeVertexShader(Vshader); + D3D::ChangePixelShader(PShader); + D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 884f16f826..874fc6316c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -105,7 +105,7 @@ void VertexManager::CreateDeviceObjects() m_current_index_buffer = 0; m_index_buffer_cursor = m_index_buffer_size; m_vertex_buffer_cursor = m_vertex_buffer_size; - + m_current_stride = 0; if (Fail) { m_buffers_count--; @@ -119,8 +119,8 @@ void VertexManager::CreateDeviceObjects() } void VertexManager::DestroyDeviceObjects() { - D3D::dev->SetStreamSource( 0, NULL, 0, 0); - D3D::dev->SetIndices(NULL); + D3D::SetStreamSource( 0, NULL, 0, 0); + D3D::SetIndices(NULL); for (int i = 0; i < MAX_VBUFFER_COUNT; i++) { if(m_vertex_buffers) @@ -160,14 +160,14 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int PDataSize = IndexGenerator::GetPointindexLen(); int IndexDataSize = TdataSize + LDataSize + PDataSize; DWORD LockMode = D3DLOCK_NOOVERWRITE; - + m_vertex_buffer_cursor--; + m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) { LockMode = D3DLOCK_DISCARD; m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - } - + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + } if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) { DestroyDeviceObjects(); @@ -177,13 +177,12 @@ void VertexManager::PrepareDrawBuffers(u32 stride) m_vertex_buffers[m_current_vertex_buffer]->Unlock(); LockMode = D3DLOCK_NOOVERWRITE; - if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) { LockMode = D3DLOCK_DISCARD; m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) { @@ -204,12 +203,16 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); } - m_index_buffers[m_current_index_buffer]->Unlock(); - D3D::dev->SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], m_vertex_buffer_cursor, stride); - if(m_index_buffer_cursor == 0) + if(m_current_stride != stride || m_vertex_buffer_cursor == 0) { - D3D::dev->SetIndices(m_index_buffers[m_current_index_buffer]); + m_current_stride = stride; + D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride); } + if (m_index_buffer_cursor == 0) + { + D3D::SetIndices(m_index_buffers[m_current_index_buffer]); + } + m_index_buffers[m_current_index_buffer]->Unlock(); } void VertexManager::DrawVertexBuffer(int stride) @@ -217,8 +220,8 @@ void VertexManager::DrawVertexBuffer(int stride) if (IndexGenerator::GetNumTriangles() > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, + D3DPT_TRIANGLELIST, + m_vertex_buffer_cursor / stride, 0, IndexGenerator::GetNumVerts(), m_index_buffer_cursor, @@ -232,7 +235,7 @@ void VertexManager::DrawVertexBuffer(int stride) { if (FAILED(D3D::dev->DrawIndexedPrimitive( D3DPT_LINELIST, - 0, + m_vertex_buffer_cursor / stride, 0, IndexGenerator::GetNumVerts(), m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen(), @@ -246,7 +249,7 @@ void VertexManager::DrawVertexBuffer(int stride) { if (FAILED(D3D::dev->DrawIndexedPrimitive( D3DPT_POINTLIST, - 0, + m_vertex_buffer_cursor / stride, 0, IndexGenerator::GetNumVerts(), m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), @@ -307,11 +310,7 @@ void VertexManager::DrawVertexArray(int stride) void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed = true; VideoFifo_CheckEFBAccess(); - u32 usedtextures = 0; for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) if (bpmem.tevorders[i / 2].getEnable(i & 1)) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index 51cf9b953d..2a165aa9af 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -40,6 +40,7 @@ private: u32 m_index_buffer_size; u32 m_buffers_count; u32 m_current_vertex_buffer; + u32 m_current_stride; u32 m_current_index_buffer; LPDIRECT3DVERTEXBUFFER9 *m_vertex_buffers; LPDIRECT3DINDEXBUFFER9 *m_index_buffers; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 03927413d8..2bd5936099 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -114,8 +114,9 @@ void VertexManager::CreateDeviceObjects() m_buffers_count = MAX_VBUFFER_COUNT; m_current_index_buffer = 0; m_current_vertex_buffer = 0; - m_index_buffer_cursor = 0; - m_vertex_buffer_cursor = 0; + m_index_buffer_cursor = m_index_buffer_size; + m_vertex_buffer_cursor = m_vertex_buffer_size; + m_CurrentVertexFmt = NULL; } void VertexManager::DestroyDeviceObjects() { @@ -153,18 +154,20 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen() * sizeof(u16); int point_index_size = IndexGenerator::GetPointindexLen() * sizeof(u16); int index_data_size = triangle_index_size + line_index_size + point_index_size; - GLbitfield LockMode = GL_MAP_WRITE_BIT; + GLbitfield LockMode = GL_MAP_WRITE_BIT; + m_vertex_buffer_cursor--; + m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; if (m_vertex_buffer_cursor > m_vertex_buffer_size - vertex_data_size) { LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; m_vertex_buffer_cursor = 0; m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]); } else { LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - } - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]); + } if(GLEW_ARB_map_buffer_range) { pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); @@ -189,13 +192,13 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]); } else { LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]); + } if(GLEW_ARB_map_buffer_range) { pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode); @@ -279,11 +282,33 @@ void VertexManager::DrawVertexBufferObject() } } +void VertexManager::DrawVertexBufferObjectBase(u32 stride) +{ + int triangle_index_size = IndexGenerator::GetTriangleindexLen(); + int line_index_size = IndexGenerator::GetLineindexLen(); + int point_index_size = IndexGenerator::GetPointindexLen(); + int StartIndex = m_index_buffer_cursor; + if (triangle_index_size > 0) + { + glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (line_index_size > 0) + { + StartIndex += triangle_index_size * sizeof(u16); + glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (point_index_size > 0) + { + StartIndex += line_index_size * sizeof(u16); + glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } +} + void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed=true; VideoFifo_CheckEFBAccess(); #if defined(_DEBUG) || defined(DEBUGFAST) PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens, @@ -318,13 +343,18 @@ void VertexManager::vFlush() u32 stride = g_nativeVertexFmt->GetVertexStride(); PrepareDrawBuffers(stride); - if(m_buffers_count) + //still testing if this line is enabled to reduce the amount of vertex setup call everything goes wrong + //if(m_CurrentVertexFmt != g_nativeVertexFmt || !GLEW_ARB_draw_elements_base_vertex ) { - ((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(m_vertex_buffer_cursor); - } - else - { - g_nativeVertexFmt->SetupVertexPointers(); + if(m_buffers_count) + { + ((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(GLEW_ARB_draw_elements_base_vertex ? 0 : m_vertex_buffer_cursor); + } + else + { + g_nativeVertexFmt->SetupVertexPointers(); + } + m_CurrentVertexFmt = g_nativeVertexFmt; } GL_REPORT_ERRORD(); @@ -402,7 +432,21 @@ void VertexManager::vFlush() if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); - if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();}; + if(m_buffers_count) + { + if(GLEW_ARB_draw_elements_base_vertex) + { + DrawVertexBufferObjectBase(stride); + } + else + { + DrawVertexBufferObject(); + } + } + else + { + DrawVertexArray(); + } // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) @@ -415,7 +459,21 @@ void VertexManager::vFlush() glDisable(GL_BLEND); - if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();}; + if(m_buffers_count) + { + if(GLEW_ARB_draw_elements_base_vertex) + { + DrawVertexBufferObjectBase(stride); + } + else + { + DrawVertexBufferObject(); + } + } + else + { + DrawVertexArray(); + } // restore color mask g_renderer->SetColorMask(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index ac45151999..db80f87a2b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -52,6 +52,7 @@ public: private: void DrawVertexArray(); void DrawVertexBufferObject(); + void DrawVertexBufferObjectBase(u32 stride); void vFlush(); void PrepareDrawBuffers(u32 stride); u32 m_vertex_buffer_cursor; @@ -63,6 +64,7 @@ private: u32 m_current_index_buffer; GLuint* m_vertex_buffers; GLuint* m_index_buffers; + NativeVertexFormat *m_CurrentVertexFmt; }; } From 53b62ab169b971627614b2e948e10b747e090015 Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Sat, 10 Nov 2012 11:37:08 -0300 Subject: [PATCH 3/7] This should fix the bugs introduced by my last commit please retest the games that where showing graphical glitches. --- .../Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp | 2 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 21 ++++++++++++++++--- .../Plugin_VideoOGL/Src/VertexManager.cpp | 17 ++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp index 222d7849d0..d24720e6f9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp @@ -238,7 +238,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo return 0; SetRenderStates(); - D3D::SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); + D3D::ChangeStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); float vpWidth = 1; float vpHeight = 1; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 874fc6316c..96ae538ff4 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -203,6 +203,7 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); } + m_index_buffers[m_current_index_buffer]->Unlock(); if(m_current_stride != stride || m_vertex_buffer_cursor == 0) { m_current_stride = stride; @@ -212,7 +213,7 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { D3D::SetIndices(m_index_buffers[m_current_index_buffer]); } - m_index_buffers[m_current_index_buffer]->Unlock(); + } void VertexManager::DrawVertexBuffer(int stride) @@ -363,7 +364,14 @@ void VertexManager::vFlush() } PrepareDrawBuffers(stride); g_nativeVertexFmt->SetupVertexPointers(); - if(m_buffers_count){ DrawVertexBuffer(stride);} else { DrawVertexArray(stride);} + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; @@ -376,7 +384,14 @@ void VertexManager::vFlush() } // update alpha only g_renderer->ApplyState(true); - if(m_buffers_count){ DrawVertexBuffer(stride);} else { DrawVertexArray(stride);} + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } g_renderer->RestoreState(); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 2bd5936099..462ddc1ff8 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -150,10 +150,10 @@ void VertexManager::PrepareDrawBuffers(u32 stride) u8* pVertices = NULL; u16* pIndices = NULL; int vertex_data_size = IndexGenerator::GetNumVerts() * stride; - int triangle_index_size = IndexGenerator::GetTriangleindexLen() * sizeof(u16); - int line_index_size = IndexGenerator::GetLineindexLen() * sizeof(u16); - int point_index_size = IndexGenerator::GetPointindexLen() * sizeof(u16); - int index_data_size = triangle_index_size + line_index_size + point_index_size; + int triangle_index_size = IndexGenerator::GetTriangleindexLen(); + int line_index_size = IndexGenerator::GetLineindexLen(); + int point_index_size = IndexGenerator::GetPointindexLen(); + int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16); GLbitfield LockMode = GL_MAP_WRITE_BIT; m_vertex_buffer_cursor--; m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; @@ -206,17 +206,17 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { if(triangle_index_size) { - memcpy(pIndices, TIBuffer, triangle_index_size); + memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16)); pIndices += triangle_index_size; } if(line_index_size) { - memcpy(pIndices, LIBuffer, line_index_size); + memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16)); pIndices += line_index_size; } if(point_index_size) { - memcpy(pIndices, PIBuffer, point_index_size); + memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16)); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } @@ -224,14 +224,17 @@ void VertexManager::PrepareDrawBuffers(u32 stride) { if(triangle_index_size) { + triangle_index_size *= sizeof(u16); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer); } if(line_index_size) { + line_index_size *= sizeof(u16); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer); } if(point_index_size) { + point_index_size *= sizeof(u16); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer); } } From 3936c06ee82a45f964d4fef77eb774e6e521114a Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Sun, 11 Nov 2012 22:39:27 -0300 Subject: [PATCH 4/7] more fixes for my last commit, player problem in twin snakes is fixed --- .../Plugin_VideoDX9/Src/VertexManager.cpp | 54 +++++++++++-------- .../Plugin_VideoOGL/Src/VertexManager.cpp | 33 ++++++------ 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 96ae538ff4..88fcca27cf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -218,43 +218,51 @@ void VertexManager::PrepareDrawBuffers(u32 stride) void VertexManager::DrawVertexBuffer(int stride) { - if (IndexGenerator::GetNumTriangles() > 0) + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + int StartIndex = m_index_buffer_cursor; + int basevertex = m_vertex_buffer_cursor / stride; + if (triangles > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, - m_vertex_buffer_cursor / stride, + basevertex, 0, - IndexGenerator::GetNumVerts(), - m_index_buffer_cursor, - IndexGenerator::GetNumTriangles()))) + numverts, + StartIndex, + triangles))) { DumpBadShaders(); } + StartIndex += IndexGenerator::GetTriangleindexLen(); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + if (lines > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitive( D3DPT_LINELIST, - m_vertex_buffer_cursor / stride, + basevertex, 0, - IndexGenerator::GetNumVerts(), - m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen(), + numverts, + StartIndex, IndexGenerator::GetNumLines()))) { DumpBadShaders(); } + StartIndex += IndexGenerator::GetLineindexLen(); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumPoints() > 0) + if (points > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitive( D3DPT_POINTLIST, - m_vertex_buffer_cursor / stride, + basevertex, 0, - IndexGenerator::GetNumVerts(), - m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), - IndexGenerator::GetNumPoints()))) + numverts, + StartIndex, + points))) { DumpBadShaders(); } @@ -264,12 +272,16 @@ void VertexManager::DrawVertexBuffer(int stride) } void VertexManager::DrawVertexArray(int stride) -{ - if (IndexGenerator::GetNumTriangles() > 0) +{ + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + if (triangles > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), + 0, numverts, triangles, TIBuffer, D3DFMT_INDEX16, LocalVBuffer, @@ -279,11 +291,11 @@ void VertexManager::DrawVertexArray(int stride) } INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + if (lines > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_LINELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), + 0, numverts, lines, LIBuffer, D3DFMT_INDEX16, LocalVBuffer, @@ -293,11 +305,11 @@ void VertexManager::DrawVertexArray(int stride) } INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumPoints() > 0) + if (points > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_POINTLIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), + 0, numverts, points, PIBuffer, D3DFMT_INDEX16, LocalVBuffer, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 462ddc1ff8..bbd196ba78 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -68,7 +68,6 @@ void VertexManager::CreateDeviceObjects() m_buffers_count = 0; m_vertex_buffers = NULL; m_index_buffers = NULL; - glEnableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); int max_Index_size = 0; @@ -243,17 +242,20 @@ void VertexManager::PrepareDrawBuffers(u32 stride) void VertexManager::DrawVertexArray() { - if (IndexGenerator::GetNumTriangles() > 0) + int triangle_index_size = IndexGenerator::GetTriangleindexLen(); + int line_index_size = IndexGenerator::GetLineindexLen(); + int point_index_size = IndexGenerator::GetPointindexLen(); + if (triangle_index_size > 0) { - glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); + glDrawElements(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, TIBuffer); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + if (line_index_size > 0) { - glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); + glDrawElements(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, LIBuffer); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumPoints() > 0) + if (point_index_size > 0) { glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); INCSTAT(stats.thisFrame.numIndexedDrawCalls); @@ -269,17 +271,17 @@ void VertexManager::DrawVertexBufferObject() if (triangle_index_size > 0) { glDrawElements(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); + StartIndex += triangle_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (line_index_size > 0) - { - StartIndex += triangle_index_size * sizeof(u16); + { glDrawElements(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); + StartIndex += line_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (point_index_size > 0) - { - StartIndex += line_index_size * sizeof(u16); + { glDrawElements(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } @@ -291,21 +293,22 @@ void VertexManager::DrawVertexBufferObjectBase(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen(); int point_index_size = IndexGenerator::GetPointindexLen(); int StartIndex = m_index_buffer_cursor; + int basevertex = m_vertex_buffer_cursor / stride; if (triangle_index_size > 0) { - glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); + StartIndex += triangle_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (line_index_size > 0) { - StartIndex += triangle_index_size * sizeof(u16); - glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); + StartIndex += line_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (point_index_size > 0) { - StartIndex += line_index_size * sizeof(u16); - glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride); + glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } } From 0809ba79ae12dd55bb5c2d7608fa24ca041c753a Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Mon, 12 Nov 2012 19:37:08 -0300 Subject: [PATCH 5/7] fix for point rendering in dx9 backend, that will teach me to read the full documentation. if someone founs a games that use points a lot i will try to implement a faster path for point rendering. now the map in twin snakes is functional in all the backends. --- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 12 +++++++++ .../Plugin_VideoDX9/Src/VertexManager.cpp | 27 +++++++++---------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index a59adb4793..b4625f0157 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -64,6 +64,7 @@ static int s_fps = 0; static u32 s_blendMode; static u32 s_LastAA; static bool IS_AMD; +static float m_fMaxPointSize; static char *st; @@ -329,6 +330,9 @@ Renderer::Renderer() D3D::BeginFrame(); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); + m_fMaxPointSize = D3D::GetCaps().MaxPointSize; + } Renderer::~Renderer() @@ -1301,7 +1305,15 @@ void Renderer::SetLineWidth() // We can't change line width in D3D unless we use ID3DXLine float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; float psize = bpmem.lineptwidth.linesize * fratio / 6.0f; + //little hack to compensate scalling problems in dx9 must be taken out when scalling is fixed. + psize *= 2.0f; + if (psize > m_fMaxPointSize) + { + psize = m_fMaxPointSize; + } D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); } void Renderer::SetSamplerState(int stage, int texindex) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 88fcca27cf..925617f3f5 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -158,7 +158,7 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int TdataSize = IndexGenerator::GetTriangleindexLen(); int LDataSize = IndexGenerator::GetLineindexLen(); int PDataSize = IndexGenerator::GetPointindexLen(); - int IndexDataSize = TdataSize + LDataSize + PDataSize; + int IndexDataSize = TdataSize + LDataSize; DWORD LockMode = D3DLOCK_NOOVERWRITE; m_vertex_buffer_cursor--; m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; @@ -199,10 +199,6 @@ void VertexManager::PrepareDrawBuffers(u32 stride) memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); pIndices += LDataSize; } - if(PDataSize) - { - memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); - } m_index_buffers[m_current_index_buffer]->Unlock(); if(m_current_stride != stride || m_vertex_buffer_cursor == 0) { @@ -256,17 +252,20 @@ void VertexManager::DrawVertexBuffer(int stride) } if (points > 0) { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_POINTLIST, - basevertex, - 0, - numverts, - StartIndex, - points))) + //DrawIndexedPrimitive does not support point list so we have to draw the points one by one + for (int i = 0; i < points; i++) { - DumpBadShaders(); + if (FAILED(D3D::dev->DrawPrimitive( + D3DPT_POINTLIST, + basevertex + PIBuffer[i], + 1))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numDrawCalls); } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); + + } } From ba8264c2acc88c277e49f78504a996a3bddbacf2 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 15 Dec 2012 14:43:01 +0100 Subject: [PATCH 6/7] use VAO in VertexManager to use VAO, we must use VBO, so some legency code was removed: - ARB_map_buffer_range must be available (OGL 3.0), don't call glBufferSubData if not - ARB_draw_elements_base_vertex also (OGL 3.2), else we have to set the pointers every time - USE_JIT was removed, it was broken and it isn't needed any more And the index and vertex buffers are now synchronized, so that there will be one VAO per NativeVertexFormat and Buffer. --- .../Src/NativeVertexFormat.cpp | 282 ++++------------ Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 23 ++ .../Plugin_VideoOGL/Src/VertexManager.cpp | 306 ++++++------------ .../Plugin_VideoOGL/Src/VertexManager.h | 21 +- 4 files changed, 193 insertions(+), 439 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index 3a98332562..8669d32711 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -27,8 +27,6 @@ #define COMPILED_CODE_SIZE 4096 -// TODO: this guy is never initialized -u32 s_prevcomponents; // previous state set /* #ifdef _WIN32 #ifdef _M_IX86 @@ -63,19 +61,13 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat() GLVertexFormat::GLVertexFormat() { -#ifdef USE_JIT - m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false); - if (m_compiledCode) - memset(m_compiledCode, 0, COMPILED_CODE_SIZE); -#endif + } GLVertexFormat::~GLVertexFormat() { -#ifdef USE_JIT - FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE); - m_compiledCode = 0; -#endif + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + glDeleteVertexArrays(vm->m_buffers_count, VAO); } inline GLuint VarToGL(VarType t) @@ -88,227 +80,69 @@ inline GLuint VarToGL(VarType t) void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) { - s_prevcomponents = 0; - - vertex_stride = _vtx_decl.stride; - using namespace Gen; + this->vtx_decl = _vtx_decl; + vertex_stride = vtx_decl.stride; // We will not allow vertex components causing uneven strides. - if (_vtx_decl.stride & 3) - PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride); - -#ifdef USE_JIT - Gen::XEmitter emit(m_compiledCode); - // Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL. - emit.ABI_EmitPrologue(6); + if (vertex_stride & 3) + PanicAlert("Uneven vertex stride: %i", vertex_stride); - emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0); + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + + VAO = new GLuint[vm->m_buffers_count]; + glGenVertexArrays(vm->m_buffers_count, VAO); + for(u32 i=0; im_buffers_count; i++) { + glBindVertexArray(VAO[i]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers[i]); + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[i]); + + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); + + if (vtx_decl.num_normals >= 1) { + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); + if (vtx_decl.num_normals == 3) { + glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); + glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); + glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); + glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); + } + } - if (_vtx_decl.num_normals >= 1) - { - emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]); - if (_vtx_decl.num_normals == 3) { - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]); - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]); + for (int i = 0; i < 2; i++) { + if (vtx_decl.color_offset[i] != -1) { + if (i == 0) { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } else { + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } + } + } + + for (int i = 0; i < 8; i++) { + if (vtx_decl.texcoord_offset[i] != -1) { + int id = GL_TEXTURE0 + i; + glClientActiveTexture(id); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), + vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); + } + } + + if (vtx_decl.posmtx_offset != -1) { + glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); + glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); } } - - for (int i = 0; i < 2; i++) - { - if (_vtx_decl.color_offset[i] != -1) - { - if (i == 0) - emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]); - else - emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]); - } - } - - for (int i = 0; i < 8; i++) - { - if (_vtx_decl.texcoord_offset[i] != -1) - { - int id = GL_TEXTURE0 + i; -#ifdef _M_X64 -#ifdef _MSC_VER - emit.MOV(32, R(RCX), Imm32(id)); -#else - emit.MOV(32, R(RDI), Imm32(id)); -#endif -#else - emit.ABI_AlignStack(1 * 4); - emit.PUSH(32, Imm32(id)); -#endif - emit.CALL((void *)glClientActiveTexture); -#ifndef _M_X64 -#ifdef _WIN32 - // don't inc stack on windows, stdcall -#else - emit.ABI_RestoreStack(1 * 4); -#endif -#endif - emit.CallCdeclFunction4_I( - glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]), - _vtx_decl.stride, _vtx_decl.texcoord_offset[i]); - } - } - - if (_vtx_decl.posmtx_offset != -1) - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset); - - emit.ABI_EmitEpilogue(6); - - if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE) - Crash(); - -#endif - this->vtx_decl = _vtx_decl; + + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); } void GLVertexFormat::SetupVertexPointers() { - // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to - // get around type checking errors, and call it. -#ifdef USE_JIT - ((void (*)())(void*)m_compiledCode)(); -#else - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer); - if (vtx_decl.num_normals >= 1) { - glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0])); - if (vtx_decl.num_normals == 3) { - glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1])); - glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2])); - } - } - - for (int i = 0; i < 2; i++) { - if (vtx_decl.color_offset[i] != -1) { - if (i == 0) - glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); - else { - glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); - } - } - } - - for (int i = 0; i < 8; i++) { - if (vtx_decl.texcoord_offset[i] != -1) { - int id = GL_TEXTURE0 + i; - glClientActiveTexture(id); - glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), - vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i])); - } - } - - if (vtx_decl.posmtx_offset != -1) { - glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset)); - } -#endif -} - -void GLVertexFormat::SetupVertexPointersOffset(u32 offset) { - // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to - // get around type checking errors, and call it. -#ifdef USE_JIT - ((void (*)())(void*)m_compiledCode)(); -#else - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (GLvoid*)offset); - if (vtx_decl.num_normals >= 1) { - glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[0])); - if (vtx_decl.num_normals == 3) { - glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[1])); - glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.normal_offset[2])); - } - } - - for (int i = 0; i < 2; i++) { - if (vtx_decl.color_offset[i] != -1) { - if (i == 0) - glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.color_offset[i])); - else { - glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.color_offset[i])); - } - } - } - - for (int i = 0; i < 8; i++) { - if (vtx_decl.texcoord_offset[i] != -1) { - int id = GL_TEXTURE0 + i; - glClientActiveTexture(id); - glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), - vtx_decl.stride, (GLvoid*)(offset + vtx_decl.texcoord_offset[i])); - } - } - - if (vtx_decl.posmtx_offset != -1) { - glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (GLvoid*)(offset + vtx_decl.posmtx_offset)); - } -#endif -} - -void GLVertexFormat::EnableComponents(u32 components) -{ - if (s_prevcomponents != components) - { - VertexManager::Flush(); - - // matrices - if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX)) - { - if (components & VB_HAS_POSMTXIDX) - glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); - else - glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB); - } - - // normals - if ((components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0)) - { - if (components & VB_HAS_NRM0) - glEnableClientState(GL_NORMAL_ARRAY); - else - glDisableClientState(GL_NORMAL_ARRAY); - } - if ((components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1)) - { - if (components & VB_HAS_NRM1) { - glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); - glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); - } - else { - glDisableVertexAttribArray(SHADER_NORM1_ATTRIB); - glDisableVertexAttribArray(SHADER_NORM2_ATTRIB); - } - } - - // color - for (int i = 0; i < 2; ++i) - { - if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i))) - { - if (components & (VB_HAS_COL0 << i)) - glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); - else - glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); - } - } - - // tex - for (int i = 0; i < 8; ++i) - { - if ((components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i))) - { - glClientActiveTexture(GL_TEXTURE0 + i); - if (components & (VB_HAS_UV0 << i)) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - else - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } - - s_prevcomponents = components; - } -} - - } +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index a6121e1436..d4b945199c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -62,6 +62,7 @@ #include "Host.h" #include "BPFunctions.h" #include "FPSCounter.h" +#include "VertexManager.h" #include "main.h" // Local #ifdef _WIN32 @@ -310,6 +311,20 @@ Renderer::Renderer() "GPU: Does your video card support OpenGL 2.x?"); bSuccess = false; } + + if (!GLEW_ARB_map_buffer_range) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n" + "GPU: Does your video card support OpenGL 3.0?"); + bSuccess = false; + } + + if (!GLEW_ARB_draw_elements_base_vertex) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_draw_elements_base_vertex.\n" + "GPU: Does your video card support OpenGL 3.2?"); + bSuccess = false; + } s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL; s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; @@ -1415,6 +1430,10 @@ void Renderer::ResetAPIState() glDisable(GL_BLEND); glDepthMask(GL_FALSE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + // TODO: remove this after merging with immediate-remove + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } void Renderer::RestoreAPIState() @@ -1432,6 +1451,10 @@ void Renderer::RestoreAPIState() VertexShaderCache::SetCurrentShader(0); PixelShaderCache::SetCurrentShader(0); + + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); + vm->m_last_vao = 0; } void Renderer::SetGenerationMode() diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index bbd196ba78..ceb04daeca 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -49,8 +49,10 @@ extern NativeVertexFormat *g_nativeVertexFmt; namespace OGL { //This are the initially requeted size for the buffers expresed in bytes -const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); -const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; +const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); +const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; +const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16); +const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1; const u32 MAX_VBUFFER_COUNT = 2; VertexManager::VertexManager() @@ -70,82 +72,77 @@ void VertexManager::CreateDeviceObjects() m_index_buffers = NULL; glEnableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); - int max_Index_size = 0; - int max_Vertex_size = 0; + u32 max_Index_size = 0; + u32 max_Vertex_size = 0; glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*)&max_Vertex_size); max_Index_size *= sizeof(u16); GL_REPORT_ERROR(); - m_index_buffer_size = IBUFFER_SIZE; - if (max_Index_size > 0 && max_Index_size < m_index_buffer_size) - m_index_buffer_size = max_Index_size; - - m_vertex_buffer_size = VBUFFER_SIZE; - if (max_Vertex_size > 0 && max_Vertex_size < m_vertex_buffer_size) - m_vertex_buffer_size = max_Vertex_size; - - if (m_index_buffer_size < VertexManager::MAXIBUFFERSIZE || m_vertex_buffer_size < VertexManager::MAXVBUFFERSIZE) - { - return; + + m_index_buffer_size = std::min(MAX_IBUFFER_SIZE, std::max(max_Index_size, MIN_IBUFFER_SIZE)); + m_vertex_buffer_size = std::min(MAX_VBUFFER_SIZE, std::max(max_Vertex_size, MIN_VBUFFER_SIZE)); + + // should be not bigger, but we need it. so try and have luck + if (m_index_buffer_size > max_Index_size) { + ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_INDICES to small, so try it anyway. good luck\n"); + } + if (m_vertex_buffer_size > max_Vertex_size) { + ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n"); } - m_vertex_buffers = new GLuint[MAX_VBUFFER_COUNT]; - m_index_buffers = new GLuint[MAX_VBUFFER_COUNT]; + //TODO: find out, how many buffers fit in gpu memory + m_buffers_count = MAX_VBUFFER_COUNT; + + m_vertex_buffers = new GLuint[m_buffers_count]; + m_index_buffers = new GLuint[m_buffers_count]; - glGenBuffers(MAX_VBUFFER_COUNT, m_vertex_buffers); + glGenBuffers(m_buffers_count, m_vertex_buffers); GL_REPORT_ERROR(); - glGenBuffers(MAX_VBUFFER_COUNT, m_index_buffers); + glGenBuffers(m_buffers_count, m_index_buffers); GL_REPORT_ERROR(); - for (u32 i = 0; i < MAX_VBUFFER_COUNT; i++) + for (u32 i = 0; i < m_buffers_count; i++) { glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[i] ); GL_REPORT_ERROR(); glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); GL_REPORT_ERROR(); } - for (u32 i = 0; i < MAX_VBUFFER_COUNT; i++) + for (u32 i = 0; i < m_buffers_count; i++) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[i] ); GL_REPORT_ERROR(); glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); GL_REPORT_ERROR(); } - m_buffers_count = MAX_VBUFFER_COUNT; - m_current_index_buffer = 0; - m_current_vertex_buffer = 0; - m_index_buffer_cursor = m_index_buffer_size; - m_vertex_buffer_cursor = m_vertex_buffer_size; + m_current_buffer = 0; + m_index_buffer_cursor = 0; + m_vertex_buffer_cursor = 0; m_CurrentVertexFmt = NULL; + m_last_vao = 0; } void VertexManager::DestroyDeviceObjects() { glDisableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); - glBindBuffer(GL_ARRAY_BUFFER, NULL ); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL ); + glBindBuffer(GL_ARRAY_BUFFER, 0 ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 ); GL_REPORT_ERROR(); - if(m_vertex_buffers) - { - glDeleteBuffers(MAX_VBUFFER_COUNT, m_vertex_buffers); - GL_REPORT_ERROR(); - delete [] m_vertex_buffers; - } - if(m_index_buffers) - { - glDeleteBuffers(MAX_VBUFFER_COUNT, m_index_buffers); - GL_REPORT_ERROR(); - delete [] m_index_buffers; - } + + glDeleteBuffers(m_buffers_count, m_vertex_buffers); + GL_REPORT_ERROR(); + delete [] m_vertex_buffers; + + glDeleteBuffers(m_buffers_count, m_index_buffers); + GL_REPORT_ERROR(); + delete [] m_index_buffers; + m_vertex_buffers = NULL; m_index_buffers = NULL; + m_buffers_count = 0; } void VertexManager::PrepareDrawBuffers(u32 stride) { - if (!m_buffers_count) - { - return; - } u8* pVertices = NULL; u16* pIndices = NULL; int vertex_data_size = IndexGenerator::GetNumVerts() * stride; @@ -153,141 +150,82 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen(); int point_index_size = IndexGenerator::GetPointindexLen(); int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16); - GLbitfield LockMode = GL_MAP_WRITE_BIT; + GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; + GLbitfield LockMode = GL_MAP_WRITE_BIT; + m_vertex_buffer_cursor--; m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; - if (m_vertex_buffer_cursor > m_vertex_buffer_size - vertex_data_size) + + if (m_vertex_buffer_cursor >= m_vertex_buffer_size - vertex_data_size || m_index_buffer_cursor >= m_index_buffer_size - index_data_size) { + // do we really want to set this? this require a reallocation. usualy only one buffer with reallocation, or much buffers without it LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]); + m_index_buffer_cursor = 0; + m_current_buffer = (m_current_buffer + 1) % m_buffers_count; + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_buffer]); } else { LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - } - if(GLEW_ARB_map_buffer_range) - { - pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); - if(pVertices) - { - memcpy(pVertices, LocalVBuffer, vertex_data_size); - glUnmapBuffer(GL_ARRAY_BUFFER); - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer); - } } - else + + // this replaces SetupVertexPointers and must be called after switching buffer and befor uploading indexes + // but could be deleted, if we only use one buffer with orphaning + if(m_last_vao != nativeVertexFmt->VAO[m_current_buffer]) + glBindVertexArray(nativeVertexFmt->VAO[m_current_buffer]); + + pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); + if(pVertices) + { + memcpy(pVertices, LocalVBuffer, vertex_data_size); + glUnmapBuffer(GL_ARRAY_BUFFER); + } + else // could that happen? out-of-memory? { glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer); } - - LockMode = GL_MAP_WRITE_BIT; - - if (m_index_buffer_cursor > m_index_buffer_size - index_data_size) + + pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode); + if(pIndices) { - LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; - m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]); - } - else - { - LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - } - if(GLEW_ARB_map_buffer_range) - { - pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode); - if(pIndices) - { - if(triangle_index_size) - { - memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16)); - pIndices += triangle_index_size; - } - if(line_index_size) - { - memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16)); - pIndices += line_index_size; - } - if(point_index_size) - { - memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16)); - } - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + if(triangle_index_size) + { + memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16)); + pIndices += triangle_index_size; } - else - { - if(triangle_index_size) - { - triangle_index_size *= sizeof(u16); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer); - } - if(line_index_size) - { - line_index_size *= sizeof(u16); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer); - } - if(point_index_size) - { - point_index_size *= sizeof(u16); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer); - } + if(line_index_size) + { + memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16)); + pIndices += line_index_size; } - } -} - -void VertexManager::DrawVertexArray() -{ - int triangle_index_size = IndexGenerator::GetTriangleindexLen(); - int line_index_size = IndexGenerator::GetLineindexLen(); - int point_index_size = IndexGenerator::GetPointindexLen(); - if (triangle_index_size > 0) - { - glDrawElements(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, TIBuffer); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); + if(point_index_size) + { + memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16)); + } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } - if (line_index_size > 0) + else // could that happen? out-of-memory? { - glDrawElements(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, LIBuffer); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (point_index_size > 0) - { - glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); + if(triangle_index_size) + { + triangle_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer); + } + if(line_index_size) + { + line_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer); + } + if(point_index_size) + { + point_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer); + } } } -void VertexManager::DrawVertexBufferObject() -{ - int triangle_index_size = IndexGenerator::GetTriangleindexLen(); - int line_index_size = IndexGenerator::GetLineindexLen(); - int point_index_size = IndexGenerator::GetPointindexLen(); - int StartIndex = m_index_buffer_cursor; - if (triangle_index_size > 0) - { - glDrawElements(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); - StartIndex += triangle_index_size * sizeof(u16); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (line_index_size > 0) - { - glDrawElements(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); - StartIndex += line_index_size * sizeof(u16); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (point_index_size > 0) - { - glDrawElements(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } -} - -void VertexManager::DrawVertexBufferObjectBase(u32 stride) +void VertexManager::Draw(u32 stride) { int triangle_index_size = IndexGenerator::GetTriangleindexLen(); int line_index_size = IndexGenerator::GetLineindexLen(); @@ -296,19 +234,19 @@ void VertexManager::DrawVertexBufferObjectBase(u32 stride) int basevertex = m_vertex_buffer_cursor / stride; if (triangle_index_size > 0) { - glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); + glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); StartIndex += triangle_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (line_index_size > 0) { - glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); + glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); StartIndex += line_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (point_index_size > 0) { - glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, basevertex); + glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } } @@ -349,19 +287,6 @@ void VertexManager::vFlush() u32 stride = g_nativeVertexFmt->GetVertexStride(); PrepareDrawBuffers(stride); - //still testing if this line is enabled to reduce the amount of vertex setup call everything goes wrong - //if(m_CurrentVertexFmt != g_nativeVertexFmt || !GLEW_ARB_draw_elements_base_vertex ) - { - if(m_buffers_count) - { - ((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(GLEW_ARB_draw_elements_base_vertex ? 0 : m_vertex_buffer_cursor); - } - else - { - g_nativeVertexFmt->SetupVertexPointers(); - } - m_CurrentVertexFmt = g_nativeVertexFmt; - } GL_REPORT_ERRORD(); u32 usedtextures = 0; @@ -438,21 +363,7 @@ void VertexManager::vFlush() if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); - if(m_buffers_count) - { - if(GLEW_ARB_draw_elements_base_vertex) - { - DrawVertexBufferObjectBase(stride); - } - else - { - DrawVertexBufferObject(); - } - } - else - { - DrawVertexArray(); - } + Draw(stride); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) @@ -465,21 +376,8 @@ void VertexManager::vFlush() glDisable(GL_BLEND); - if(m_buffers_count) - { - if(GLEW_ARB_draw_elements_base_vertex) - { - DrawVertexBufferObjectBase(stride); - } - else - { - DrawVertexBufferObject(); - } - } - else - { - DrawVertexArray(); - } + Draw(stride); + // restore color mask g_renderer->SetColorMask(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index db80f87a2b..91319b54f2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -26,7 +26,6 @@ namespace OGL { class GLVertexFormat : public NativeVertexFormat { - u8 *m_compiledCode; PortableVertexDeclaration vtx_decl; public: @@ -35,8 +34,8 @@ namespace OGL virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void SetupVertexPointers(); - virtual void SetupVertexPointersOffset(u32 offset); - virtual void EnableComponents(u32 components); + + GLuint *VAO; }; // Handles the OpenGL details of drawing lots of vertices quickly. @@ -49,21 +48,21 @@ public: NativeVertexFormat* CreateNativeVertexFormat(); void CreateDeviceObjects(); void DestroyDeviceObjects(); + + // NativeVertexFormat use this + u32 m_buffers_count; + u32 m_current_buffer; + GLuint* m_vertex_buffers; + GLuint* m_index_buffers; + GLuint m_last_vao; private: - void DrawVertexArray(); - void DrawVertexBufferObject(); - void DrawVertexBufferObjectBase(u32 stride); + void Draw(u32 stride); void vFlush(); void PrepareDrawBuffers(u32 stride); u32 m_vertex_buffer_cursor; u32 m_vertex_buffer_size; u32 m_index_buffer_cursor; u32 m_index_buffer_size; - u32 m_buffers_count; - u32 m_current_vertex_buffer; - u32 m_current_index_buffer; - GLuint* m_vertex_buffers; - GLuint* m_index_buffers; NativeVertexFormat *m_CurrentVertexFmt; }; From 1919a458e88fc1a06567b9496c6c47d34b9df5f2 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 15 Dec 2012 17:28:58 +0100 Subject: [PATCH 7/7] only use one buffer, orphaning should do the rest --- .../Src/NativeVertexFormat.cpp | 92 +++++++++---------- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 2 +- .../Plugin_VideoOGL/Src/VertexManager.cpp | 76 +++++---------- .../Plugin_VideoOGL/Src/VertexManager.h | 8 +- 4 files changed, 72 insertions(+), 106 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index 8669d32711..506c1a707d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -66,8 +66,7 @@ GLVertexFormat::GLVertexFormat() GLVertexFormat::~GLVertexFormat() { - VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - glDeleteVertexArrays(vm->m_buffers_count, VAO); + glDeleteVertexArrays(1, &VAO); } inline GLuint VarToGL(VarType t) @@ -89,57 +88,54 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - VAO = new GLuint[vm->m_buffers_count]; - glGenVertexArrays(vm->m_buffers_count, VAO); - for(u32 i=0; im_buffers_count; i++) { - glBindVertexArray(VAO[i]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers[i]); - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[i]); + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); - - if (vtx_decl.num_normals >= 1) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); - if (vtx_decl.num_normals == 3) { - glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); - glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); - glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); - glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); - } - } + // the element buffer is bound directly to the vao, so we must it set for every vao + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers); - for (int i = 0; i < 2; i++) { - if (vtx_decl.color_offset[i] != -1) { - if (i == 0) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); - } else { - glEnableClientState(GL_SECONDARY_COLOR_ARRAY); - glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); - } - } - } - - for (int i = 0; i < 8; i++) { - if (vtx_decl.texcoord_offset[i] != -1) { - int id = GL_TEXTURE0 + i; - glClientActiveTexture(id); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), - vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); - } - } - - if (vtx_decl.posmtx_offset != -1) { - glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); - glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); + + if (vtx_decl.num_normals >= 1) { + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); + if (vtx_decl.num_normals == 3) { + glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); + glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); + glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); + glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); } } + + for (int i = 0; i < 2; i++) { + if (vtx_decl.color_offset[i] != -1) { + if (i == 0) { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } else { + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } + } + } + + for (int i = 0; i < 8; i++) { + if (vtx_decl.texcoord_offset[i] != -1) { + int id = GL_TEXTURE0 + i; + glClientActiveTexture(id); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), + vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); + } + } + + if (vtx_decl.posmtx_offset != -1) { + glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); + glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); + } - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); + vm->m_last_vao = VAO; } void GLVertexFormat::SetupVertexPointers() { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index d4b945199c..a03ac84b8a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1453,7 +1453,7 @@ void Renderer::RestoreAPIState() PixelShaderCache::SetCurrentShader(0); VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); vm->m_last_vao = 0; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index ceb04daeca..29cf903c04 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -53,7 +53,6 @@ const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16); const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1; -const u32 MAX_VBUFFER_COUNT = 2; VertexManager::VertexManager() { @@ -67,10 +66,6 @@ VertexManager::~VertexManager() void VertexManager::CreateDeviceObjects() { - m_buffers_count = 0; - m_vertex_buffers = NULL; - m_index_buffers = NULL; - glEnableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); u32 max_Index_size = 0; u32 max_Vertex_size = 0; @@ -90,31 +85,18 @@ void VertexManager::CreateDeviceObjects() ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n"); } - //TODO: find out, how many buffers fit in gpu memory - m_buffers_count = MAX_VBUFFER_COUNT; - - m_vertex_buffers = new GLuint[m_buffers_count]; - m_index_buffers = new GLuint[m_buffers_count]; - - glGenBuffers(m_buffers_count, m_vertex_buffers); + glGenBuffers(1, &m_vertex_buffers); GL_REPORT_ERROR(); - glGenBuffers(m_buffers_count, m_index_buffers); + glGenBuffers(1, &m_index_buffers); + GL_REPORT_ERROR(); + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); GL_REPORT_ERROR(); - for (u32 i = 0; i < m_buffers_count; i++) - { - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[i] ); - GL_REPORT_ERROR(); - glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); - GL_REPORT_ERROR(); - } - for (u32 i = 0; i < m_buffers_count; i++) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[i] ); - GL_REPORT_ERROR(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); - GL_REPORT_ERROR(); - } - m_current_buffer = 0; m_index_buffer_cursor = 0; m_vertex_buffer_cursor = 0; m_CurrentVertexFmt = NULL; @@ -122,23 +104,16 @@ void VertexManager::CreateDeviceObjects() } void VertexManager::DestroyDeviceObjects() { - glDisableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); glBindBuffer(GL_ARRAY_BUFFER, 0 ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 ); GL_REPORT_ERROR(); - glDeleteBuffers(m_buffers_count, m_vertex_buffers); + glDeleteBuffers(1, &m_vertex_buffers); GL_REPORT_ERROR(); - delete [] m_vertex_buffers; - glDeleteBuffers(m_buffers_count, m_index_buffers); + glDeleteBuffers(1, &m_index_buffers); GL_REPORT_ERROR(); - delete [] m_index_buffers; - - m_vertex_buffers = NULL; - m_index_buffers = NULL; - m_buffers_count = 0; } void VertexManager::PrepareDrawBuffers(u32 stride) @@ -150,7 +125,6 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen(); int point_index_size = IndexGenerator::GetPointindexLen(); int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16); - GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; GLbitfield LockMode = GL_MAP_WRITE_BIT; m_vertex_buffer_cursor--; @@ -158,22 +132,14 @@ void VertexManager::PrepareDrawBuffers(u32 stride) if (m_vertex_buffer_cursor >= m_vertex_buffer_size - vertex_data_size || m_index_buffer_cursor >= m_index_buffer_size - index_data_size) { - // do we really want to set this? this require a reallocation. usualy only one buffer with reallocation, or much buffers without it LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; m_vertex_buffer_cursor = 0; m_index_buffer_cursor = 0; - m_current_buffer = (m_current_buffer + 1) % m_buffers_count; - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_buffer]); } else { LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; } - - // this replaces SetupVertexPointers and must be called after switching buffer and befor uploading indexes - // but could be deleted, if we only use one buffer with orphaning - if(m_last_vao != nativeVertexFmt->VAO[m_current_buffer]) - glBindVertexArray(nativeVertexFmt->VAO[m_current_buffer]); pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); if(pVertices) @@ -284,9 +250,16 @@ void VertexManager::vFlush() (void)GL_REPORT_ERROR(); - u32 stride = g_nativeVertexFmt->GetVertexStride(); + GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; + u32 stride = nativeVertexFmt->GetVertexStride(); + + if(m_last_vao != nativeVertexFmt->VAO) { + glBindVertexArray(nativeVertexFmt->VAO); + m_last_vao = nativeVertexFmt->VAO; + } PrepareDrawBuffers(stride); + GL_REPORT_ERRORD(); u32 usedtextures = 0; @@ -385,11 +358,10 @@ void VertexManager::vFlush() glEnable(GL_BLEND); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); - if(m_buffers_count) - { - m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); - m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; - } + + m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + ResetBuffer(); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 91319b54f2..4d820692b9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -35,7 +35,7 @@ namespace OGL virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void SetupVertexPointers(); - GLuint *VAO; + GLuint VAO; }; // Handles the OpenGL details of drawing lots of vertices quickly. @@ -50,10 +50,8 @@ public: void DestroyDeviceObjects(); // NativeVertexFormat use this - u32 m_buffers_count; - u32 m_current_buffer; - GLuint* m_vertex_buffers; - GLuint* m_index_buffers; + GLuint m_vertex_buffers; + GLuint m_index_buffers; GLuint m_last_vao; private: void Draw(u32 stride);