workaround for broken d3d11 constant buffer updates
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
d3d5a5a525
commit
397e84fe4a
|
@ -53,7 +53,7 @@
|
||||||
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
|
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
|
||||||
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
||||||
#define WINDOW_DATA "Refresh_D3D11WindowData"
|
#define WINDOW_DATA "Refresh_D3D11WindowData"
|
||||||
#define UBO_BUFFER_SIZE 16000 /* 16KB */
|
#define UBO_BUFFER_SIZE 1048576 /* 1 MiB */
|
||||||
|
|
||||||
#define NOT_IMPLEMENTED SDL_assert(0 && "Not implemented!");
|
#define NOT_IMPLEMENTED SDL_assert(0 && "Not implemented!");
|
||||||
|
|
||||||
|
@ -458,10 +458,9 @@ typedef struct D3D11TransferBufferContainer
|
||||||
|
|
||||||
typedef struct D3D11UniformBuffer
|
typedef struct D3D11UniformBuffer
|
||||||
{
|
{
|
||||||
D3D11Buffer *d3d11Buffer;
|
D3D11Buffer d3d11Buffer;
|
||||||
uint32_t offset; /* number of bytes written */
|
uint32_t offset; /* number of bytes written */
|
||||||
uint32_t drawOffset; /* parameter for SetConstantBuffers */
|
uint32_t drawOffset; /* parameter for SetConstantBuffers */
|
||||||
uint8_t hasDiscarded;
|
|
||||||
} D3D11UniformBuffer;
|
} D3D11UniformBuffer;
|
||||||
|
|
||||||
typedef struct D3D11Fence
|
typedef struct D3D11Fence
|
||||||
|
@ -707,8 +706,7 @@ static void D3D11_DestroyDevice(
|
||||||
for (uint32_t i = 0; i < renderer->availableUniformBufferCount; i += 1)
|
for (uint32_t i = 0; i < renderer->availableUniformBufferCount; i += 1)
|
||||||
{
|
{
|
||||||
D3D11UniformBuffer *uniformBuffer = renderer->availableUniformBuffers[i];
|
D3D11UniformBuffer *uniformBuffer = renderer->availableUniformBuffers[i];
|
||||||
ID3D11Buffer_Release(uniformBuffer->d3d11Buffer->handle);
|
ID3D11Buffer_Release(uniformBuffer->d3d11Buffer.handle);
|
||||||
SDL_free(uniformBuffer->d3d11Buffer);
|
|
||||||
SDL_free(uniformBuffer);
|
SDL_free(uniformBuffer);
|
||||||
}
|
}
|
||||||
SDL_free(renderer->availableUniformBuffers);
|
SDL_free(renderer->availableUniformBuffers);
|
||||||
|
@ -781,13 +779,25 @@ static void D3D11_DrawInstancedPrimitives(
|
||||||
uint32_t vertexBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->vertexUniformBlockSize / 16;
|
uint32_t vertexBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->vertexUniformBlockSize / 16;
|
||||||
uint32_t fragmentBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->fragmentUniformBlockSize / 16;
|
uint32_t fragmentBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->fragmentUniformBlockSize / 16;
|
||||||
|
|
||||||
|
ID3D11Buffer *nullBuf = NULL;
|
||||||
|
|
||||||
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
|
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
|
||||||
{
|
{
|
||||||
|
/* stupid workaround for god awful D3D11 drivers
|
||||||
|
* see: https://learn.microsoft.com/en-us/windows/win32/api/d3d11_1/nf-d3d11_1-id3d11devicecontext1-vssetconstantbuffers1#calling-vssetconstantbuffers1-with-command-list-emulation
|
||||||
|
*/
|
||||||
|
ID3D11DeviceContext1_VSSetConstantBuffers(
|
||||||
|
d3d11CommandBuffer->context,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
&nullBuf
|
||||||
|
);
|
||||||
|
|
||||||
ID3D11DeviceContext1_VSSetConstantBuffers1(
|
ID3D11DeviceContext1_VSSetConstantBuffers1(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer.handle,
|
||||||
&vertexOffsetInConstants,
|
&vertexOffsetInConstants,
|
||||||
&vertexBlockSizeInConstants
|
&vertexBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -795,11 +805,19 @@ static void D3D11_DrawInstancedPrimitives(
|
||||||
|
|
||||||
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
|
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
|
||||||
{
|
{
|
||||||
|
/* another stupid workaround for god awful D3D11 drivers */
|
||||||
|
ID3D11DeviceContext1_PSSetConstantBuffers(
|
||||||
|
d3d11CommandBuffer->context,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
&nullBuf
|
||||||
|
);
|
||||||
|
|
||||||
ID3D11DeviceContext1_PSSetConstantBuffers1(
|
ID3D11DeviceContext1_PSSetConstantBuffers1(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer.handle,
|
||||||
&fragmentOffsetInConstants,
|
&fragmentOffsetInConstants,
|
||||||
&fragmentBlockSizeInConstants
|
&fragmentBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -850,7 +868,7 @@ static void D3D11_DrawPrimitives(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer.handle,
|
||||||
&vertexOffsetInConstants,
|
&vertexOffsetInConstants,
|
||||||
&vertexBlockSizeInConstants
|
&vertexBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -862,7 +880,7 @@ static void D3D11_DrawPrimitives(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer.handle,
|
||||||
&fragmentOffsetInConstants,
|
&fragmentOffsetInConstants,
|
||||||
&fragmentBlockSizeInConstants
|
&fragmentBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -896,7 +914,7 @@ static void D3D11_DrawPrimitivesIndirect(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer.handle,
|
||||||
&vertexOffsetInConstants,
|
&vertexOffsetInConstants,
|
||||||
&vertexBlockSizeInConstants
|
&vertexBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -908,7 +926,7 @@ static void D3D11_DrawPrimitivesIndirect(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer.handle,
|
||||||
&fragmentOffsetInConstants,
|
&fragmentOffsetInConstants,
|
||||||
&fragmentBlockSizeInConstants
|
&fragmentBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -938,13 +956,23 @@ static void D3D11_DispatchCompute(
|
||||||
uint32_t computeOffsetInConstants = d3d11CommandBuffer->computeUniformBuffer != NULL ? d3d11CommandBuffer->computeUniformBuffer->drawOffset / 16 : 0;
|
uint32_t computeOffsetInConstants = d3d11CommandBuffer->computeUniformBuffer != NULL ? d3d11CommandBuffer->computeUniformBuffer->drawOffset / 16 : 0;
|
||||||
uint32_t computeBlockSizeInConstants = (uint32_t) (d3d11CommandBuffer->computePipeline->computeUniformBlockSize / 16);
|
uint32_t computeBlockSizeInConstants = (uint32_t) (d3d11CommandBuffer->computePipeline->computeUniformBlockSize / 16);
|
||||||
|
|
||||||
|
ID3D11Buffer *nullBuf = NULL;
|
||||||
|
|
||||||
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
|
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
|
||||||
{
|
{
|
||||||
|
/* another stupid workaround for god awful D3D11 drivers */
|
||||||
|
ID3D11DeviceContext1_CSSetConstantBuffers(
|
||||||
|
d3d11CommandBuffer->context,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
&nullBuf
|
||||||
|
);
|
||||||
|
|
||||||
ID3D11DeviceContext1_CSSetConstantBuffers1(
|
ID3D11DeviceContext1_CSSetConstantBuffers1(
|
||||||
d3d11CommandBuffer->context,
|
d3d11CommandBuffer->context,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&d3d11CommandBuffer->computeUniformBuffer->d3d11Buffer->handle,
|
&d3d11CommandBuffer->computeUniformBuffer->d3d11Buffer.handle,
|
||||||
&computeOffsetInConstants,
|
&computeOffsetInConstants,
|
||||||
&computeBlockSizeInConstants
|
&computeBlockSizeInConstants
|
||||||
);
|
);
|
||||||
|
@ -2417,10 +2445,10 @@ static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
|
||||||
|
|
||||||
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
bufferDesc.ByteWidth = UBO_BUFFER_SIZE;
|
bufferDesc.ByteWidth = UBO_BUFFER_SIZE;
|
||||||
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
bufferDesc.CPUAccessFlags = 0;
|
||||||
bufferDesc.MiscFlags = 0;
|
bufferDesc.MiscFlags = 0;
|
||||||
bufferDesc.StructureByteStride = 0;
|
bufferDesc.StructureByteStride = 0;
|
||||||
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
|
||||||
res = ID3D11Device_CreateBuffer(
|
res = ID3D11Device_CreateBuffer(
|
||||||
renderer->device,
|
renderer->device,
|
||||||
|
@ -2433,11 +2461,9 @@ static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
|
||||||
uniformBuffer = SDL_malloc(sizeof(D3D11UniformBuffer));
|
uniformBuffer = SDL_malloc(sizeof(D3D11UniformBuffer));
|
||||||
uniformBuffer->offset = 0;
|
uniformBuffer->offset = 0;
|
||||||
uniformBuffer->drawOffset = 0;
|
uniformBuffer->drawOffset = 0;
|
||||||
uniformBuffer->hasDiscarded = 0;
|
uniformBuffer->d3d11Buffer.handle = bufferHandle;
|
||||||
uniformBuffer->d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
|
uniformBuffer->d3d11Buffer.size = UBO_BUFFER_SIZE;
|
||||||
uniformBuffer->d3d11Buffer->handle = bufferHandle;
|
uniformBuffer->d3d11Buffer.uav = NULL;
|
||||||
uniformBuffer->d3d11Buffer->size = UBO_BUFFER_SIZE;
|
|
||||||
uniformBuffer->d3d11Buffer->uav = NULL;
|
|
||||||
|
|
||||||
/* Add it to the available pool */
|
/* Add it to the available pool */
|
||||||
if (renderer->availableUniformBufferCount >= renderer->availableUniformBufferCapacity)
|
if (renderer->availableUniformBufferCount >= renderer->availableUniformBufferCapacity)
|
||||||
|
@ -2483,7 +2509,6 @@ static uint8_t D3D11_INTERNAL_AcquireUniformBuffer(
|
||||||
SDL_UnlockMutex(renderer->uniformBufferLock);
|
SDL_UnlockMutex(renderer->uniformBufferLock);
|
||||||
|
|
||||||
/* Reset the uniform buffer */
|
/* Reset the uniform buffer */
|
||||||
uniformBuffer->hasDiscarded = 0;
|
|
||||||
uniformBuffer->offset = 0;
|
uniformBuffer->offset = 0;
|
||||||
uniformBuffer->drawOffset = 0;
|
uniformBuffer->drawOffset = 0;
|
||||||
|
|
||||||
|
@ -2511,31 +2536,18 @@ static void D3D11_INTERNAL_SetUniformBufferData(
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t dataLength
|
uint32_t dataLength
|
||||||
) {
|
) {
|
||||||
D3D11_MAPPED_SUBRESOURCE subres;
|
D3D11_BOX dstBox = { uniformBuffer->offset, 0, 0, uniformBuffer->offset + dataLength, 1, 1 };
|
||||||
|
|
||||||
HRESULT res = ID3D11DeviceContext_Map(
|
ID3D11DeviceContext1_UpdateSubresource1(
|
||||||
commandBuffer->context,
|
commandBuffer->context,
|
||||||
(ID3D11Resource*) uniformBuffer->d3d11Buffer->handle,
|
(ID3D11Resource*) uniformBuffer->d3d11Buffer.handle,
|
||||||
0,
|
0,
|
||||||
uniformBuffer->hasDiscarded ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD,
|
&dstBox,
|
||||||
0,
|
|
||||||
&subres
|
|
||||||
);
|
|
||||||
ERROR_CHECK_RETURN("Could not map buffer for writing!", );
|
|
||||||
|
|
||||||
SDL_memcpy(
|
|
||||||
(uint8_t*) subres.pData + uniformBuffer->offset,
|
|
||||||
data,
|
data,
|
||||||
dataLength
|
0,
|
||||||
|
0,
|
||||||
|
uniformBuffer->offset == 0 ? D3D11_COPY_DISCARD : D3D11_COPY_NO_OVERWRITE
|
||||||
);
|
);
|
||||||
|
|
||||||
ID3D11DeviceContext_Unmap(
|
|
||||||
commandBuffer->context,
|
|
||||||
(ID3D11Resource*) uniformBuffer->d3d11Buffer->handle,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
uniformBuffer->hasDiscarded = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_PushVertexShaderUniforms(
|
static void D3D11_PushVertexShaderUniforms(
|
||||||
|
@ -3274,11 +3286,8 @@ static void D3D11_BindGraphicsPipeline(
|
||||||
|
|
||||||
d3d11CommandBuffer->graphicsPipeline = pipeline;
|
d3d11CommandBuffer->graphicsPipeline = pipeline;
|
||||||
|
|
||||||
if (pipeline->vertexUniformBlockSize == 0)
|
/* Get a vertex uniform buffer if we need one */
|
||||||
{
|
if (d3d11CommandBuffer->vertexUniformBuffer == NULL && pipeline->vertexUniformBlockSize > 0)
|
||||||
d3d11CommandBuffer->vertexUniformBuffer = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
D3D11_INTERNAL_AcquireUniformBuffer(
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -3288,11 +3297,8 @@ static void D3D11_BindGraphicsPipeline(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipeline->fragmentUniformBlockSize == 0)
|
/* Get a fragment uniform buffer if we need one */
|
||||||
{
|
if (d3d11CommandBuffer->fragmentUniformBuffer == NULL && pipeline->fragmentUniformBlockSize > 0)
|
||||||
d3d11CommandBuffer->fragmentUniformBuffer = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
D3D11_INTERNAL_AcquireUniformBuffer(
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -3455,11 +3461,8 @@ static void D3D11_BindComputePipeline(
|
||||||
|
|
||||||
d3d11CommandBuffer->computePipeline = pipeline;
|
d3d11CommandBuffer->computePipeline = pipeline;
|
||||||
|
|
||||||
if (pipeline->computeUniformBlockSize == 0)
|
/* Get a compute uniform buffer if we need one */
|
||||||
{
|
if (d3d11CommandBuffer->computeUniformBuffer == NULL && pipeline->computeUniformBlockSize > 0)
|
||||||
d3d11CommandBuffer->computeUniformBuffer = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
D3D11_INTERNAL_AcquireUniformBuffer(
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -4692,7 +4695,7 @@ tryCreateDevice:
|
||||||
D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2);
|
D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2);
|
||||||
|
|
||||||
/* Create uniform buffer pool */
|
/* Create uniform buffer pool */
|
||||||
renderer->availableUniformBufferCapacity = 2;
|
renderer->availableUniformBufferCapacity = 16;
|
||||||
renderer->availableUniformBuffers = SDL_malloc(
|
renderer->availableUniformBuffers = SDL_malloc(
|
||||||
sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity
|
sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue