Merge branch 'index_buffer_cleanup'
This commit is contained in:
commit
355df60abd
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue