298 changes: 260 additions & 38 deletions Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
Expand Up @@ -39,7 +39,6 @@

// internal state for loading vertices
extern NativeVertexFormat *g_nativeVertexFmt;

namespace DX9
{

Expand All @@ -62,49 +61,259 @@ inline void DumpBadShaders()
#endif
}

void VertexManager::Draw(int stride)
void VertexManager::CreateDeviceObjects()
{
if (IndexGenerator::GetNumTriangles() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(),
TIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
NumVBuffers = 0;
CurrentIBufferIndex = 0;
CurrentVBufferIndex = 0;
CurrentVBufferSize = 8 * MAXVBUFFERSIZE;
CurrentIBufferSize = 12 * MAXIBUFFERSIZE;
D3DCAPS9 DeviceCaps = D3D::GetCaps();
int maxdevicevbuffersize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride;
if (CurrentVBufferSize > maxdevicevbuffersize)
{
CurrentVBufferSize = maxdevicevbuffersize;
}
if (CurrentIBufferSize > DeviceCaps.MaxVertexIndex)
{
CurrentIBufferSize = DeviceCaps.MaxVertexIndex;
}
if (CurrentIBufferSize < MAXIBUFFERSIZE)
{
return;
}
if (CurrentVBufferSize < MAXVBUFFERSIZE)
{
return;
}
VBuffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBufferCount];
IBuffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBufferCount];
bool Fail = false;
for (CurrentVBuffer = 0; CurrentVBuffer < MAX_VBufferCount; CurrentVBuffer++)
{
VBuffers[CurrentVBuffer] = NULL;
IBuffers[CurrentVBuffer] = NULL;
}
for (CurrentVBuffer = 0; CurrentVBuffer < MAX_VBufferCount; CurrentVBuffer++)
{
if(FAILED( D3D::dev->CreateVertexBuffer( CurrentVBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &VBuffers[CurrentVBuffer], NULL ) ) )
{
DumpBadShaders();
Fail = true;
break;
}
if( FAILED( D3D::dev->CreateIndexBuffer( CurrentIBufferSize * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IBuffers[CurrentVBuffer], NULL ) ) )
{
Fail = true;
return;
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumLines() > 0)
NumVBuffers = CurrentVBuffer;
CurrentVBuffer = 0;
CurrentIBuffer = 0;
LastVBuffer = NumVBuffers;
LastIBuffer = NumVBuffers;
if (Fail)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(),
LIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
NumVBuffers--;
if (NumVBuffers < 2)
{
DumpBadShaders();
NumVBuffers = MAX_VBufferCount;
DestroyDeviceObjects();
}
}

}
void VertexManager::DestroyDeviceObjects()
{
D3D::dev->SetStreamSource( 0, NULL, 0, 0);
D3D::dev->SetIndices(NULL);
for (int i = 0; i < MAX_VBufferCount; i++)
{
if(VBuffers)
{
if (VBuffers[i])
{
VBuffers[i]->Release();
VBuffers[i] = NULL;
}
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);

if (IBuffers[i])
{
IBuffers[i]->Release();
IBuffers[i] = NULL;
}
}
if(VBuffers)
delete [] VBuffers;
if(IBuffers)
delete [] IBuffers;
VBuffers = NULL;
IBuffers = NULL;
}

VertexManager::VertexManager()
{
//CreateDeviceObjects();
}

VertexManager::~VertexManager()
{
//DestroyDeviceObjects();
}

void VertexManager::PrepareVBuffers(int stride)
{
if (!NumVBuffers)
{
return;
}
u8* pVertices;
u16* pIndices;
int datasize = IndexGenerator::GetNumVerts() * stride;
int TdataSize = IndexGenerator::GetTriangleindexLen();
int LDataSize = IndexGenerator::GetLineindexLen();
int PDataSize = IndexGenerator::GetPointindexLen();
int IndexDataSize = TdataSize + LDataSize + PDataSize;
DWORD LockMode = D3DLOCK_NOOVERWRITE;

if (CurrentVBufferIndex > CurrentVBufferSize - datasize || LastVBuffer != CurrentVBuffer)
{
LockMode = D3DLOCK_DISCARD;
CurrentVBufferIndex = 0;
CurrentVBuffer = (CurrentVBuffer + 1) % NumVBuffers;
}

if(FAILED(VBuffers[CurrentVBuffer]->Lock(CurrentVBufferIndex, datasize,(VOID**)(&pVertices), LockMode)))
{
DestroyDeviceObjects();
return;
}
memcpy(pVertices, LocalVBuffer, datasize);
VBuffers[CurrentVBuffer]->Unlock();

LockMode = D3DLOCK_NOOVERWRITE;

if (CurrentIBufferIndex > CurrentIBufferSize - IndexDataSize || LastIBuffer != CurrentIBuffer)
{
LockMode = D3DLOCK_DISCARD;
CurrentIBufferIndex = 0;
CurrentIBuffer = (CurrentIBuffer + 1) % NumVBuffers;
}
if (IndexGenerator::GetNumPoints() > 0)

if(FAILED(IBuffers[CurrentIBuffer]->Lock(CurrentIBufferIndex * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode )))
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(),
PIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
DestroyDeviceObjects();
return;
}
if(TdataSize)
{
memcpy(pIndices, TIBuffer, TdataSize * sizeof(u16));
pIndices += TdataSize;
}
if(LDataSize)
{
memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16));
pIndices += LDataSize;
}
if(PDataSize)
{
memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16));
}
IBuffers[CurrentIBuffer]->Unlock();
}

