Compare commits

...

2 Commits

1 changed files with 181 additions and 131 deletions

View File

@ -443,6 +443,11 @@ typedef struct D3D11UniformBuffer
uint32_t offset; uint32_t offset;
} D3D11UniformBuffer; } D3D11UniformBuffer;
typedef struct D3D11Fence
{
ID3D11Query *handle;
} D3D11Fence;
typedef struct D3D11CommandBuffer typedef struct D3D11CommandBuffer
{ {
/* D3D11 Object References */ /* D3D11 Object References */
@ -459,7 +464,7 @@ typedef struct D3D11CommandBuffer
/* State */ /* State */
SDL_threadID threadID; SDL_threadID threadID;
ID3D11Query *completionQuery; D3D11Fence *fence;
/* Uniforms */ /* Uniforms */
D3D11UniformBuffer *vertexUniformBuffer; D3D11UniformBuffer *vertexUniformBuffer;
@ -509,9 +514,14 @@ typedef struct D3D11Renderer
uint32_t availableUniformBufferCount; uint32_t availableUniformBufferCount;
uint32_t availableUniformBufferCapacity; uint32_t availableUniformBufferCapacity;
D3D11Fence **availableFences;
uint32_t availableFenceCount;
uint32_t availableFenceCapacity;
SDL_mutex *contextLock; SDL_mutex *contextLock;
SDL_mutex *acquireCommandBufferLock; SDL_mutex *acquireCommandBufferLock;
SDL_mutex *uniformBufferLock; SDL_mutex *uniformBufferLock;
SDL_mutex *acquireFenceLock;
} D3D11Renderer; } D3D11Renderer;
/* Logging */ /* Logging */
@ -572,7 +582,7 @@ static void D3D11_INTERNAL_LogError(
Refresh_LogError("%s! Error Code: %s (0x%08X)", msg, wszMsgBuff, res); Refresh_LogError("%s! Error Code: %s (0x%08X)", msg, wszMsgBuff, res);
} }
/* Subresources */ /* Helper Functions */
static inline uint32_t D3D11_INTERNAL_CalcSubresource( static inline uint32_t D3D11_INTERNAL_CalcSubresource(
uint32_t mipLevel, uint32_t mipLevel,
@ -582,6 +592,13 @@ static inline uint32_t D3D11_INTERNAL_CalcSubresource(
return mipLevel + (arraySlice * numLevels); return mipLevel + (arraySlice * numLevels);
} }
static inline uint32_t D3D11_INTERNAL_NextHighestAlignment(
uint32_t n,
uint32_t align
) {
return align * ((n + align - 1) / align);
}
/* Quit */ /* Quit */
static void D3D11_DestroyDevice( static void D3D11_DestroyDevice(
@ -606,7 +623,6 @@ static void D3D11_DestroyDevice(
for (uint32_t i = 0; i < renderer->availableCommandBufferCount; i += 1) for (uint32_t i = 0; i < renderer->availableCommandBufferCount; i += 1)
{ {
D3D11CommandBuffer *commandBuffer = renderer->availableCommandBuffers[i]; D3D11CommandBuffer *commandBuffer = renderer->availableCommandBuffers[i];
ID3D11Query_Release(commandBuffer->completionQuery);
ID3D11DeviceContext_Release(commandBuffer->context); ID3D11DeviceContext_Release(commandBuffer->context);
SDL_free(commandBuffer); SDL_free(commandBuffer);
} }
@ -623,10 +639,20 @@ static void D3D11_DestroyDevice(
} }
SDL_free(renderer->availableUniformBuffers); SDL_free(renderer->availableUniformBuffers);
/* Release fence infrastructure */
for (uint32_t i = 0; i < renderer->availableFenceCount; i += 1)
{
D3D11Fence *fence = renderer->availableFences[i];
ID3D11Query_Release(fence->handle);
SDL_free(fence);
}
SDL_free(renderer->availableFences);
/* Release the mutexes */ /* Release the mutexes */
SDL_DestroyMutex(renderer->acquireCommandBufferLock); SDL_DestroyMutex(renderer->acquireCommandBufferLock);
SDL_DestroyMutex(renderer->contextLock); SDL_DestroyMutex(renderer->contextLock);
SDL_DestroyMutex(renderer->uniformBufferLock); SDL_DestroyMutex(renderer->uniformBufferLock);
SDL_DestroyMutex(renderer->acquireFenceLock);
/* Release the device and associated objects */ /* Release the device and associated objects */
ID3D11DeviceContext_Release(renderer->immediateContext); ID3D11DeviceContext_Release(renderer->immediateContext);
@ -877,7 +903,6 @@ static ID3D11BlendState* D3D11_INTERNAL_FetchBlendState(
) { ) {
ID3D11BlendState *result; ID3D11BlendState *result;
D3D11_BLEND_DESC blendDesc; D3D11_BLEND_DESC blendDesc;
uint32_t i;
HRESULT res; HRESULT res;
/* Create a new blend state. /* Create a new blend state.
@ -888,7 +913,7 @@ static ID3D11BlendState* D3D11_INTERNAL_FetchBlendState(
blendDesc.AlphaToCoverageEnable = FALSE; blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = TRUE; blendDesc.IndependentBlendEnable = TRUE;
for (i = 0; i < numColorAttachments; i += 1) for (uint32_t i = 0; i < numColorAttachments; i += 1)
{ {
blendDesc.RenderTarget[i].BlendEnable = colorAttachments[i].blendState.blendEnable; blendDesc.RenderTarget[i].BlendEnable = colorAttachments[i].blendState.blendEnable;
blendDesc.RenderTarget[i].BlendOp = RefreshToD3D11_BlendOp[ blendDesc.RenderTarget[i].BlendOp = RefreshToD3D11_BlendOp[
@ -1009,8 +1034,7 @@ static uint32_t D3D11_INTERNAL_FindIndexOfVertexBinding(
const Refresh_VertexBinding *bindings, const Refresh_VertexBinding *bindings,
uint32_t numBindings uint32_t numBindings
) { ) {
uint32_t i; for (uint32_t i = 0; i < numBindings; i += 1)
for (i = 0; i < numBindings; i += 1)
{ {
if (bindings[i].binding == targetBinding) if (bindings[i].binding == targetBinding)
{ {
@ -1030,7 +1054,7 @@ static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout(
) { ) {
ID3D11InputLayout *result = NULL; ID3D11InputLayout *result = NULL;
D3D11_INPUT_ELEMENT_DESC *elementDescs; D3D11_INPUT_ELEMENT_DESC *elementDescs;
uint32_t i, bindingIndex; uint32_t bindingIndex;
HRESULT res; HRESULT res;
/* Don't bother creating/fetching an input layout if there are no attributes. */ /* Don't bother creating/fetching an input layout if there are no attributes. */
@ -1046,7 +1070,7 @@ static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout(
); );
/* Create the array of input elements */ /* Create the array of input elements */
for (i = 0; i < inputState.vertexAttributeCount; i += 1) for (uint32_t i = 0; i < inputState.vertexAttributeCount; i += 1)
{ {
elementDescs[i].AlignedByteOffset = inputState.vertexAttributes[i].offset; elementDescs[i].AlignedByteOffset = inputState.vertexAttributes[i].offset;
elementDescs[i].Format = RefreshToD3D11_VertexFormat[ elementDescs[i].Format = RefreshToD3D11_VertexFormat[
@ -1099,7 +1123,6 @@ static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ComputeShaderInfo *computeShaderInfo Refresh_ComputeShaderInfo *computeShaderInfo
) { ) {
D3D11Renderer* renderer = (D3D11Renderer*) driverData;
D3D11ComputePipeline* pipeline = (D3D11ComputePipeline*) SDL_malloc(sizeof(D3D11ComputePipeline)); D3D11ComputePipeline* pipeline = (D3D11ComputePipeline*) SDL_malloc(sizeof(D3D11ComputePipeline));
D3D11ShaderModule* shaderModule = (D3D11ShaderModule*) computeShaderInfo->shaderModule; D3D11ShaderModule* shaderModule = (D3D11ShaderModule*) computeShaderInfo->shaderModule;
@ -1111,13 +1134,6 @@ static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
return (Refresh_ComputePipeline*) pipeline; return (Refresh_ComputePipeline*) pipeline;
} }
static inline uint32_t D3D11_INTERNAL_NextHighestAlignment(
uint32_t n,
uint32_t align
) {
return align * ((n + align - 1) / align);
}
static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline( static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo
@ -1129,7 +1145,7 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
ID3D10Blob *errorBlob; ID3D10Blob *errorBlob;
HRESULT res; HRESULT res;
/* Color */ /* Blend */
pipeline->colorAttachmentBlendState = D3D11_INTERNAL_FetchBlendState( pipeline->colorAttachmentBlendState = D3D11_INTERNAL_FetchBlendState(
renderer, renderer,
@ -1150,9 +1166,11 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2]; pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2];
pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3]; pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3];
/* Multisample */
pipeline->multisampleState = pipelineCreateInfo->multisampleState; pipeline->multisampleState = pipelineCreateInfo->multisampleState;
/* Depth stencil */ /* Depth-Stencil */
pipeline->depthStencilState = D3D11_INTERNAL_FetchDepthStencilState( pipeline->depthStencilState = D3D11_INTERNAL_FetchDepthStencilState(
renderer, renderer,
@ -1173,7 +1191,7 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
pipelineCreateInfo->rasterizerState pipelineCreateInfo->rasterizerState
); );
/* Vertex shader */ /* Vertex Shader */
if (vertShaderModule->shader == NULL) if (vertShaderModule->shader == NULL)
{ {
@ -1325,6 +1343,7 @@ static Refresh_Sampler* D3D11_CreateSampler(
); );
ERROR_CHECK_RETURN("Could not create sampler state", NULL); ERROR_CHECK_RETURN("Could not create sampler state", NULL);
/* FIXME: Is there even a point to having a D3D11Sampler struct if it's just a wrapper? */
d3d11Sampler = (D3D11Sampler*) SDL_malloc(sizeof(D3D11Sampler)); d3d11Sampler = (D3D11Sampler*) SDL_malloc(sizeof(D3D11Sampler));
d3d11Sampler->handle = samplerStateHandle; d3d11Sampler->handle = samplerStateHandle;
@ -1659,7 +1678,7 @@ static Refresh_Buffer* D3D11_CreateBuffer(
return (Refresh_Buffer*) d3d11Buffer; return (Refresh_Buffer*) d3d11Buffer;
} }
/* Setters */ /* Texture Data */
static void D3D11_SetTextureData( static void D3D11_SetTextureData(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
@ -1746,6 +1765,8 @@ static void D3D11_CopyTextureToBuffer(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
/* Buffer Data */
static void D3D11_INTERNAL_SetBufferData( static void D3D11_INTERNAL_SetBufferData(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11CommandBuffer *commandBuffer, D3D11CommandBuffer *commandBuffer,
@ -1824,22 +1845,16 @@ static void D3D11_SetBufferData(
); );
} }
static void D3D11_INTERNAL_BindUniformBuffer( static void D3D11_GetBufferData(
D3D11CommandBuffer *commandBuffer, Refresh_Renderer *driverData,
D3D11UniformBuffer *uniformBuffer Refresh_Buffer *buffer,
void* data,
uint32_t dataLengthInBytes
) { ) {
if (commandBuffer->boundUniformBufferCount >= commandBuffer->boundUniformBufferCapacity) NOT_IMPLEMENTED
{
commandBuffer->boundUniformBufferCapacity *= 2;
commandBuffer->boundUniformBuffers = SDL_realloc(
commandBuffer->boundUniformBuffers,
sizeof(D3D11UniformBuffer*) * commandBuffer->boundUniformBufferCapacity
);
} }
commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer; /* Uniforms */
commandBuffer->boundUniformBufferCount += 1;
}
static uint8_t D3D11_INTERNAL_CreateUniformBuffer( static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
D3D11Renderer *renderer D3D11Renderer *renderer
@ -1869,6 +1884,8 @@ 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;
/* Add it to the available pool */ /* Add it to the available pool */
if (renderer->availableUniformBufferCount >= renderer->availableUniformBufferCapacity) if (renderer->availableUniformBufferCount >= renderer->availableUniformBufferCapacity)
@ -1887,12 +1904,15 @@ static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
return 1; return 1;
} }
static D3D11UniformBuffer* D3D11_INTERNAL_AcquireUniformBufferFromPool( static uint8_t D3D11_INTERNAL_AcquireUniformBuffer(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11CommandBuffer *commandBuffer,
D3D11UniformBuffer **uniformBufferToBind,
uint64_t blockSize uint64_t blockSize
) { ) {
D3D11UniformBuffer *uniformBuffer; D3D11UniformBuffer *uniformBuffer;
/* Acquire a uniform buffer from the pool */
SDL_LockMutex(renderer->uniformBufferLock); SDL_LockMutex(renderer->uniformBufferLock);
if (renderer->availableUniformBufferCount == 0) if (renderer->availableUniformBufferCount == 0)
@ -1901,7 +1921,7 @@ static D3D11UniformBuffer* D3D11_INTERNAL_AcquireUniformBufferFromPool(
{ {
SDL_UnlockMutex(renderer->uniformBufferLock); SDL_UnlockMutex(renderer->uniformBufferLock);
Refresh_LogError("Failed to create uniform buffer!"); Refresh_LogError("Failed to create uniform buffer!");
return NULL; return 0;
} }
} }
@ -1910,9 +1930,24 @@ static D3D11UniformBuffer* D3D11_INTERNAL_AcquireUniformBufferFromPool(
SDL_UnlockMutex(renderer->uniformBufferLock); SDL_UnlockMutex(renderer->uniformBufferLock);
/* Reset the uniform buffer */
uniformBuffer->offset = 0; uniformBuffer->offset = 0;
return uniformBuffer; /* Bind the uniform buffer to the command buffer */
if (commandBuffer->boundUniformBufferCount >= commandBuffer->boundUniformBufferCapacity)
{
commandBuffer->boundUniformBufferCapacity *= 2;
commandBuffer->boundUniformBuffers = SDL_realloc(
commandBuffer->boundUniformBuffers,
sizeof(D3D11UniformBuffer*) * commandBuffer->boundUniformBufferCapacity
);
}
commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer;
commandBuffer->boundUniformBufferCount += 1;
*uniformBufferToBind = uniformBuffer;
return 1;
} }
static uint32_t D3D11_PushVertexShaderUniforms( static uint32_t D3D11_PushVertexShaderUniforms(
@ -1928,13 +1963,11 @@ static uint32_t D3D11_PushVertexShaderUniforms(
if (d3d11CommandBuffer->vertexUniformBuffer->offset + graphicsPipeline->vertexUniformBlockSize >= UBO_BUFFER_SIZE) if (d3d11CommandBuffer->vertexUniformBuffer->offset + graphicsPipeline->vertexUniformBlockSize >= UBO_BUFFER_SIZE)
{ {
/* We're out of space in this buffer, bind the old one and acquire a new one */ /* Out of space! Get a new uniform buffer. */
D3D11_INTERNAL_BindUniformBuffer( D3D11_INTERNAL_AcquireUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->vertexUniformBuffer
);
d3d11CommandBuffer->vertexUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool(
renderer, renderer,
d3d11CommandBuffer,
&d3d11CommandBuffer->vertexUniformBuffer,
graphicsPipeline->vertexUniformBlockSize graphicsPipeline->vertexUniformBlockSize
); );
} }
@ -1969,13 +2002,11 @@ static uint32_t D3D11_PushFragmentShaderUniforms(
if (d3d11CommandBuffer->fragmentUniformBuffer->offset + graphicsPipeline->fragmentUniformBlockSize >= UBO_BUFFER_SIZE) if (d3d11CommandBuffer->fragmentUniformBuffer->offset + graphicsPipeline->fragmentUniformBlockSize >= UBO_BUFFER_SIZE)
{ {
/* We're out of space in this buffer, bind the old one and acquire a new one */ /* Out of space! Get a new uniform buffer. */
D3D11_INTERNAL_BindUniformBuffer( D3D11_INTERNAL_AcquireUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->fragmentUniformBuffer
);
d3d11CommandBuffer->fragmentUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool(
renderer, renderer,
d3d11CommandBuffer,
&d3d11CommandBuffer->fragmentUniformBuffer,
graphicsPipeline->fragmentUniformBlockSize graphicsPipeline->fragmentUniformBlockSize
); );
} }
@ -2007,6 +2038,8 @@ static uint32_t D3D11_PushComputeShaderUniforms(
return 0; return 0;
} }
/* Samplers */
static void D3D11_BindVertexSamplers( static void D3D11_BindVertexSamplers(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
@ -2075,17 +2108,6 @@ static void D3D11_BindFragmentSamplers(
); );
} }
/* Getters */
static void D3D11_GetBufferData(
Refresh_Renderer *driverData,
Refresh_Buffer *buffer,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
/* Disposal */ /* Disposal */
static void D3D11_QueueDestroyTexture( static void D3D11_QueueDestroyTexture(
@ -2193,7 +2215,6 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
uint32_t allocateCount uint32_t allocateCount
) { ) {
D3D11CommandBuffer *commandBuffer; D3D11CommandBuffer *commandBuffer;
D3D11_QUERY_DESC queryDesc;
HRESULT res; HRESULT res;
renderer->availableCommandBufferCapacity += allocateCount; renderer->availableCommandBufferCapacity += allocateCount;
@ -2215,16 +2236,6 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
); );
ERROR_CHECK("Could not create deferred context"); ERROR_CHECK("Could not create deferred context");
/* Fence Query */
queryDesc.Query = D3D11_QUERY_EVENT;
queryDesc.MiscFlags = 0;
res = ID3D11Device_CreateQuery(
renderer->device,
&queryDesc,
&commandBuffer->completionQuery
);
ERROR_CHECK("Could not create query");
/* Bound Uniform Buffers */ /* Bound Uniform Buffers */
commandBuffer->boundUniformBufferCapacity = 16; commandBuffer->boundUniformBufferCapacity = 16;
commandBuffer->boundUniformBufferCount = 0; commandBuffer->boundUniformBufferCount = 0;
@ -2232,8 +2243,6 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
commandBuffer->boundUniformBufferCapacity * sizeof(D3D11UniformBuffer*) commandBuffer->boundUniformBufferCapacity * sizeof(D3D11UniformBuffer*)
); );
/* FIXME: Resource tracking? */
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer; renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
renderer->availableCommandBufferCount += 1; renderer->availableCommandBufferCount += 1;
} }
@ -2258,17 +2267,69 @@ static D3D11CommandBuffer* D3D11_INTERNAL_GetInactiveCommandBufferFromPool(
return commandBuffer; return commandBuffer;
} }
static void D3D11_INTERNAL_AllocateFences(
D3D11Renderer *renderer,
uint32_t allocateCount
) {
D3D11Fence *fence;
D3D11_QUERY_DESC queryDesc;
HRESULT res;
renderer->availableFenceCapacity += allocateCount;
renderer->availableFences = SDL_realloc(
renderer->availableFences,
sizeof(D3D11Fence*) * renderer->availableFenceCapacity
);
for (uint32_t i = 0; i < allocateCount; i += 1)
{
fence = SDL_malloc(sizeof(D3D11Fence));
queryDesc.Query = D3D11_QUERY_EVENT;
queryDesc.MiscFlags = 0;
res = ID3D11Device_CreateQuery(
renderer->device,
&queryDesc,
&fence->handle
);
ERROR_CHECK("Could not create query"); /* FIXME: Should this return an error code? */
renderer->availableFences[renderer->availableFenceCount] = fence;
renderer->availableFenceCount += 1;
}
}
static D3D11Fence* D3D11_INTERNAL_GetFenceFromPool(
D3D11Renderer* renderer
) {
D3D11Fence *fence;
SDL_LockMutex(renderer->acquireFenceLock);
if (renderer->availableFenceCount == 0)
{
D3D11_INTERNAL_AllocateFences(renderer, renderer->availableFenceCapacity);
}
fence = renderer->availableFences[renderer->availableFenceCount - 1];
renderer->availableFenceCount -= 1;
SDL_UnlockMutex(renderer->acquireFenceLock);
return fence;
}
static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
Refresh_Renderer *driverData Refresh_Renderer *driverData
) { ) {
D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *commandBuffer; D3D11CommandBuffer *commandBuffer;
uint32_t i;
SDL_LockMutex(renderer->acquireCommandBufferLock); SDL_LockMutex(renderer->acquireCommandBufferLock);
/* Set up the command buffer */
commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer); commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer);
commandBuffer->threadID = SDL_ThreadID(); commandBuffer->threadID = SDL_ThreadID();
commandBuffer->swapchainData = NULL; commandBuffer->swapchainData = NULL;
commandBuffer->graphicsPipeline = NULL; commandBuffer->graphicsPipeline = NULL;
@ -2277,11 +2338,16 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
commandBuffer->fragmentUniformBuffer = NULL; commandBuffer->fragmentUniformBuffer = NULL;
commandBuffer->computeUniformBuffer = NULL; commandBuffer->computeUniformBuffer = NULL;
commandBuffer->dsView = NULL; commandBuffer->dsView = NULL;
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
for (uint32_t i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{ {
commandBuffer->rtViews[i] = NULL; commandBuffer->rtViews[i] = NULL;
} }
SDL_LockMutex(renderer->acquireFenceLock);
commandBuffer->fence = D3D11_INTERNAL_GetFenceFromPool(renderer);
SDL_UnlockMutex(renderer->acquireFenceLock);
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
return (Refresh_CommandBuffer*) commandBuffer; return (Refresh_CommandBuffer*) commandBuffer;
@ -2300,7 +2366,6 @@ static void D3D11_BeginRenderPass(
D3D11_CLEAR_FLAG dsClearFlags; D3D11_CLEAR_FLAG dsClearFlags;
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
D3D11_RECT scissorRect; D3D11_RECT scissorRect;
uint32_t i;
/* FIXME: /* FIXME:
* We need to unbind the RT textures on the Refresh side * We need to unbind the RT textures on the Refresh side
@ -2308,14 +2373,14 @@ static void D3D11_BeginRenderPass(
*/ */
/* Clear the bound RTs for the current command buffer */ /* Clear the bound RTs for the current command buffer */
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) for (uint32_t i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{ {
d3d11CommandBuffer->rtViews[i] = NULL; d3d11CommandBuffer->rtViews[i] = NULL;
} }
d3d11CommandBuffer->dsView = NULL; d3d11CommandBuffer->dsView = NULL;
/* Get RTVs for the color attachments */ /* Get RTVs for the color attachments */
for (i = 0; i < colorAttachmentCount; i += 1) for (uint32_t i = 0; i < colorAttachmentCount; i += 1)
{ {
/* FIXME: Cube RTs */ /* FIXME: Cube RTs */
@ -2337,7 +2402,7 @@ static void D3D11_BeginRenderPass(
); );
/* Perform load ops on the RTs */ /* Perform load ops on the RTs */
for (i = 0; i < colorAttachmentCount; i += 1) for (uint32_t i = 0; i < colorAttachmentCount; i += 1)
{ {
if (colorAttachmentInfos[i].loadOp == REFRESH_LOADOP_CLEAR) if (colorAttachmentInfos[i].loadOp == REFRESH_LOADOP_CLEAR)
{ {
@ -2410,23 +2475,9 @@ static void D3D11_EndRenderPass(
) { ) {
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer; D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->vertexUniformBuffer
);
}
d3d11CommandBuffer->vertexUniformBuffer = NULL; d3d11CommandBuffer->vertexUniformBuffer = NULL;
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->fragmentUniformBuffer
);
}
d3d11CommandBuffer->fragmentUniformBuffer = NULL; d3d11CommandBuffer->fragmentUniformBuffer = NULL;
d3d11CommandBuffer->computeUniformBuffer = NULL;
/* FIXME: Resolve MSAA here! */ /* FIXME: Resolve MSAA here! */
/* FIXME: Anything else we need to do...? */ /* FIXME: Anything else we need to do...? */
@ -2443,31 +2494,17 @@ static void D3D11_BindGraphicsPipeline(
d3d11CommandBuffer->graphicsPipeline = pipeline; d3d11CommandBuffer->graphicsPipeline = pipeline;
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->vertexUniformBuffer
);
}
if (pipeline->vertexUniformBlockSize == 0) if (pipeline->vertexUniformBlockSize == 0)
{ {
d3d11CommandBuffer->vertexUniformBuffer = NULL; d3d11CommandBuffer->vertexUniformBuffer = NULL;
} }
else else
{ {
d3d11CommandBuffer->vertexUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool( D3D11_INTERNAL_AcquireUniformBuffer(
renderer, renderer,
pipeline->vertexUniformBlockSize
);
}
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer, d3d11CommandBuffer,
d3d11CommandBuffer->fragmentUniformBuffer &d3d11CommandBuffer->vertexUniformBuffer,
pipeline->vertexUniformBlockSize
); );
} }
@ -2477,8 +2514,10 @@ static void D3D11_BindGraphicsPipeline(
} }
else else
{ {
d3d11CommandBuffer->fragmentUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool( D3D11_INTERNAL_AcquireUniformBuffer(
renderer, renderer,
d3d11CommandBuffer,
&d3d11CommandBuffer->fragmentUniformBuffer,
pipeline->fragmentUniformBlockSize pipeline->fragmentUniformBlockSize
); );
} }
@ -2629,22 +2668,16 @@ static void D3D11_BindComputePipeline(
d3d11CommandBuffer->computePipeline = pipeline; d3d11CommandBuffer->computePipeline = pipeline;
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->computeUniformBuffer
);
}
if (pipeline->computeUniformBlockSize == 0) if (pipeline->computeUniformBlockSize == 0)
{ {
d3d11CommandBuffer->computeUniformBuffer = NULL; d3d11CommandBuffer->computeUniformBuffer = NULL;
} }
else else
{ {
d3d11CommandBuffer->computeUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool( D3D11_INTERNAL_AcquireUniformBuffer(
renderer, renderer,
d3d11CommandBuffer,
&d3d11CommandBuffer->computeUniformBuffer,
pipeline->computeUniformBlockSize pipeline->computeUniformBlockSize
); );
} }
@ -2985,7 +3018,6 @@ static void D3D11_UnclaimWindow(
) { ) {
D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle); D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
uint32_t i;
if (windowData == NULL) if (windowData == NULL)
{ {
@ -3001,7 +3033,7 @@ static void D3D11_UnclaimWindow(
); );
} }
for (i = 0; i < renderer->claimedWindowCount; i += 1) for (uint32_t i = 0; i < renderer->claimedWindowCount; i += 1)
{ {
if (renderer->claimedWindows[i]->windowHandle == windowHandle) if (renderer->claimedWindows[i]->windowHandle == windowHandle)
{ {
@ -3111,6 +3143,22 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
commandBuffer->boundUniformBufferCount = 0; commandBuffer->boundUniformBufferCount = 0;
/* The fence is now available */
/* FIXME: Not if auto-release is false! */
SDL_LockMutex(renderer->acquireFenceLock);
if (renderer->availableFenceCount == renderer->availableFenceCapacity)
{
renderer->availableFenceCapacity *= 2;
renderer->availableFences = SDL_realloc(
renderer->availableFences,
renderer->availableFenceCapacity * sizeof(D3D11Fence*)
);
}
renderer->availableFences[renderer->availableFenceCount] = commandBuffer->fence;
renderer->availableFenceCount += 1;
SDL_UnlockMutex(renderer->acquireFenceLock);
/* Return command buffer to pool */ /* Return command buffer to pool */
SDL_LockMutex(renderer->acquireCommandBufferLock); SDL_LockMutex(renderer->acquireCommandBufferLock);
@ -3155,7 +3203,7 @@ static void D3D11_Submit(
/* Notify the command buffer completion query that we have completed recording */ /* Notify the command buffer completion query that we have completed recording */
ID3D11DeviceContext_End( ID3D11DeviceContext_End(
renderer->immediateContext, renderer->immediateContext,
(ID3D11Asynchronous*) d3d11CommandBuffer->completionQuery (ID3D11Asynchronous*) d3d11CommandBuffer->fence->handle
); );
/* Serialize the commands into the command list */ /* Serialize the commands into the command list */
@ -3205,7 +3253,7 @@ static void D3D11_Submit(
res = ID3D11DeviceContext_GetData( res = ID3D11DeviceContext_GetData(
renderer->immediateContext, renderer->immediateContext,
(ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->completionQuery, (ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->fence->handle,
&queryData, &queryData,
sizeof(queryData), sizeof(queryData),
0 0
@ -3245,7 +3293,7 @@ static void D3D11_Wait(
{ {
while (S_OK != ID3D11DeviceContext_GetData( while (S_OK != ID3D11DeviceContext_GetData(
renderer->immediateContext, renderer->immediateContext,
(ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->completionQuery, (ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->fence->handle,
&queryData, &queryData,
sizeof(queryData), sizeof(queryData),
0 0
@ -3262,8 +3310,6 @@ static void D3D11_Wait(
D3D11_INTERNAL_CleanCommandBuffer(renderer, commandBuffer); D3D11_INTERNAL_CleanCommandBuffer(renderer, commandBuffer);
} }
/* FIXME: D3D11_INTERNAL_PerformPendingDestroys(renderer); */
SDL_UnlockMutex(renderer->contextLock); SDL_UnlockMutex(renderer->contextLock);
} }
@ -3615,17 +3661,21 @@ tryCreateDevice:
renderer->contextLock = SDL_CreateMutex(); renderer->contextLock = SDL_CreateMutex();
renderer->acquireCommandBufferLock = SDL_CreateMutex(); renderer->acquireCommandBufferLock = SDL_CreateMutex();
renderer->uniformBufferLock = SDL_CreateMutex(); renderer->uniformBufferLock = SDL_CreateMutex();
renderer->acquireFenceLock = SDL_CreateMutex();
/* Initialize miscellaneous renderer members */ /* Initialize miscellaneous renderer members */
renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG); renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG);
/* Create command buffers to initialize the pool */ /* Create command buffer pool */
D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2); D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2);
/* Create uniform buffer pool */ /* Create uniform buffer pool */
renderer->availableUniformBufferCapacity = 2; renderer->availableUniformBufferCapacity = 2;
renderer->availableUniformBuffers = SDL_malloc(sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity); renderer->availableUniformBuffers = SDL_malloc(sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity);
/* Create fence pool */
D3D11_INTERNAL_AllocateFences(renderer, 2);
/* Create the Refresh Device */ /* Create the Refresh Device */
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device)); result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));
ASSIGN_DRIVER(D3D11) ASSIGN_DRIVER(D3D11)