Fix repeated buffer writes by using USAGE_DEFAULT/UpdateSubresource instead of DYNAMIC/Map for non-uniform buffers

d3d11
Caleb Cornett 2024-02-09 11:04:32 -06:00 committed by cosmonaut
parent 557ce50737
commit c9b98c6e2b
1 changed files with 41 additions and 47 deletions

View File

@ -432,9 +432,8 @@ typedef struct D3D11ComputePipeline
typedef struct D3D11Buffer typedef struct D3D11Buffer
{ {
ID3D11Buffer *handle; ID3D11Buffer *handle;
ID3D11UnorderedAccessView* uav;
uint32_t size; uint32_t size;
uint8_t isDynamic;
ID3D11UnorderedAccessView *uav;
} D3D11Buffer; } D3D11Buffer;
typedef struct D3D11UniformBuffer typedef struct D3D11UniformBuffer
@ -1648,26 +1647,23 @@ static Refresh_Buffer* D3D11_CreateBuffer(
D3D11Buffer *d3d11Buffer; D3D11Buffer *d3d11Buffer;
HRESULT res; HRESULT res;
uint8_t isDynamic = 1; bufferDesc.BindFlags = 0;
uint32_t bindFlags = 0;
if (usageFlags & REFRESH_BUFFERUSAGE_VERTEX_BIT) if (usageFlags & REFRESH_BUFFERUSAGE_VERTEX_BIT)
{ {
bindFlags |= D3D11_BIND_VERTEX_BUFFER; bufferDesc.BindFlags |= D3D11_BIND_VERTEX_BUFFER;
} }
if (usageFlags & REFRESH_BUFFERUSAGE_INDEX_BIT) if (usageFlags & REFRESH_BUFFERUSAGE_INDEX_BIT)
{ {
bindFlags |= D3D11_BIND_INDEX_BUFFER; bufferDesc.BindFlags |= D3D11_BIND_INDEX_BUFFER;
} }
if ((usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT) || (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT)) if ((usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT) || (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT))
{ {
bindFlags |= D3D11_BIND_UNORDERED_ACCESS; bufferDesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
isDynamic = 0;
} }
bufferDesc.BindFlags = bindFlags;
bufferDesc.ByteWidth = sizeInBytes; bufferDesc.ByteWidth = sizeInBytes;
bufferDesc.Usage = isDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0; bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT) ? D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS : 0; bufferDesc.MiscFlags = (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT) ? D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS : 0;
bufferDesc.StructureByteStride = 0; bufferDesc.StructureByteStride = 0;
@ -1705,7 +1701,6 @@ static Refresh_Buffer* D3D11_CreateBuffer(
d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer)); d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
d3d11Buffer->handle = bufferHandle; d3d11Buffer->handle = bufferHandle;
d3d11Buffer->size = sizeInBytes; d3d11Buffer->size = sizeInBytes;
d3d11Buffer->isDynamic = isDynamic;
d3d11Buffer->uav = uav; d3d11Buffer->uav = uav;
return (Refresh_Buffer*) d3d11Buffer; return (Refresh_Buffer*) d3d11Buffer;
@ -1807,56 +1802,56 @@ static void D3D11_INTERNAL_SetBufferData(
uint32_t offsetInBytes, uint32_t offsetInBytes,
void* data, void* data,
uint32_t dataLength, uint32_t dataLength,
uint8_t noOverwrite uint8_t isUniformBuffer
) { ) {
D3D11_BOX dstBox; D3D11_BOX dstBox;
D3D11_MAPPED_SUBRESOURCE subres; D3D11_MAPPED_SUBRESOURCE subres;
HRESULT res; HRESULT res;
/* Use UpdateSubresource for non-dynamic buffers (i.e. compute/indirect) */ if (isUniformBuffer)
if (!buffer->isDynamic)
{ {
dstBox.left = 0; res = ID3D11DeviceContext_Map(
dstBox.right = dataLength; commandBuffer->context,
(ID3D11Resource*) buffer->handle,
0,
D3D11_MAP_WRITE_DISCARD, /* FIXME: Use NoOverwrite for subsequent writes! */
0,
&subres
);
ERROR_CHECK_RETURN("Could not map buffer for writing!", );
SDL_memcpy(
(uint8_t*) subres.pData + offsetInBytes,
data,
dataLength
);
ID3D11DeviceContext_Unmap(
commandBuffer->context,
(ID3D11Resource*) buffer->handle,
0
);
}
else
{
dstBox.left = offsetInBytes;
dstBox.right = offsetInBytes + dataLength;
dstBox.top = 0; dstBox.top = 0;
dstBox.bottom = 1; dstBox.bottom = 1;
dstBox.front = 0; dstBox.front = 0;
dstBox.back = 1; dstBox.back = 1;
ID3D11DeviceContext_UpdateSubresource( ID3D11DeviceContext1_UpdateSubresource1(
commandBuffer->context, commandBuffer->context,
(ID3D11Resource*) buffer->handle, (ID3D11Resource*) buffer->handle,
0, 0,
&dstBox, &dstBox,
data, data,
dataLength, dataLength,
1 1,
dataLength == buffer->size ? D3D11_COPY_DISCARD : 0
); );
return;
} }
res = ID3D11DeviceContext_Map(
commandBuffer->context,
(ID3D11Resource*) buffer->handle,
0,
noOverwrite ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD,
0,
&subres
);
ERROR_CHECK_RETURN("Could not map buffer for writing!", );
SDL_memcpy(
(uint8_t*) subres.pData + offsetInBytes,
data,
dataLength
);
ID3D11DeviceContext_Unmap(
commandBuffer->context,
(ID3D11Resource*) buffer->handle,
0
);
} }
static void D3D11_SetBufferData( static void D3D11_SetBufferData(
@ -1983,7 +1978,6 @@ static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
uniformBuffer->d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer)); uniformBuffer->d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
uniformBuffer->d3d11Buffer->handle = bufferHandle; uniformBuffer->d3d11Buffer->handle = bufferHandle;
uniformBuffer->d3d11Buffer->size = UBO_BUFFER_SIZE; uniformBuffer->d3d11Buffer->size = UBO_BUFFER_SIZE;
uniformBuffer->d3d11Buffer->isDynamic = 1;
uniformBuffer->d3d11Buffer->uav = NULL; uniformBuffer->d3d11Buffer->uav = NULL;
/* Add it to the available pool */ /* Add it to the available pool */
@ -2080,7 +2074,7 @@ static uint32_t D3D11_PushVertexShaderUniforms(
d3d11CommandBuffer->vertexUniformBuffer->offset, d3d11CommandBuffer->vertexUniformBuffer->offset,
data, data,
dataLengthInBytes, dataLengthInBytes,
0 /* FIXME: Should be NoOverwrite! */ 1
); );
d3d11CommandBuffer->vertexUniformBuffer->offset += graphicsPipeline->vertexUniformBlockSize; d3d11CommandBuffer->vertexUniformBuffer->offset += graphicsPipeline->vertexUniformBlockSize;
@ -2119,7 +2113,7 @@ static uint32_t D3D11_PushFragmentShaderUniforms(
d3d11CommandBuffer->fragmentUniformBuffer->offset, d3d11CommandBuffer->fragmentUniformBuffer->offset,
data, data,
dataLengthInBytes, dataLengthInBytes,
0 /* FIXME: Should be NoOverwrite! */ 1
); );
d3d11CommandBuffer->fragmentUniformBuffer->offset += graphicsPipeline->fragmentUniformBlockSize; d3d11CommandBuffer->fragmentUniformBuffer->offset += graphicsPipeline->fragmentUniformBlockSize;
@ -2158,7 +2152,7 @@ static uint32_t D3D11_PushComputeShaderUniforms(
d3d11CommandBuffer->computeUniformBuffer->offset, d3d11CommandBuffer->computeUniformBuffer->offset,
data, data,
dataLengthInBytes, dataLengthInBytes,
0 /* FIXME: Should be NoOverwrite! */ 1
); );
d3d11CommandBuffer->computeUniformBuffer->offset += (uint32_t) computePipeline->computeUniformBlockSize; /* FIXME: Is this cast safe? */ d3d11CommandBuffer->computeUniformBuffer->offset += (uint32_t) computePipeline->computeUniformBlockSize; /* FIXME: Is this cast safe? */