Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Hey, long time no commits :).
So to compensate lets bring back some speed to the emulation.
change a little the way the vertex are send to the gpu,
This first implementation changes dx9 a lot and dx11 a little to increase the parallelism between the cpu and gpu.
ogl: is my next step in ogl is a little more trickier so i have to take a little more time.
the original concept is Marcos idea, with my little touch to make it even more faster.
what to look for: SPEEEEEDDD :).
please test it a lot and let me know if you see any problem.
in dx9 the code is prepared to fall back to the previous implementation if your card does not support the amount of buffers needed.
So if you did not experience any speed gains you know where is the problem :).
for the ones with more experience and compression of the code please test changing the amount and size of the buffers to tune this for your specific machine.
The current values are the sweet spot for my machine.
All must Thanks Marcos, I hate him for giving good ideas when I'm full of work.
  • Loading branch information
Tinob committed Oct 20, 2012
1 parent 0384f61 commit 5230146
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 89 deletions.
5 changes: 3 additions & 2 deletions Source/Core/VideoCommon/Src/VertexManagerBase.h
Expand Up @@ -21,7 +21,7 @@ class VertexManager

// values from DX11 backend
MAXVBUFFERSIZE = 0x50000,
MAXIBUFFERSIZE = 0x10000,
MAXIBUFFERSIZE = 0xFFFF,
};

VertexManager();
Expand All @@ -46,7 +46,8 @@ class VertexManager
static u8* GetVertexBuffer() { return LocalVBuffer; }

static void DoState(PointerWrap& p);

virtual void CreateDeviceObjects(){};
virtual void DestroyDeviceObjects(){};
protected:
// TODO: make private after Flush() is merged
static void ResetBuffer();
Expand Down
96 changes: 57 additions & 39 deletions Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
Expand Up @@ -39,32 +39,47 @@ namespace DX11
{

// TODO: Find sensible values for these two
const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE*2 * 16;
const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 12;
const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 8;
const UINT MAXVBUFFER_COUNT = 4;

void VertexManager::CreateDeviceObjects()
{
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE,
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);

CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffer)),
"Failed to create index buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffer, "index buffer of VertexManager");

bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufdesc.ByteWidth = VBUFFER_SIZE;

CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffer)),
"Failed to create vertex buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffer, "vertex buffer of VertexManager");

m_indexBufferCursor = 0;
m_vertexBufferCursor = 0;
m_vertexDrawOffset = 0;

m_triangleDrawIndex = 0;
m_lineDrawIndex = 0;
m_pointDrawIndex = 0;
m_indexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT];
m_vertexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT];
bool Fail = false;
for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++)
{
m_indexBuffers[m_activeVertexBuffer] = NULL;
m_vertexBuffers[m_activeVertexBuffer] = NULL;
}
for (m_activeIndexBuffer = 0; m_activeIndexBuffer < MAXVBUFFER_COUNT; m_activeIndexBuffer++)
{
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffers[m_activeIndexBuffer])),
"Failed to create index buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffers[m_activeIndexBuffer], "index buffer of VertexManager");
}
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufdesc.ByteWidth = VBUFFER_SIZE;
for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++)
{
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffers[m_activeVertexBuffer])),
"Failed to create vertex buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffers[m_activeVertexBuffer], "Vertex buffer of VertexManager");
}
m_activeVertexBuffer = 0;
m_activeIndexBuffer = 0;
m_LastVertexBuffer = MAXVBUFFER_COUNT;
m_LastIndexBuffer = MAXVBUFFER_COUNT;

m_lineShader.Init();
m_pointShader.Init();
Expand All @@ -74,9 +89,12 @@ void VertexManager::DestroyDeviceObjects()
{
m_pointShader.Shutdown();
m_lineShader.Shutdown();

SAFE_RELEASE(m_vertexBuffer);
SAFE_RELEASE(m_indexBuffer);
for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++)
{
SAFE_RELEASE(m_vertexBuffers[m_activeVertexBuffer]);
SAFE_RELEASE(m_indexBuffers[m_activeVertexBuffer]);
}

}

VertexManager::VertexManager()
Expand All @@ -94,42 +112,41 @@ void VertexManager::LoadBuffers()
D3D11_MAPPED_SUBRESOURCE map;

UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer);
if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE)
D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE || m_activeVertexBuffer != m_LastVertexBuffer)
{
// Wrap around
D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
m_activeVertexBuffer = (m_activeVertexBuffer + 1) % MAXVBUFFER_COUNT;
m_vertexBufferCursor = 0;
MapType = D3D11_MAP_WRITE_DISCARD;
}
else
{
// Append data
D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
}

D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map);

memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize);
D3D::context->Unmap(m_vertexBuffer, 0);
D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0);
m_vertexDrawOffset = m_vertexBufferCursor;
m_vertexBufferCursor += vSize;

UINT iCount = IndexGenerator::GetTriangleindexLen() +
IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2)
MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2 || m_activeIndexBuffer != m_LastIndexBuffer)
{
// Wrap around
D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
m_activeIndexBuffer = (m_activeIndexBuffer + 1) % MAXVBUFFER_COUNT;
m_indexBufferCursor = 0;
MapType = D3D11_MAP_WRITE_DISCARD;
}
else
{
// Append data
D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
}
D3D::context->Map(m_indexBuffers[m_activeIndexBuffer], 0, MapType, 0, &map);

m_triangleDrawIndex = m_indexBufferCursor;
m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen();
m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen();
memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, 2*IndexGenerator::GetTriangleindexLen());
memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, 2*IndexGenerator::GetLineindexLen());
memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, 2*IndexGenerator::GetPointindexLen());
D3D::context->Unmap(m_indexBuffer, 0);
D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0);
m_indexBufferCursor += iCount;
}

Expand All @@ -139,9 +156,11 @@ static const float LINE_PT_TEX_OFFSETS[8] = {

void VertexManager::Draw(UINT stride)
{
D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset);
D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);

D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffers[m_activeVertexBuffer], &stride, &m_vertexDrawOffset);
D3D::context->IASetIndexBuffer(m_indexBuffers[m_activeIndexBuffer], DXGI_FORMAT_R16_UINT, 0);
m_LastIndexBuffer = m_activeIndexBuffer;
m_LastVertexBuffer = m_activeVertexBuffer;

if (IndexGenerator::GetNumTriangles() > 0)
{
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Expand Down Expand Up @@ -260,12 +279,11 @@ void VertexManager::vFlush()
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail;
}

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

g_renderer->ApplyState(useDstAlpha);
LoadBuffers();

Draw(stride);

GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
Expand Down
16 changes: 11 additions & 5 deletions Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h
Expand Up @@ -32,10 +32,11 @@ class VertexManager : public ::VertexManager
~VertexManager();

NativeVertexFormat* CreateNativeVertexFormat();

private:
void CreateDeviceObjects();
void DestroyDeviceObjects();

private:

void LoadBuffers();
void Draw(UINT stride);
// temp
Expand All @@ -46,9 +47,14 @@ class VertexManager : public ::VertexManager
UINT m_vertexDrawOffset;
UINT m_triangleDrawIndex;
UINT m_lineDrawIndex;
UINT m_pointDrawIndex;
ID3D11Buffer* m_indexBuffer;
ID3D11Buffer* m_vertexBuffer;
UINT m_pointDrawIndex;
UINT m_activeVertexBuffer;
UINT m_activeIndexBuffer;
UINT m_LastVertexBuffer;
UINT m_LastIndexBuffer;
typedef ID3D11Buffer* PID3D11Buffer;
PID3D11Buffer* m_indexBuffers;
PID3D11Buffer* m_vertexBuffers;

LineGeometryShader m_lineShader;
PointGeometryShader m_pointShader;
Expand Down
15 changes: 14 additions & 1 deletion Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
Expand Up @@ -225,6 +225,7 @@ void SetupDeviceObjects()
// To avoid shader compilation stutters, read back all shaders from cache.
VertexShaderCache::Init();
PixelShaderCache::Init();
g_vertex_manager->CreateDeviceObjects();
// Texture cache will recreate themselves over time.
}

Expand All @@ -243,6 +244,7 @@ void TeardownDeviceObjects()
VertexShaderCache::Shutdown();
PixelShaderCache::Shutdown();
TextureConverter::Shutdown();
g_vertex_manager->DestroyDeviceObjects();
}

// Init functions
Expand Down Expand Up @@ -1198,14 +1200,25 @@ void Renderer::ApplyState(bool bUseDstAlpha)
{
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
if(bpmem.zmode.testenable && bpmem.zmode.updateenable)
{
D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE);
D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false);
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
}
}
}

void Renderer::RestoreState()
{
D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE);
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);

if(bpmem.zmode.testenable && bpmem.zmode.updateenable)
{
D3D::RefreshRenderState(D3DRS_ZENABLE);
D3D::RefreshRenderState(D3DRS_ZWRITEENABLE);
D3D::RefreshRenderState(D3DRS_ZFUNC);
}
// TODO: Enable this code. Caused glitches for me however (neobrain)
// for (unsigned int i = 0; i < 8; ++i)
// D3D::dev->SetTexture(i, NULL);
Expand Down

0 comments on commit 5230146

Please sign in to comment.