diff --git a/Source/Core/VideoBackends/D3D/VertexManager.cpp b/Source/Core/VideoBackends/D3D/VertexManager.cpp index 45638dfbf1..6553a56084 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/VertexManager.cpp @@ -36,9 +36,7 @@ void VertexManager::CreateDeviceObjects() D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); m_vertex_draw_offset = 0; - m_triangle_draw_index = 0; - m_line_draw_index = 0; - m_point_draw_index = 0; + m_index_draw_offset = 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++) @@ -108,8 +106,7 @@ void VertexManager::PrepareDrawBuffers() m_vertex_draw_offset = m_vertex_buffer_cursor; m_vertex_buffer_cursor += vSize; - UINT iCount = IndexGenerator::GetTriangleindexLen() + - IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + UINT iCount = IndexGenerator::GetIndexLen(); MapType = D3D11_MAP_WRITE_NO_OVERWRITE; if (m_index_buffer_cursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) { @@ -120,13 +117,9 @@ void VertexManager::PrepareDrawBuffers() } D3D::context->Map(m_index_buffers[m_current_index_buffer], 0, MapType, 0, &map); - 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, GetTriangleIndexBuffer(), sizeof(u16) * IndexGenerator::GetTriangleindexLen()); - memcpy((u16*)map.pData + m_line_draw_index, GetLineIndexBuffer(), sizeof(u16) * IndexGenerator::GetLineindexLen()); - memcpy((u16*)map.pData + m_point_draw_index, GetPointIndexBuffer(), sizeof(u16) * IndexGenerator::GetPointindexLen()); + memcpy((u16*)map.pData + m_index_buffer_cursor, GetIndexBuffer(), sizeof(u16) * IndexGenerator::GetIndexLen()); D3D::context->Unmap(m_index_buffers[m_current_index_buffer], 0); + m_index_draw_offset = m_index_buffer_cursor; m_index_buffer_cursor += iCount; ADDSTAT(stats.thisFrame.bytesVertexStreamed, vSize); @@ -142,16 +135,13 @@ void VertexManager::Draw(UINT stride) 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) + if (current_primitive_type == PRIMITIVE_TRIANGLES) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangle_draw_index, 0); + D3D::context->DrawIndexed(IndexGenerator::GetIndexLen(), m_index_draw_offset, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - // Disable culling for lines and points - if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0) - ((DX11::Renderer*)g_renderer)->ApplyCullDisable(); - if (IndexGenerator::GetNumLines() > 0) + else if (current_primitive_type == PRIMITIVE_LINES) { float lineWidth = float(bpmem.lineptwidth.linesize) / 6.f; float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff]; @@ -166,14 +156,16 @@ void VertexManager::Draw(UINT stride) if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth, texOffset, vpWidth, vpHeight, texOffsetEnable)) { + ((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_line_draw_index, 0); + D3D::context->DrawIndexed(IndexGenerator::GetIndexLen(), m_index_draw_offset, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); + ((DX11::Renderer*)g_renderer)->RestoreCull(); } } - if (IndexGenerator::GetNumPoints() > 0) + else //if (current_primitive_type == PRIMITIVE_POINTS) { float pointSize = float(bpmem.lineptwidth.pointsize) / 6.f; float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff]; @@ -188,15 +180,15 @@ void VertexManager::Draw(UINT stride) if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize, texOffset, vpWidth, vpHeight, texOffsetEnable)) { + ((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_point_draw_index, 0); + D3D::context->DrawIndexed(IndexGenerator::GetIndexLen(), m_index_draw_offset, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); + ((DX11::Renderer*)g_renderer)->RestoreCull(); } } - if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0) - ((DX11::Renderer*)g_renderer)->RestoreCull(); } void VertexManager::vFlush() diff --git a/Source/Core/VideoBackends/D3D/VertexManager.h b/Source/Core/VideoBackends/D3D/VertexManager.h index b4b7aa0ef4..9440c737b2 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.h +++ b/Source/Core/VideoBackends/D3D/VertexManager.h @@ -32,11 +32,9 @@ private: u32 m_vertex_buffer_cursor; u32 m_vertex_draw_offset; u32 m_index_buffer_cursor; + u32 m_index_draw_offset; 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_index_buffers; PID3D11Buffer* m_vertex_buffers; diff --git a/Source/Core/VideoBackends/OGL/VertexManager.cpp b/Source/Core/VideoBackends/OGL/VertexManager.cpp index f10618e7f3..fdd1fbee34 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/VertexManager.cpp @@ -44,7 +44,7 @@ const u32 MAX_VBUFFER_SIZE = 16*1024*1024; static StreamBuffer *s_vertexBuffer; static StreamBuffer *s_indexBuffer; static size_t s_baseVertex; -static size_t s_offset[3]; +static size_t s_index_offset; VertexManager::VertexManager() { @@ -83,74 +83,44 @@ void VertexManager::DestroyDeviceObjects() void VertexManager::PrepareDrawBuffers(u32 stride) { u32 vertex_data_size = IndexGenerator::GetNumVerts() * stride; - u32 triangle_index_size = IndexGenerator::GetTriangleindexLen(); - u32 line_index_size = IndexGenerator::GetLineindexLen(); - u32 point_index_size = IndexGenerator::GetPointindexLen(); - u32 index_size = (triangle_index_size+line_index_size+point_index_size) * sizeof(u16); + u32 index_data_size = IndexGenerator::GetIndexLen() * sizeof(u16); s_vertexBuffer->Alloc(vertex_data_size, stride); size_t offset = s_vertexBuffer->Upload(GetVertexBuffer(), vertex_data_size); s_baseVertex = offset / stride; - s_indexBuffer->Alloc(index_size); - if(triangle_index_size) - { - s_offset[0] = s_indexBuffer->Upload((u8*)GetTriangleIndexBuffer(), triangle_index_size * sizeof(u16)); - } - if(line_index_size) - { - s_offset[1] = s_indexBuffer->Upload((u8*)GetLineIndexBuffer(), line_index_size * sizeof(u16)); - } - if(point_index_size) - { - s_offset[2] = s_indexBuffer->Upload((u8*)GetPointIndexBuffer(), point_index_size * sizeof(u16)); - } + s_indexBuffer->Alloc(index_data_size); + s_index_offset = s_indexBuffer->Upload((u8*)GetIndexBuffer(), index_data_size); ADDSTAT(stats.thisFrame.bytesVertexStreamed, vertex_data_size); - ADDSTAT(stats.thisFrame.bytesIndexStreamed, index_size); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, index_data_size); } void VertexManager::Draw(u32 stride) { - u32 triangle_index_size = IndexGenerator::GetTriangleindexLen(); - u32 line_index_size = IndexGenerator::GetLineindexLen(); - u32 point_index_size = IndexGenerator::GetPointindexLen(); + u32 index_size = IndexGenerator::GetIndexLen(); u32 max_index = IndexGenerator::GetNumVerts(); - GLenum triangle_mode = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart?GL_TRIANGLE_STRIP:GL_TRIANGLES; + GLenum primitive_mode = 0; + + switch(current_primitive_type) + { + case PRIMITIVE_POINTS: + primitive_mode = GL_POINTS; + break; + case PRIMITIVE_LINES: + primitive_mode = GL_LINES; + break; + case PRIMITIVE_TRIANGLES: + primitive_mode = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? GL_TRIANGLE_STRIP : GL_TRIANGLES; + break; + } if(g_ogl_config.bSupportsGLBaseVertex) { - if (triangle_index_size > 0) - { - glDrawRangeElementsBaseVertex(triangle_mode, 0, max_index, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[0], (GLint)s_baseVertex); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (line_index_size > 0) - { - glDrawRangeElementsBaseVertex(GL_LINES, 0, max_index, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[1], (GLint)s_baseVertex); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (point_index_size > 0) - { - glDrawRangeElementsBaseVertex(GL_POINTS, 0, max_index, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[2], (GLint)s_baseVertex); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } + glDrawRangeElementsBaseVertex(primitive_mode, 0, max_index, index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_index_offset, (GLint)s_baseVertex); } else { - if (triangle_index_size > 0) - { - glDrawRangeElements(triangle_mode, 0, max_index, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[0]); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (line_index_size > 0) - { - glDrawRangeElements(GL_LINES, 0, max_index, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[1]); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (point_index_size > 0) - { - glDrawRangeElements(GL_POINTS, 0, max_index, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_offset[2]); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } + glDrawRangeElements(primitive_mode, 0, max_index, index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_index_offset); } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); } void VertexManager::vFlush() diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index 4b49a4db5e..0789ec1e1a 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -9,20 +9,13 @@ #include "IndexGenerator.h" //Init -u16 *IndexGenerator::Tptr; -u16 *IndexGenerator::BASETptr; -u16 *IndexGenerator::Lptr; -u16 *IndexGenerator::BASELptr; -u16 *IndexGenerator::Pptr; -u16 *IndexGenerator::BASEPptr; -u32 IndexGenerator::numT; -u32 IndexGenerator::numL; -u32 IndexGenerator::numP; -u32 IndexGenerator::index; +u16 *IndexGenerator::index_buffer_current; +u16 *IndexGenerator::BASEIptr; +u32 IndexGenerator::base_index; static const u16 s_primitive_restart = -1; -static void (*primitive_table[8])(u32); +static u16* (*primitive_table[8])(u16*, u32, u32); void IndexGenerator::Init() { @@ -46,56 +39,48 @@ void IndexGenerator::Init() primitive_table[7] = &IndexGenerator::AddPoints; } -void IndexGenerator::Start(u16* Triangleptr, u16* Lineptr, u16* Pointptr) +void IndexGenerator::Start(u16* Indexptr) { - Tptr = Triangleptr; - Lptr = Lineptr; - Pptr = Pointptr; - BASETptr = Triangleptr; - BASELptr = Lineptr; - BASEPptr = Pointptr; - index = 0; - numT = 0; - numL = 0; - numP = 0; + index_buffer_current = Indexptr; + BASEIptr = Indexptr; + base_index = 0; } void IndexGenerator::AddIndices(int primitive, u32 numVerts) { - primitive_table[primitive](numVerts); - index += numVerts; + index_buffer_current = primitive_table[primitive](index_buffer_current, numVerts, base_index); + base_index += numVerts; } // Triangles -template __forceinline void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) +template __forceinline u16* IndexGenerator::WriteTriangle(u16 *Iptr, u32 index1, u32 index2, u32 index3) { - *Tptr++ = index1; - *Tptr++ = index2; - *Tptr++ = index3; + *Iptr++ = index1; + *Iptr++ = index2; + *Iptr++ = index3; if(pr) - *Tptr++ = s_primitive_restart; - - ++numT; + *Iptr++ = s_primitive_restart; + return Iptr; } -template void IndexGenerator::AddList(u32 const numVerts) +template u16* IndexGenerator::AddList(u16 *Iptr, u32 const numVerts, u32 index) { for (u32 i = 2; i < numVerts; i+=3) { - WriteTriangle(index + i - 2, index + i - 1, index + i); + Iptr = WriteTriangle(Iptr, index + i - 2, index + i - 1, index + i); } + return Iptr; } -template void IndexGenerator::AddStrip(u32 const numVerts) +template u16* IndexGenerator::AddStrip(u16 *Iptr, u32 const numVerts, u32 index) { if(pr) { for (u32 i = 0; i < numVerts; ++i) { - *Tptr++ = index + i; + *Iptr++ = index + i; } - *Tptr++ = s_primitive_restart; - numT += numVerts - 2; + *Iptr++ = s_primitive_restart; } else @@ -103,7 +88,7 @@ template void IndexGenerator::AddStrip(u32 const numVerts) bool wind = false; for (u32 i = 2; i < numVerts; ++i) { - WriteTriangle( + Iptr = WriteTriangle(Iptr, index + i - 2, index + i - !wind, index + i - wind); @@ -111,6 +96,7 @@ template void IndexGenerator::AddStrip(u32 const numVerts) wind ^= true; } } + return Iptr; } /** @@ -132,7 +118,7 @@ template void IndexGenerator::AddStrip(u32 const numVerts) * so we use 6 indices for 3 triangles */ -template void IndexGenerator::AddFan(u32 numVerts) +template u16* IndexGenerator::AddFan(u16 *Iptr, u32 numVerts, u32 index) { u32 i = 2; @@ -140,30 +126,29 @@ template void IndexGenerator::AddFan(u32 numVerts) { for(; i+3<=numVerts; i+=3) { - *Tptr++ = index + i - 1; - *Tptr++ = index + i + 0; - *Tptr++ = index; - *Tptr++ = index + i + 1; - *Tptr++ = index + i + 2; - *Tptr++ = s_primitive_restart; - numT += 3; + *Iptr++ = index + i - 1; + *Iptr++ = index + i + 0; + *Iptr++ = index; + *Iptr++ = index + i + 1; + *Iptr++ = index + i + 2; + *Iptr++ = s_primitive_restart; } for(; i+2<=numVerts; i+=2) { - *Tptr++ = index + i - 1; - *Tptr++ = index + i + 0; - *Tptr++ = index; - *Tptr++ = index + i + 1; - *Tptr++ = s_primitive_restart; - numT += 2; + *Iptr++ = index + i - 1; + *Iptr++ = index + i + 0; + *Iptr++ = index; + *Iptr++ = index + i + 1; + *Iptr++ = s_primitive_restart; } } for (; i < numVerts; ++i) { - WriteTriangle(index, index + i - 1, index + i); + Iptr = WriteTriangle(Iptr, index, index + i - 1, index + i); } + return Iptr; } /* @@ -183,71 +168,71 @@ template void IndexGenerator::AddFan(u32 numVerts) * A simple triangle has to be rendered for three vertices. * ZWW do this for sun rays */ -template void IndexGenerator::AddQuads(u32 numVerts) +template u16* IndexGenerator::AddQuads(u16 *Iptr, u32 numVerts, u32 index) { u32 i = 3; for (; i < numVerts; i+=4) { if(pr) { - *Tptr++ = index + i - 2; - *Tptr++ = index + i - 1; - *Tptr++ = index + i - 3; - *Tptr++ = index + i - 0; - *Tptr++ = s_primitive_restart; - numT += 2; + *Iptr++ = index + i - 2; + *Iptr++ = index + i - 1; + *Iptr++ = index + i - 3; + *Iptr++ = index + i - 0; + *Iptr++ = s_primitive_restart; } else { - WriteTriangle(index + i - 3, index + i - 2, index + i - 1); - WriteTriangle(index + i - 3, index + i - 1, index + i - 0); + Iptr = WriteTriangle(Iptr, index + i - 3, index + i - 2, index + i - 1); + Iptr = WriteTriangle(Iptr, index + i - 3, index + i - 1, index + i - 0); } } // three vertices remaining, so render a triangle if(i == numVerts) { - WriteTriangle(index+numVerts-3, index+numVerts-2, index+numVerts-1); + Iptr = WriteTriangle(Iptr, index+numVerts-3, index+numVerts-2, index+numVerts-1); } + return Iptr; } // Lines -void IndexGenerator::AddLineList(u32 numVerts) +u16* IndexGenerator::AddLineList(u16 *Iptr, u32 numVerts, u32 index) { for (u32 i = 1; i < numVerts; i+=2) { - *Lptr++ = index + i - 1; - *Lptr++ = index + i; - ++numL; + *Iptr++ = index + i - 1; + *Iptr++ = index + i; } + return Iptr; } // shouldn't be used as strips as LineLists are much more common // so converting them to lists -void IndexGenerator::AddLineStrip(u32 numVerts) +u16* IndexGenerator::AddLineStrip(u16 *Iptr, u32 numVerts, u32 index) { for (u32 i = 1; i < numVerts; ++i) { - *Lptr++ = index + i - 1; - *Lptr++ = index + i; - ++numL; + *Iptr++ = index + i - 1; + *Iptr++ = index + i; } + return Iptr; } // Points -void IndexGenerator::AddPoints(u32 numVerts) +u16* IndexGenerator::AddPoints(u16 *Iptr, u32 numVerts, u32 index) { for (u32 i = 0; i != numVerts; ++i) { - *Pptr++ = index + i; - ++numP; + *Iptr++ = index + i; } + return Iptr; } u32 IndexGenerator::GetRemainingIndices() { u32 max_index = 65534; // -1 is reserved for primitive restart (ogl + dx11) - return max_index - index; + return max_index - base_index; } diff --git a/Source/Core/VideoCommon/IndexGenerator.h b/Source/Core/VideoCommon/IndexGenerator.h index 1f72e6e74f..4b9a0fee3c 100644 --- a/Source/Core/VideoCommon/IndexGenerator.h +++ b/Source/Core/VideoCommon/IndexGenerator.h @@ -14,59 +14,36 @@ class IndexGenerator public: // Init static void Init(); - static void Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr); + static void Start(u16 *Indexptr); static void AddIndices(int primitive, u32 numVertices); - // Interface - static u32 GetNumTriangles() {return numT;} - static u32 GetNumLines() {return numL;} - static u32 GetNumPoints() {return numP;} - // returns numprimitives - static u32 GetNumVerts() {return index;} + static u32 GetNumVerts() {return base_index;} - static u32 GetTriangleindexLen() {return (u32)(Tptr - BASETptr);} - static u32 GetLineindexLen() {return (u32)(Lptr - BASELptr);} - static u32 GetPointindexLen() {return (u32)(Pptr - BASEPptr);} + static u32 GetIndexLen() {return (u32)(index_buffer_current - BASEIptr);} static u32 GetRemainingIndices(); -/* - enum IndexPrimitiveType - { - Prim_None = 0, - Prim_List, - Prim_Strip, - Prim_Fan - }; -*/ + private: // Triangles - template static void AddList(u32 numVerts); - template static void AddStrip(u32 numVerts); - template static void AddFan(u32 numVerts); - template static void AddQuads(u32 numVerts); + template static u16* AddList(u16 *Iptr, u32 numVerts, u32 index); + template static u16* AddStrip(u16 *Iptr, u32 numVerts, u32 index); + template static u16* AddFan(u16 *Iptr, u32 numVerts, u32 index); + template static u16* AddQuads(u16 *Iptr, u32 numVerts, u32 index); // Lines - static void AddLineList(u32 numVerts); - static void AddLineStrip(u32 numVerts); + static u16* AddLineList(u16 *Iptr, u32 numVerts, u32 index); + static u16* AddLineStrip(u16 *Iptr, u32 numVerts, u32 index); // Points - static void AddPoints(u32 numVerts); + static u16* AddPoints(u16 *Iptr, u32 numVerts, u32 index); - template static void WriteTriangle(u32 index1, u32 index2, u32 index3); + template static u16* WriteTriangle(u16 *Iptr, u32 index1, u32 index2, u32 index3); - static u16 *Tptr; - static u16 *BASETptr; - static u16 *Lptr; - static u16 *BASELptr; - static u16 *Pptr; - static u16 *BASEPptr; - // TODO: redundant variables - static u32 numT; - static u32 numL; - static u32 numP; - static u32 index; + static u16 *index_buffer_current; + static u16 *BASEIptr; + static u32 base_index; }; #endif // _INDEXGENERATOR_H diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index b5285dd0e2..bce4af457e 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -21,15 +21,26 @@ u8 *VertexManager::s_pCurBufferPointer; u8 *VertexManager::s_pBaseBufferPointer; u8 *VertexManager::s_pEndBufferPointer; +PrimitiveType VertexManager::current_primitive_type; + +static const PrimitiveType primitive_from_gx[8] = { + PRIMITIVE_TRIANGLES, // GX_DRAW_QUADS + PRIMITIVE_TRIANGLES, // GX_DRAW_NONE + PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLES + PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLE_STRIP + PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLE_FAN + PRIMITIVE_LINES, // GX_DRAW_LINES + PRIMITIVE_LINES, // GX_DRAW_LINE_STRIP + PRIMITIVE_POINTS, // GX_DRAW_POINTS +}; + VertexManager::VertexManager() { LocalVBuffer.resize(MAXVBUFFERSIZE); s_pCurBufferPointer = s_pBaseBufferPointer = &LocalVBuffer[0]; s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size(); - TIBuffer.resize(MAXIBUFFERSIZE); - LIBuffer.resize(MAXIBUFFERSIZE); - PIBuffer.resize(MAXIBUFFERSIZE); + LocalIBuffer.resize(MAXIBUFFERSIZE); ResetBuffer(); } @@ -41,7 +52,7 @@ VertexManager::~VertexManager() void VertexManager::ResetBuffer() { s_pCurBufferPointer = s_pBaseBufferPointer; - IndexGenerator::Start(GetTriangleIndexBuffer(), GetLineIndexBuffer(), GetPointIndexBuffer()); + IndexGenerator::Start(GetIndexBuffer()); } u32 VertexManager::GetRemainingSize() @@ -53,6 +64,12 @@ void VertexManager::PrepareForAdditionalData(int primitive, u32 count, u32 strid { u32 const needed_vertex_bytes = count * stride; + // We can't merge different kinds of primitives, so we have to flush here + if (current_primitive_type != primitive_from_gx[primitive]) + Flush(); + current_primitive_type = primitive_from_gx[primitive]; + + // Check for size in buffer, if the buffer gets full, call Flush() if (count > IndexGenerator::GetRemainingIndices() || count > GetRemainingIndices(primitive) || needed_vertex_bytes > GetRemainingSize()) { Flush(); @@ -75,27 +92,28 @@ bool VertexManager::IsFlushed() const u32 VertexManager::GetRemainingIndices(int primitive) { + u32 index_len = MAXIBUFFERSIZE - IndexGenerator::GetIndexLen(); if(g_Config.backend_info.bSupportsPrimitiveRestart) { switch (primitive) { case GX_DRAW_QUADS: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 5 * 4; + return index_len / 5 * 4; case GX_DRAW_TRIANGLES: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 4 * 3; + return index_len / 4 * 3; case GX_DRAW_TRIANGLE_STRIP: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 1 - 1; + return index_len / 1 - 1; case GX_DRAW_TRIANGLE_FAN: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 6 * 4 + 1; + return index_len / 6 * 4 + 1; case GX_DRAW_LINES: - return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()); + return index_len; case GX_DRAW_LINE_STRIP: - return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2 + 1; + return index_len / 2 + 1; case GX_DRAW_POINTS: - return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); + return index_len; default: return 0; @@ -106,21 +124,21 @@ u32 VertexManager::GetRemainingIndices(int primitive) switch (primitive) { case GX_DRAW_QUADS: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 6 * 4; + return index_len / 6 * 4; case GX_DRAW_TRIANGLES: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()); + return index_len; case GX_DRAW_TRIANGLE_STRIP: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3 + 2; + return index_len / 3 + 2; case GX_DRAW_TRIANGLE_FAN: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3 + 2; + return index_len / 3 + 2; case GX_DRAW_LINES: - return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()); + return index_len; case GX_DRAW_LINE_STRIP: - return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2 + 1; + return index_len / 2 + 1; case GX_DRAW_POINTS: - return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); + return index_len; default: return 0; @@ -167,9 +185,7 @@ void VertexManager::DoStateShared(PointerWrap& p) // and maybe other things are overlooked p.Do(LocalVBuffer); - p.Do(TIBuffer); - p.Do(LIBuffer); - p.Do(PIBuffer); + p.Do(LocalIBuffer); s_pBaseBufferPointer = &LocalVBuffer[0]; s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size(); diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index b5b13c8933..f0f8c131ee 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -8,6 +8,12 @@ class NativeVertexFormat; class PointerWrap; +enum PrimitiveType { + PRIMITIVE_POINTS, + PRIMITIVE_LINES, + PRIMITIVE_TRIANGLES, +}; + class VertexManager { private: @@ -45,14 +51,14 @@ public: virtual void DestroyDeviceObjects(){}; protected: - u16* GetTriangleIndexBuffer() { return &TIBuffer[0]; } - u16* GetLineIndexBuffer() { return &LIBuffer[0]; } - u16* GetPointIndexBuffer() { return &PIBuffer[0]; } + u16* GetIndexBuffer() { return &LocalIBuffer[0]; } u8* GetVertexBuffer() { return &s_pBaseBufferPointer[0]; } virtual void vDoState(PointerWrap& p) { DoStateShared(p); } void DoStateShared(PointerWrap& p); + static PrimitiveType current_primitive_type; + private: bool IsFlushed() const; @@ -63,9 +69,7 @@ private: virtual void vFlush() = 0; std::vector LocalVBuffer; - std::vector TIBuffer; - std::vector LIBuffer; - std::vector PIBuffer; + std::vector LocalIBuffer; }; extern VertexManager *g_vertex_manager;