Tweak Vertex/Index buffer handling a bit.

This commit is contained in:
Jordan Woyak 2013-02-26 22:47:50 -06:00
parent bd14ad5300
commit 6b80e6f83c
6 changed files with 69 additions and 79 deletions

View File

@ -517,7 +517,7 @@ void VertexLoader::WriteSetVariable(int bits, void *address, OpArg value)
#endif #endif
} }
void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const count)
{ {
m_numLoadedVertices += count; m_numLoadedVertices += count;
@ -560,21 +560,11 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
colElements[i] = m_VtxAttr.color[i].Elements; colElements[i] = m_VtxAttr.color[i].Elements;
if (VertexManager::GetRemainingSize() < count * native_stride) VertexManager::PrepareForAdditionalData(primitive, count, native_stride);
{
VertexManager::Flush();
if (VertexManager::GetRemainingSize() < count * native_stride)
ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! "
"Increase MAXVBUFFERSIZE or we need primitive breaking afterall.");
}
ConvertVertices(count); ConvertVertices(count);
VertexManager::AddVertices(primitive, count); VertexManager::AddVertices(primitive, count);
//VertexManager::Flush();
} }
void VertexLoader::ConvertVertices ( int count ) void VertexLoader::ConvertVertices ( int count )
{ {
#ifdef USE_JIT #ifdef USE_JIT
@ -598,7 +588,7 @@ void VertexLoader::ConvertVertices ( int count )
void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int count, u8* Data) void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int const count, u8* Data)
{ {
m_numLoadedVertices += count; m_numLoadedVertices += count;
@ -641,16 +631,15 @@ void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int co
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
colElements[i] = m_VtxAttr.color[i].Elements; colElements[i] = m_VtxAttr.color[i].Elements;
if(VertexManager::GetRemainingSize() < native_stride * count) VertexManager::PrepareForAdditionalData(primitive, count, native_stride);
VertexManager::Flush();
memcpy_gc(VertexManager::s_pCurBufferPointer, Data, native_stride * count); memcpy_gc(VertexManager::s_pCurBufferPointer, Data, native_stride * count);
VertexManager::s_pCurBufferPointer += native_stride * count; VertexManager::s_pCurBufferPointer += native_stride * count;
DataSkip(count * m_VertexSize); DataSkip(count * m_VertexSize);
VertexManager::AddVertices(primitive, count); VertexManager::AddVertices(primitive, count);
} }
void VertexLoader::SetVAT(u32 _group0, u32 _group1, u32 _group2) void VertexLoader::SetVAT(u32 _group0, u32 _group1, u32 _group2)
{ {
VAT vat; VAT vat;

View File

@ -23,38 +23,43 @@ u8 *VertexManager::s_pEndBufferPointer;
VertexManager::VertexManager() VertexManager::VertexManager()
{ {
LocalVBuffer = new u8[MAXVBUFFERSIZE]; LocalVBuffer.resize(MAXVBUFFERSIZE);
s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer; s_pCurBufferPointer = s_pBaseBufferPointer = &LocalVBuffer[0];
s_pEndBufferPointer = s_pBaseBufferPointer + MAXVBUFFERSIZE; s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size();
TIBuffer = new u16[MAXIBUFFERSIZE]; TIBuffer.resize(MAXIBUFFERSIZE);
LIBuffer = new u16[MAXIBUFFERSIZE]; LIBuffer.resize(MAXIBUFFERSIZE);
PIBuffer = new u16[MAXIBUFFERSIZE]; PIBuffer.resize(MAXIBUFFERSIZE);
ResetBuffer(); ResetBuffer();
} }
VertexManager::~VertexManager() VertexManager::~VertexManager()
{ {}
delete[] LocalVBuffer;
delete[] TIBuffer;
delete[] LIBuffer;
delete[] PIBuffer;
// TODO: necessary??
ResetBuffer();
}
void VertexManager::ResetBuffer() void VertexManager::ResetBuffer()
{ {
s_pCurBufferPointer = s_pBaseBufferPointer; s_pCurBufferPointer = s_pBaseBufferPointer;
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); IndexGenerator::Start(GetTriangleIndexBuffer(), GetLineIndexBuffer(), GetPointIndexBuffer());
} }
int VertexManager::GetRemainingSize() u32 VertexManager::GetRemainingSize()
{ {
return (int)(s_pEndBufferPointer - s_pCurBufferPointer); return (u32)(s_pEndBufferPointer - s_pCurBufferPointer);
}
void VertexManager::PrepareForAdditionalData(int primitive, u32 count, u32 stride)
{
u32 const needed_vertex_bytes = count * stride;
if (needed_vertex_bytes > GetRemainingSize() || count > GetRemainingIndices(primitive))
{
Flush();
if (needed_vertex_bytes > GetRemainingSize())
ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! "
"Increase MAXVBUFFERSIZE or we need primitive breaking afterall.");
}
} }
bool VertexManager::IsFlushed() const bool VertexManager::IsFlushed() const
@ -62,10 +67,7 @@ bool VertexManager::IsFlushed() const
return s_pBaseBufferPointer == s_pCurBufferPointer; return s_pBaseBufferPointer == s_pCurBufferPointer;
} }
// Not used anywhere u32 VertexManager::GetRemainingIndices(int primitive)
// TODO: use this
#if 0
int VertexManager::GetRemainingVertices(int primitive)
{ {
switch (primitive) switch (primitive)
{ {
@ -90,7 +92,6 @@ int VertexManager::GetRemainingVertices(int primitive)
break; break;
} }
} }
#endif
void VertexManager::AddVertices(int primitive, u32 numVertices) void VertexManager::AddVertices(int primitive, u32 numVertices)
{ {
@ -252,9 +253,16 @@ void VertexManager::DoState(PointerWrap& p)
void VertexManager::DoStateShared(PointerWrap& p) void VertexManager::DoStateShared(PointerWrap& p)
{ {
p.DoPointer(s_pCurBufferPointer, g_vertex_manager->LocalVBuffer); // It seems we half-assume to be flushed here
p.DoArray(LocalVBuffer, MAXVBUFFERSIZE); // We update s_pCurBufferPointer yet don't worry about IndexGenerator's outdated pointers
p.DoArray(g_vertex_manager->TIBuffer, MAXIBUFFERSIZE); // and maybe other things are overlooked
p.DoArray(g_vertex_manager->LIBuffer, MAXIBUFFERSIZE);
p.DoArray(g_vertex_manager->PIBuffer, MAXIBUFFERSIZE); p.Do(LocalVBuffer);
p.Do(TIBuffer);
p.Do(LIBuffer);
p.Do(PIBuffer);
s_pBaseBufferPointer = &LocalVBuffer[0];
s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size();
p.DoPointer(s_pCurBufferPointer, s_pBaseBufferPointer);
} }

View File

@ -2,6 +2,8 @@
#ifndef _VERTEXMANAGERBASE_H #ifndef _VERTEXMANAGERBASE_H
#define _VERTEXMANAGERBASE_H #define _VERTEXMANAGERBASE_H
#include <vector>
class NativeVertexFormat; class NativeVertexFormat;
class PointerWrap; class PointerWrap;
@ -15,16 +17,10 @@ private:
static const u32 MAX_PRIMITIVES_PER_COMMAND = (u16)-1; static const u32 MAX_PRIMITIVES_PER_COMMAND = (u16)-1;
public: public:
// values from OGL backend
//static const u32 MAXVBUFFERSIZE = 0x1FFFF;
// values from DX9/11 backend
static const u32 MAXVBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX; static const u32 MAXVBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX;
// We may convert triangle-fans to triangle-lists, almost 3x as many indices. // We may convert triangle-fans to triangle-lists, almost 3x as many indices.
// Watching for a full index buffer would probably be smarter than this calculation. static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3;
static const u32 MAXIBUFFERSIZE = MAXVBUFFERSIZE * 3 / SMALLEST_POSSIBLE_VERTEX;
//static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3;
VertexManager(); VertexManager();
// needs to be virtual for DX11's dtor // needs to be virtual for DX11's dtor
@ -36,29 +32,23 @@ public:
static u8 *s_pBaseBufferPointer; static u8 *s_pBaseBufferPointer;
static u8 *s_pEndBufferPointer; static u8 *s_pEndBufferPointer;
static int GetRemainingSize(); static u32 GetRemainingSize();
static void PrepareForAdditionalData(int primitive, u32 count, u32 stride);
//int GetRemainingVertices(int primitive); static u32 GetRemainingIndices(int primitive);
static void Flush(); static void Flush();
virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0; virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0;
// TODO: use these instead of TIBuffer, etc
// u16* GetTriangleIndexBuffer() { return TIBuffer; }
// u16* GetLineIndexBuffer() { return LIBuffer; }
// u16* GetPointIndexBuffer() { return PIBuffer; }
// u8* GetVertexBuffer() { return s_pBaseBufferPointer; }
static void DoState(PointerWrap& p); static void DoState(PointerWrap& p);
virtual void CreateDeviceObjects(){}; virtual void CreateDeviceObjects(){};
virtual void DestroyDeviceObjects(){}; virtual void DestroyDeviceObjects(){};
protected: protected:
u16* TIBuffer; u16* GetTriangleIndexBuffer() { return &TIBuffer[0]; }
u16* LIBuffer; u16* GetLineIndexBuffer() { return &LIBuffer[0]; }
u16* PIBuffer; u16* GetPointIndexBuffer() { return &PIBuffer[0]; }
u8* GetVertexBuffer() { return &s_pBaseBufferPointer[0]; }
virtual void vDoState(PointerWrap& p) { DoStateShared(p); } virtual void vDoState(PointerWrap& p) { DoStateShared(p); }
void DoStateShared(PointerWrap& p); void DoStateShared(PointerWrap& p);
@ -72,7 +62,10 @@ private:
// temp // temp
virtual void vFlush() = 0; virtual void vFlush() = 0;
u8* LocalVBuffer; std::vector<u8> LocalVBuffer;
std::vector<u16> TIBuffer;
std::vector<u16> LIBuffer;
std::vector<u16> PIBuffer;
}; };
extern VertexManager *g_vertex_manager; extern VertexManager *g_vertex_manager;

