Merge branch 'index_buffer_cleanup'

This commit is contained in:
degasus 2014-01-17 16:35:54 +01:00
commit 355df60abd
7 changed files with 160 additions and 218 deletions

View File

@ -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,16 +180,16 @@ 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);
}
}
if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0)
((DX11::Renderer*)g_renderer)->RestoreCull();
}
}
}
void VertexManager::vFlush()
{

View File

@ -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;

View File

@ -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,75 +83,45 @@ 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]);
glDrawRangeElements(primitive_mode, 0, max_index, index_size, GL_UNSIGNED_SHORT, (u8*)NULL+s_index_offset);
}
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);
}
}
}
void VertexManager::vFlush()
{

View File

@ -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 <bool pr> __forceinline void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3)
template <bool pr> __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 <bool pr> void IndexGenerator::AddList(u32 const numVerts)
template <bool pr> u16* IndexGenerator::AddList(u16 *Iptr, u32 const numVerts, u32 index)
{
for (u32 i = 2; i < numVerts; i+=3)
{
WriteTriangle<pr>(index + i - 2, index + i - 1, index + i);
Iptr = WriteTriangle<pr>(Iptr, index + i - 2, index + i - 1, index + i);
}
return Iptr;
}
template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
template <bool pr> 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 <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
bool wind = false;
for (u32 i = 2; i < numVerts; ++i)
{
WriteTriangle<pr>(
Iptr = WriteTriangle<pr>(Iptr,
index + i - 2,
index + i - !wind,
index + i - wind);
@ -111,6 +96,7 @@ template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
wind ^= true;
}
}
return Iptr;
}
/**
@ -132,7 +118,7 @@ template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
* so we use 6 indices for 3 triangles
*/
template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
template <bool pr> u16* IndexGenerator::AddFan(u16 *Iptr, u32 numVerts, u32 index)
{
u32 i = 2;
@ -140,30 +126,29 @@ template <bool pr> 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<pr>(index, index + i - 1, index + i);
Iptr = WriteTriangle<pr>(Iptr, index, index + i - 1, index + i);
}
return Iptr;
}
/*
@ -183,71 +168,71 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
* A simple triangle has to be rendered for three vertices.
* ZWW do this for sun rays
*/
template <bool pr> void IndexGenerator::AddQuads(u32 numVerts)
template <bool pr> 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<pr>(index + i - 3, index + i - 2, index + i - 1);
WriteTriangle<pr>(index + i - 3, index + i - 1, index + i - 0);
Iptr = WriteTriangle<pr>(Iptr, index + i - 3, index + i - 2, index + i - 1);
Iptr = WriteTriangle<pr>(Iptr, index + i - 3, index + i - 1, index + i - 0);
}
}
// three vertices remaining, so render a triangle
if(i == numVerts)
{
WriteTriangle<pr>(index+numVerts-3, index+numVerts-2, index+numVerts-1);
Iptr = WriteTriangle<pr>(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;
}

View File

@ -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 <bool pr> static void AddList(u32 numVerts);
template <bool pr> static void AddStrip(u32 numVerts);
template <bool pr> static void AddFan(u32 numVerts);
template <bool pr> static void AddQuads(u32 numVerts);
template <bool pr> static u16* AddList(u16 *Iptr, u32 numVerts, u32 index);
template <bool pr> static u16* AddStrip(u16 *Iptr, u32 numVerts, u32 index);
template <bool pr> static u16* AddFan(u16 *Iptr, u32 numVerts, u32 index);
template <bool pr> 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 <bool pr> static void WriteTriangle(u32 index1, u32 index2, u32 index3);
template <bool pr> 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

View File

@ -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();

View File

@ -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<u8> LocalVBuffer;
std::vector<u16> TIBuffer;
std::vector<u16> LIBuffer;
std::vector<u16> PIBuffer;
std::vector<u16> LocalIBuffer;
};
extern VertexManager *g_vertex_manager;