Combine swapchain and window data structs + actually allocate claimedWindows...

d3d11
Caleb Cornett 2024-02-10 22:18:25 -06:00 committed by cosmonaut
parent 4fe02e8571
commit 0a520f7a66
1 changed files with 59 additions and 91 deletions

View File

@ -385,18 +385,12 @@ typedef struct D3D11Texture
uint8_t isRenderTarget; uint8_t isRenderTarget;
} D3D11Texture; } D3D11Texture;
typedef struct D3D11SwapchainData
{
IDXGISwapChain *swapchain;
D3D11Texture texture;
Refresh_PresentMode presentMode;
} D3D11SwapchainData;
/* FIXME: Why do we have WindowData separate from SwapchainData? */
typedef struct D3D11WindowData typedef struct D3D11WindowData
{ {
void* windowHandle; void* windowHandle;
D3D11SwapchainData *swapchainData; IDXGISwapChain *swapchain;
D3D11Texture texture;
Refresh_PresentMode presentMode;
} D3D11WindowData; } D3D11WindowData;
typedef struct D3D11ShaderModule typedef struct D3D11ShaderModule
@ -472,9 +466,11 @@ static const D3D11TargetBinding NullTargetBinding = { NULL, 0 };
typedef struct D3D11CommandBuffer typedef struct D3D11CommandBuffer
{ {
/* D3D11 Object References */ /* Deferred Context */
ID3D11DeviceContext1 *context; ID3D11DeviceContext1 *context;
D3D11SwapchainData *swapchainData;
/* Window */
D3D11WindowData *windowData;
/* Render Pass */ /* Render Pass */
D3D11TargetBinding colorTargets[MAX_COLOR_TARGET_BINDINGS]; D3D11TargetBinding colorTargets[MAX_COLOR_TARGET_BINDINGS];
@ -546,6 +542,7 @@ typedef struct D3D11Renderer
SDL_mutex *acquireCommandBufferLock; SDL_mutex *acquireCommandBufferLock;
SDL_mutex *uniformBufferLock; SDL_mutex *uniformBufferLock;
SDL_mutex *fenceLock; SDL_mutex *fenceLock;
SDL_mutex *windowLock;
} D3D11Renderer; } D3D11Renderer;
/* Logging */ /* Logging */
@ -677,9 +674,6 @@ static void D3D11_DestroyDevice(
} }
SDL_free(renderer->claimedWindows); SDL_free(renderer->claimedWindows);
/* FIXME: Copied this from Vulkan, is it actually necessary? */
D3D11_Wait(device->driverData);
/* Release command buffer infrastructure */ /* Release command buffer infrastructure */
for (uint32_t i = 0; i < renderer->availableCommandBufferCount; i += 1) for (uint32_t i = 0; i < renderer->availableCommandBufferCount; i += 1)
{ {
@ -715,6 +709,7 @@ static void D3D11_DestroyDevice(
SDL_DestroyMutex(renderer->contextLock); SDL_DestroyMutex(renderer->contextLock);
SDL_DestroyMutex(renderer->uniformBufferLock); SDL_DestroyMutex(renderer->uniformBufferLock);
SDL_DestroyMutex(renderer->fenceLock); SDL_DestroyMutex(renderer->fenceLock);
SDL_DestroyMutex(renderer->windowLock);
/* Release the device and associated objects */ /* Release the device and associated objects */
ID3D11DeviceContext_Release(renderer->immediateContext); ID3D11DeviceContext_Release(renderer->immediateContext);
@ -2606,7 +2601,7 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
SDL_LockMutex(renderer->acquireCommandBufferLock); SDL_LockMutex(renderer->acquireCommandBufferLock);
commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer); commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer);
commandBuffer->swapchainData = NULL; commandBuffer->windowData = NULL;
commandBuffer->graphicsPipeline = NULL; commandBuffer->graphicsPipeline = NULL;
commandBuffer->computePipeline = NULL; commandBuffer->computePipeline = NULL;
commandBuffer->vertexUniformBuffer = NULL; commandBuffer->vertexUniformBuffer = NULL;
@ -2951,7 +2946,7 @@ static void D3D11_EndRenderPass(
if (texture != NULL && texture->msaaHandle != NULL) if (texture != NULL && texture->msaaHandle != NULL)
{ {
uint32_t subresource = D3D11_INTERNAL_CalcSubresource( uint32_t subresource = D3D11_INTERNAL_CalcSubresource(
0, /* FIXME: Is this right? */ 0, /* FIXME: This should probably the color target's mip level */
d3d11CommandBuffer->colorTargets[i].layer, d3d11CommandBuffer->colorTargets[i].layer,
texture->levelCount texture->levelCount
); );
@ -3308,7 +3303,6 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
DXGI_SWAP_CHAIN_DESC swapchainDesc; DXGI_SWAP_CHAIN_DESC swapchainDesc;
IDXGIFactory1 *pParent; IDXGIFactory1 *pParent;
IDXGISwapChain *swapchain; IDXGISwapChain *swapchain;
D3D11SwapchainData *swapchainData;
HRESULT res; HRESULT res;
/* Get the DXGI handle */ /* Get the DXGI handle */
@ -3400,40 +3394,35 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
IDXGIFactory1_Release(pParent); IDXGIFactory1_Release(pParent);
} }
/* Create the swapchain data */ /* Initialize the swapchain data */
swapchainData = (D3D11SwapchainData*) SDL_malloc(sizeof(D3D11SwapchainData)); windowData->swapchain = swapchain;
swapchainData->swapchain = swapchain; windowData->presentMode = presentMode;
swapchainData->presentMode = presentMode;
if (!D3D11_INTERNAL_InitializeSwapchainTexture( if (!D3D11_INTERNAL_InitializeSwapchainTexture(
renderer, renderer,
swapchain, swapchain,
&swapchainData->texture &windowData->texture
)) { )) {
SDL_free(swapchainData);
IDXGISwapChain_Release(swapchain); IDXGISwapChain_Release(swapchain);
return 0; return 0;
} }
windowData->swapchainData = swapchainData;
return 1; return 1;
} }
static uint8_t D3D11_INTERNAL_ResizeSwapchain( static uint8_t D3D11_INTERNAL_ResizeSwapchain(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11SwapchainData *swapchainData, D3D11WindowData *windowData,
int32_t width, int32_t width,
int32_t height int32_t height
) { ) {
HRESULT res;
/* Release the old RTV */ /* Release the old RTV */
ID3D11RenderTargetView_Release(swapchainData->texture.targetViews[0].view); ID3D11RenderTargetView_Release(windowData->texture.targetViews[0].view);
SDL_free(swapchainData->texture.targetViews); SDL_free(windowData->texture.targetViews);
/* Resize the swapchain */ /* Resize the swapchain */
res = IDXGISwapChain_ResizeBuffers( HRESULT res = IDXGISwapChain_ResizeBuffers(
swapchainData->swapchain, windowData->swapchain,
0, /* Keep buffer count the same */ 0, /* Keep buffer count the same */
width, width,
height, height,
@ -3445,38 +3434,11 @@ static uint8_t D3D11_INTERNAL_ResizeSwapchain(
/* Create the Refresh-side texture for the swapchain */ /* Create the Refresh-side texture for the swapchain */
return D3D11_INTERNAL_InitializeSwapchainTexture( return D3D11_INTERNAL_InitializeSwapchainTexture(
renderer, renderer,
swapchainData->swapchain, windowData->swapchain,
&swapchainData->texture &windowData->texture
); );
} }
static void D3D11_INTERNAL_DestroySwapchain(
D3D11Renderer *renderer,
D3D11WindowData *windowData
) {
D3D11SwapchainData *swapchainData;
if (windowData == NULL)
{
return;
}
swapchainData = windowData->swapchainData;
if (swapchainData == NULL)
{
return;
}
ID3D11RenderTargetView_Release(swapchainData->texture.targetViews[0].view);
SDL_free(swapchainData->texture.targetViews);
IDXGISwapChain_Release(swapchainData->swapchain);
windowData->swapchainData = NULL;
SDL_free(swapchainData);
}
static uint8_t D3D11_ClaimWindow( static uint8_t D3D11_ClaimWindow(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
void *windowHandle, void *windowHandle,
@ -3494,6 +3456,8 @@ static uint8_t D3D11_ClaimWindow(
{ {
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, windowData); SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, windowData);
SDL_LockMutex(renderer->windowLock);
if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity)
{ {
renderer->claimedWindowCapacity *= 2; renderer->claimedWindowCapacity *= 2;
@ -3502,10 +3466,11 @@ static uint8_t D3D11_ClaimWindow(
renderer->claimedWindowCapacity * sizeof(D3D11WindowData*) renderer->claimedWindowCapacity * sizeof(D3D11WindowData*)
); );
} }
renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindows[renderer->claimedWindowCount] = windowData;
renderer->claimedWindowCount += 1; renderer->claimedWindowCount += 1;
SDL_UnlockMutex(renderer->windowLock);
return 1; return 1;
} }
else else
@ -3534,15 +3499,13 @@ static void D3D11_UnclaimWindow(
return; return;
} }
if (windowData->swapchainData != NULL) D3D11_Wait(driverData);
{
D3D11_Wait(driverData);
D3D11_INTERNAL_DestroySwapchain(
(D3D11Renderer*) driverData,
windowData
);
}
ID3D11RenderTargetView_Release(windowData->texture.targetViews[0].view);
SDL_free(windowData->texture.targetViews);
IDXGISwapChain_Release(windowData->swapchain);
SDL_LockMutex(renderer->windowLock);
for (uint32_t 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)
@ -3552,6 +3515,7 @@ static void D3D11_UnclaimWindow(
break; break;
} }
} }
SDL_UnlockMutex(renderer->windowLock);
SDL_free(windowData); SDL_free(windowData);
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, NULL); SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, NULL);
@ -3567,7 +3531,6 @@ static Refresh_Texture* D3D11_AcquireSwapchainTexture(
D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer; D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
D3D11WindowData *windowData; D3D11WindowData *windowData;
D3D11SwapchainData *swapchainData;
DXGI_SWAP_CHAIN_DESC swapchainDesc; DXGI_SWAP_CHAIN_DESC swapchainDesc;
int w, h; int w, h;
HRESULT res; HRESULT res;
@ -3578,21 +3541,15 @@ static Refresh_Texture* D3D11_AcquireSwapchainTexture(
return NULL; return NULL;
} }
swapchainData = windowData->swapchainData;
if (swapchainData == NULL)
{
return NULL;
}
/* Check for window size changes and resize the swapchain if needed. */ /* Check for window size changes and resize the swapchain if needed. */
IDXGISwapChain_GetDesc(swapchainData->swapchain, &swapchainDesc); IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
SDL_GetWindowSize((SDL_Window*) windowHandle, &w, &h); SDL_GetWindowSize((SDL_Window*) windowHandle, &w, &h);
if (w != swapchainDesc.BufferDesc.Width || h != swapchainDesc.BufferDesc.Height) if (w != swapchainDesc.BufferDesc.Width || h != swapchainDesc.BufferDesc.Height)
{ {
res = D3D11_INTERNAL_ResizeSwapchain( res = D3D11_INTERNAL_ResizeSwapchain(
renderer, renderer,
swapchainData, windowData,
w, w,
h h
); );
@ -3600,14 +3557,14 @@ static Refresh_Texture* D3D11_AcquireSwapchainTexture(
} }
/* Let the command buffer know it's associated with this swapchain. */ /* Let the command buffer know it's associated with this swapchain. */
d3d11CommandBuffer->swapchainData = swapchainData; d3d11CommandBuffer->windowData = windowData;
/* Send the dimensions to the out parameters. */ /* Send the dimensions to the out parameters. */
*pWidth = swapchainData->texture.width; *pWidth = windowData->texture.width;
*pHeight = swapchainData->texture.height; *pHeight = windowData->texture.height;
/* Return the swapchain texture */ /* Return the swapchain texture */
return (Refresh_Texture*) &swapchainData->texture; return (Refresh_Texture*) &windowData->texture;
} }
static Refresh_TextureFormat D3D11_GetSwapchainFormat( static Refresh_TextureFormat D3D11_GetSwapchainFormat(
@ -3623,8 +3580,7 @@ static void D3D11_SetSwapchainPresentMode(
Refresh_PresentMode presentMode Refresh_PresentMode presentMode
) { ) {
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle); D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
D3D11SwapchainData *swapchainData = windowData->swapchainData; windowData->presentMode = presentMode;
swapchainData->presentMode = presentMode;
} }
/* Submission and Fences */ /* Submission and Fences */
@ -3776,25 +3732,26 @@ static void D3D11_Submit(
renderer->submittedCommandBufferCount += 1; renderer->submittedCommandBufferCount += 1;
/* Present, if applicable */ /* Present, if applicable */
if (d3d11CommandBuffer->swapchainData) if (d3d11CommandBuffer->windowData)
{ {
/* FIXME: Is there some way to emulate FIFO_RELAXED? */ /* FIXME: Is there some way to emulate FIFO_RELAXED? */
uint32_t syncInterval = 1; uint32_t syncInterval = 1;
if ( d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE || if ( d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE ||
(renderer->supportsFlipDiscard && d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_MAILBOX) (renderer->supportsFlipDiscard && d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_MAILBOX)
) { ) {
syncInterval = 0; syncInterval = 0;
} }
uint32_t presentFlags = 0; uint32_t presentFlags = 0;
if (renderer->supportsTearing && d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE) if ( renderer->supportsTearing &&
d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE )
{ {
presentFlags = DXGI_PRESENT_ALLOW_TEARING; presentFlags = DXGI_PRESENT_ALLOW_TEARING;
} }
IDXGISwapChain_Present( IDXGISwapChain_Present(
d3d11CommandBuffer->swapchainData->swapchain, d3d11CommandBuffer->windowData->swapchain,
syncInterval, syncInterval,
presentFlags presentFlags
); );
@ -4306,6 +4263,7 @@ tryCreateDevice:
renderer->acquireCommandBufferLock = SDL_CreateMutex(); renderer->acquireCommandBufferLock = SDL_CreateMutex();
renderer->uniformBufferLock = SDL_CreateMutex(); renderer->uniformBufferLock = SDL_CreateMutex();
renderer->fenceLock = SDL_CreateMutex(); renderer->fenceLock = SDL_CreateMutex();
renderer->windowLock = SDL_CreateMutex();
/* Initialize miscellaneous renderer members */ /* Initialize miscellaneous renderer members */
renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG); renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG);
@ -4315,11 +4273,21 @@ tryCreateDevice:
/* 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 */ /* Create fence pool */
renderer->availableFenceCapacity = 2; renderer->availableFenceCapacity = 2;
renderer->availableFences = SDL_malloc(sizeof(D3D11Fence*) * renderer->availableFenceCapacity); renderer->availableFences = SDL_malloc(
sizeof(D3D11Fence*) * renderer->availableFenceCapacity
);
/* Create claimed window list */
renderer->claimedWindowCapacity = 1;
renderer->claimedWindows = SDL_malloc(
sizeof(D3D11WindowData*) * renderer->claimedWindowCapacity
);
/* Create the Refresh Device */ /* Create the Refresh Device */
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device)); result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));