View File

@ -136,9 +136,9 @@ void VertexManager::LoadBuffers()
m_triangleDrawIndex = m_indexBufferCursor; m_triangleDrawIndex = m_indexBufferCursor;
m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen();
m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen(); m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen();
memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); memcpy((u16*)map.pData + m_triangleDrawIndex, GetTriangleIndexBuffer(), sizeof(u16) * IndexGenerator::GetTriangleindexLen());
memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); memcpy((u16*)map.pData + m_lineDrawIndex, GetLineIndexBuffer(), sizeof(u16) * IndexGenerator::GetLineindexLen());
memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); memcpy((u16*)map.pData + m_pointDrawIndex, GetPointIndexBuffer(), sizeof(u16) * IndexGenerator::GetPointindexLen());
D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0);
m_indexBufferCursor += iCount; m_indexBufferCursor += iCount;
} }

View File

@ -192,17 +192,17 @@ void VertexManager::PrepareVBuffers(int stride)
} }
if(TdataSize) if(TdataSize)
{ {
memcpy(pIndices, TIBuffer, TdataSize * sizeof(u16)); memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16));
pIndices += TdataSize; pIndices += TdataSize;
} }
if(LDataSize) if(LDataSize)
{ {
memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16));
pIndices += LDataSize; pIndices += LDataSize;
} }
if(PDataSize) if(PDataSize)
{ {
memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); memcpy(pIndices, GetPointIndexBuffer(), PDataSize * sizeof(u16));
} }
IBuffers[CurrentIBuffer]->Unlock(); IBuffers[CurrentIBuffer]->Unlock();
D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride); D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride);
@ -266,7 +266,7 @@ void VertexManager::DrawVA(int stride)
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(),
TIBuffer, GetTriangleIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))
@ -280,7 +280,7 @@ void VertexManager::DrawVA(int stride)
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST, D3DPT_LINELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(),
LIBuffer, GetLineIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))
@ -294,7 +294,7 @@ void VertexManager::DrawVA(int stride)
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST, D3DPT_POINTLIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(),
PIBuffer, GetPointIndexBuffer(),
D3DFMT_INDEX16, D3DFMT_INDEX16,
s_pBaseBufferPointer, s_pBaseBufferPointer,
stride))) stride)))

View File

@ -83,17 +83,17 @@ void VertexManager::Draw()
{ {
if (IndexGenerator::GetNumTriangles() > 0) if (IndexGenerator::GetNumTriangles() > 0)
{ {
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, GetTriangleIndexBuffer());
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumLines() > 0) if (IndexGenerator::GetNumLines() > 0)
{ {
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, GetLineIndexBuffer());
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumPoints() > 0) if (IndexGenerator::GetNumPoints() > 0)
{ {
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, GetPointIndexBuffer());
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
} }