diff --git a/src/Refresh_Driver_D3D11.c b/src/Refresh_Driver_D3D11.c index b49903c..5d8c0d0 100644 --- a/src/Refresh_Driver_D3D11.c +++ b/src/Refresh_Driver_D3D11.c @@ -61,14 +61,6 @@ return ret; \ } -#define ERROR_CHECK_UNLOCK_RETURN(msg, ret) \ - if (FAILED(res)) \ - { \ - D3D11_INTERNAL_LogError(renderer->device, msg, res); \ - SDL_UnlockMutex(renderer->ctxLock); \ - return ret; \ - } - #define EXPAND_ELEMENTS_IF_NEEDED(arr, initialValue, type) \ if (arr->count == arr->capacity) \ { \ @@ -278,8 +270,10 @@ typedef struct D3D11Renderer IDXGIAdapter1* adapter; void *d3d11_dll; void *dxgi_dll; + SDL_mutex *immediateContextMutex; D3D11CommandBufferPool *commandBufferPool; + SDL_mutex *commandBufferAcquisitionMutex; D3D11SwapchainData** swapchainDatas; uint32_t swapchainDataCount; @@ -993,6 +987,9 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( uint32_t i; HRESULT res; + /* Make sure multiple threads can't acquire the same command buffer. */ + SDL_LockMutex(renderer->commandBufferAcquisitionMutex); + /* Try to use an existing command buffer, if one is available. */ for (i = 0; i < renderer->commandBufferPool->count; i += 1) { @@ -1025,7 +1022,11 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( 0, &renderer->commandBufferPool->elements[i]->context ); - ERROR_CHECK_RETURN("Could not create deferred context for command buffer", NULL); + if (FAILED(res)) + { + SDL_UnlockMutex(renderer->commandBufferAcquisitionMutex); + ERROR_CHECK_RETURN("Could not create deferred context for command buffer", NULL); + } /* Now we have a new command buffer we can use! */ commandBuffer = renderer->commandBufferPool->elements[i]; @@ -1039,6 +1040,8 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( commandBuffer->swapchainData = NULL; commandBuffer->commandList = NULL; + SDL_UnlockMutex(renderer->commandBufferAcquisitionMutex); + return (Refresh_CommandBuffer*) commandBuffer; } @@ -1144,12 +1147,13 @@ static void D3D11_Submit( } /* Submit the command list to the immediate context */ - /* FIXME: Mutex lock me! */ + SDL_LockMutex(renderer->immediateContextMutex); ID3D11DeviceContext_ExecuteCommandList( renderer->immediateContext, commandList, 0 ); + SDL_UnlockMutex(renderer->immediateContextMutex); /* Now that we're done, either save the command list or release it. */ if (commandBuffer->fixed) @@ -1315,6 +1319,10 @@ tryCreateDevice: ); SDL_memset(renderer->commandBufferPool, 0, sizeof(D3D11CommandBufferPool)); + /* Create mutexes */ + renderer->immediateContextMutex = SDL_CreateMutex(); + renderer->commandBufferAcquisitionMutex = SDL_CreateMutex(); + /* Initialize miscellaneous renderer members */ renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG) != 0; renderer->blendFactor.x = 1.0f;