void VertexManager::Draw(int stride)
{
if(NumVBuffers)
{
if (IndexGenerator::GetNumTriangles() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex,
IndexGenerator::GetNumTriangles())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumLines() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen(),
IndexGenerator::GetNumLines())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumPoints() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_POINTLIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(),
IndexGenerator::GetNumPoints())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
}
else
{
if (IndexGenerator::GetNumTriangles() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(),
TIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumLines() > 0)
{
DumpBadShaders();
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(),
LIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumPoints() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(),
PIBuffer,
D3DFMT_INDEX16,
LocalVBuffer,
stride)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
}

Expand Down Expand Up @@ -153,7 +362,7 @@ void VertexManager::vFlush()
// set global constants
VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants();

int 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");});
Expand All @@ -165,10 +374,18 @@ void VertexManager::vFlush()
goto shader_fail;

}

int stride = g_nativeVertexFmt->GetVertexStride();
g_nativeVertexFmt->SetupVertexPointers();

PrepareVBuffers(stride);
if (NumVBuffers)
{
D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride);
if(LastIBuffer != CurrentIBuffer)
{
LastIBuffer = CurrentIBuffer;
D3D::dev->SetIndices(IBuffers[CurrentIBuffer]);
}
LastVBuffer = CurrentVBuffer;
}
g_nativeVertexFmt->SetupVertexPointers();
Draw(stride);

bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
Expand All @@ -189,6 +406,11 @@ void VertexManager::vFlush()
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);

shader_fail:
if(NumVBuffers)
{
CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride;
}
ResetBuffer();
}

Expand Down
17 changes: 17 additions & 0 deletions Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h
Expand Up @@ -23,6 +23,7 @@

#include "VertexManagerBase.h"

#define MAX_VBufferCount 4
namespace DX9
{

Expand All @@ -31,8 +32,24 @@ class VertexManager : public ::VertexManager
public:
NativeVertexFormat* CreateNativeVertexFormat();
void GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num);
void CreateDeviceObjects();
void DestroyDeviceObjects();
VertexManager();
~VertexManager();

private:
u32 CurrentVBufferIndex;
u32 CurrentVBufferSize;
u32 CurrentIBufferIndex;
u32 CurrentIBufferSize;
u32 NumVBuffers;
u32 CurrentVBuffer;
u32 CurrentIBuffer;
u32 LastVBuffer;
u32 LastIBuffer;
LPDIRECT3DVERTEXBUFFER9 *VBuffers;
LPDIRECT3DINDEXBUFFER9 *IBuffers;
void PrepareVBuffers(int stride);
void Draw(int stride);
// temp
void vFlush();
Expand Down
6 changes: 3 additions & 3 deletions Source/Plugins/Plugin_VideoDX9/Src/main.cpp
Expand Up @@ -168,9 +168,9 @@ void VideoBackend::Video_Prepare()
s_swapRequested = FALSE;

// internal interfaces
g_renderer = new Renderer;
g_texture_cache = new TextureCache;
g_vertex_manager = new VertexManager;
g_renderer = new Renderer;
g_texture_cache = new TextureCache;
// VideoCommon
BPInit();
Fifo_Init();
Expand Down Expand Up @@ -208,9 +208,9 @@ void VideoBackend::Shutdown()
// internal interfaces
PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown();
delete g_vertex_manager;
delete g_texture_cache;
delete g_renderer;
delete g_vertex_manager;
g_renderer = NULL;
g_texture_cache = NULL;
}
Expand Down
10 changes: 10 additions & 0 deletions Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
Expand Up @@ -69,6 +69,16 @@ VertexManager::VertexManager()
GL_REPORT_ERRORD();
}

void VertexManager::CreateDeviceObjects()
{


}
void VertexManager::DestroyDeviceObjects()
{

}

void VertexManager::Draw()
{
if (IndexGenerator::GetNumTriangles() > 0)
Expand Down
3 changes: 2 additions & 1 deletion Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h
Expand Up @@ -33,7 +33,8 @@ class VertexManager : public ::VertexManager
VertexManager();

NativeVertexFormat* CreateNativeVertexFormat();

void CreateDeviceObjects();
void DestroyDeviceObjects();
private:
void Draw();
// temp
Expand Down