render: D3D11 now cycles through 8 vertex buffers.

This means it doesn't have to block while the current frame finishes using the
vertex buffer; it just moves on to the next, probably-not-in-use buffer.
This commit is contained in:
Ryan C. Gordon 2018-10-03 19:05:20 -04:00
parent a9094a21a8
commit bd08a4e6b1

View File

@ -123,7 +123,8 @@ typedef struct
ID3D11RenderTargetView *mainRenderTargetView; ID3D11RenderTargetView *mainRenderTargetView;
ID3D11RenderTargetView *currentOffscreenRenderTargetView; ID3D11RenderTargetView *currentOffscreenRenderTargetView;
ID3D11InputLayout *inputLayout; ID3D11InputLayout *inputLayout;
ID3D11Buffer *vertexBuffer; ID3D11Buffer *vertexBuffers[8];
size_t vertexBufferSizes[8];
ID3D11VertexShader *vertexShader; ID3D11VertexShader *vertexShader;
ID3D11PixelShader *pixelShaders[NUM_SHADERS]; ID3D11PixelShader *pixelShaders[NUM_SHADERS];
int blendModesCount; int blendModesCount;
@ -155,6 +156,7 @@ typedef struct
int currentViewportRotation; int currentViewportRotation;
SDL_bool viewportDirty; SDL_bool viewportDirty;
Float4X4 identity; Float4X4 identity;
int currentVertexBuffer;
} D3D11_RenderData; } D3D11_RenderData;
@ -242,7 +244,9 @@ D3D11_ReleaseAll(SDL_Renderer * renderer)
SAFE_RELEASE(data->mainRenderTargetView); SAFE_RELEASE(data->mainRenderTargetView);
SAFE_RELEASE(data->currentOffscreenRenderTargetView); SAFE_RELEASE(data->currentOffscreenRenderTargetView);
SAFE_RELEASE(data->inputLayout); SAFE_RELEASE(data->inputLayout);
SAFE_RELEASE(data->vertexBuffer); for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
SAFE_RELEASE(data->vertexBuffers[i]);
}
SAFE_RELEASE(data->vertexShader); SAFE_RELEASE(data->vertexShader);
for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) { for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) {
SAFE_RELEASE(data->pixelShaders[i]); SAFE_RELEASE(data->pixelShaders[i]);
@ -1798,28 +1802,18 @@ D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture *
} }
/* !!! FIXME: rotate through a few vertex buffers so the GPU has time to finish using them */
static int static int
D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
const void * vertexData, size_t dataSizeInBytes) const void * vertexData, size_t dataSizeInBytes)
{ {
D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
D3D11_BUFFER_DESC vertexBufferDesc;
HRESULT result = S_OK; HRESULT result = S_OK;
D3D11_SUBRESOURCE_DATA vertexBufferData; const int vbidx = rendererData->currentVertexBuffer;
const UINT stride = sizeof(VertexPositionColor);
const UINT offset = 0;
if (rendererData->vertexBuffer) { if (rendererData->vertexBuffers[vbidx] && rendererData->vertexBufferSizes[vbidx] >= dataSizeInBytes) {
ID3D11Buffer_GetDesc(rendererData->vertexBuffer, &vertexBufferDesc);
} else {
SDL_zero(vertexBufferDesc);
}
if (rendererData->vertexBuffer && vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
result = ID3D11DeviceContext_Map(rendererData->d3dContext, result = ID3D11DeviceContext_Map(rendererData->d3dContext,
(ID3D11Resource *)rendererData->vertexBuffer, (ID3D11Resource *)rendererData->vertexBuffers[vbidx],
0, 0,
D3D11_MAP_WRITE_DISCARD, D3D11_MAP_WRITE_DISCARD,
0, 0,
@ -1830,10 +1824,16 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
return -1; return -1;
} }
SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes); SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffer, 0); ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0);
} else { } else {
SAFE_RELEASE(rendererData->vertexBuffer); D3D11_BUFFER_DESC vertexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexBufferData;
const UINT stride = sizeof(VertexPositionColor);
const UINT offset = 0;
SAFE_RELEASE(rendererData->vertexBuffers[vbidx]);
SDL_zero(vertexBufferDesc);
vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes; vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes;
vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
@ -1847,7 +1847,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
result = ID3D11Device_CreateBuffer(rendererData->d3dDevice, result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
&vertexBufferDesc, &vertexBufferDesc,
&vertexBufferData, &vertexBufferData,
&rendererData->vertexBuffer &rendererData->vertexBuffers[vbidx]
); );
if (FAILED(result)) { if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
@ -1857,12 +1857,17 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext, ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
0, 0,
1, 1,
&rendererData->vertexBuffer, &rendererData->vertexBuffers[vbidx],
&stride, &stride,
&offset &offset
); );
} }
rendererData->currentVertexBuffer++;
if (rendererData->currentVertexBuffer >= SDL_arraysize(rendererData->vertexBuffers)) {
rendererData->currentVertexBuffer = 0;
}
return 0; return 0;
} }