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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index e9baadc..ea2fd3a 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -123,7 +123,8 @@ typedef struct
ID3D11RenderTargetView *mainRenderTargetView;
ID3D11RenderTargetView *currentOffscreenRenderTargetView;
ID3D11InputLayout *inputLayout;
- ID3D11Buffer *vertexBuffer;
+ ID3D11Buffer *vertexBuffers[8];
+ size_t vertexBufferSizes[8];
ID3D11VertexShader *vertexShader;
ID3D11PixelShader *pixelShaders[NUM_SHADERS];
int blendModesCount;
@@ -155,6 +156,7 @@ typedef struct
int currentViewportRotation;
SDL_bool viewportDirty;
Float4X4 identity;
+ int currentVertexBuffer;
} D3D11_RenderData;
@@ -242,7 +244,9 @@ D3D11_ReleaseAll(SDL_Renderer * renderer)
SAFE_RELEASE(data->mainRenderTargetView);
SAFE_RELEASE(data->currentOffscreenRenderTargetView);
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);
for (i = 0; i < SDL_arraysize(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
D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
const void * vertexData, size_t dataSizeInBytes)
{
D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
- D3D11_BUFFER_DESC vertexBufferDesc;
HRESULT result = S_OK;
- D3D11_SUBRESOURCE_DATA vertexBufferData;
- const UINT stride = sizeof(VertexPositionColor);
- const UINT offset = 0;
-
- if (rendererData->vertexBuffer) {
- ID3D11Buffer_GetDesc(rendererData->vertexBuffer, &vertexBufferDesc);
- } else {
- SDL_zero(vertexBufferDesc);
- }
+ const int vbidx = rendererData->currentVertexBuffer;
- if (rendererData->vertexBuffer && vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
+ if (rendererData->vertexBuffers[vbidx] && rendererData->vertexBufferSizes[vbidx] >= dataSizeInBytes) {
D3D11_MAPPED_SUBRESOURCE mappedResource;
result = ID3D11DeviceContext_Map(rendererData->d3dContext,
- (ID3D11Resource *)rendererData->vertexBuffer,
+ (ID3D11Resource *)rendererData->vertexBuffers[vbidx],
0,
D3D11_MAP_WRITE_DISCARD,
0,
@@ -1830,10 +1824,16 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
return -1;
}
SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
- ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffer, 0);
+ ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0);
} 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.Usage = D3D11_USAGE_DYNAMIC;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
@@ -1847,7 +1847,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
&vertexBufferDesc,
&vertexBufferData,
- &rendererData->vertexBuffer
+ &rendererData->vertexBuffers[vbidx]
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
@@ -1857,12 +1857,17 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
0,
1,
- &rendererData->vertexBuffer,
+ &rendererData->vertexBuffers[vbidx],
&stride,
&offset
);
}
+ rendererData->currentVertexBuffer++;
+ if (rendererData->currentVertexBuffer >= SDL_arraysize(rendererData->vertexBuffers)) {
+ rendererData->currentVertexBuffer = 0;
+ }
+
return 0;
}