Implemented Clear, fleshed out D3D11Texture, added depth-stencil clear support in BeginRenderPass

Caleb Cornett 2022-03-10 00:30:28 -05:00
parent 5ebbd8ac63
commit 3b0774579f
1 changed files with 202 additions and 64 deletions

View File

@ -235,7 +235,39 @@ static D3D11_TEXTURE_ADDRESS_MODE RefreshToD3D11_SamplerAddressMode[] =
typedef struct D3D11Texture typedef struct D3D11Texture
{ {
ID3D11RenderTargetView *rtv; /* D3D Handles */
ID3D11Resource *handle; /* ID3D11Texture2D* or ID3D11Texture3D* */
ID3D11ShaderResourceView *shaderView;
/* Basic Info */
int32_t levelCount;
uint8_t isRenderTarget;
/* Dimensions */
#define REFRESH_D3D11_RENDERTARGET_2D 0
#define REFRESH_D3D11_RENDERTARGET_3D 1
#define REFRESH_D3D11_RENDERTARGET_CUBE 2
uint8_t rtType;
REFRESHNAMELESS union
{
struct
{
int32_t width;
int32_t height;
ID3D11View *targetView; /* ID3D11RenderTargetView* or ID3D11DepthStencilView* */
} twod;
struct
{
int32_t width;
int32_t height;
int32_t depth;
} threed;
struct
{
int32_t size;
ID3D11RenderTargetView **rtViews;
} cube;
};
} D3D11Texture; } D3D11Texture;
typedef struct D3D11SwapchainData typedef struct D3D11SwapchainData
@ -247,9 +279,17 @@ typedef struct D3D11SwapchainData
typedef struct D3D11CommandBuffer typedef struct D3D11CommandBuffer
{ {
/* D3D11 Object References */
ID3D11DeviceContext *context; ID3D11DeviceContext *context;
ID3D11CommandList *commandList; ID3D11CommandList *commandList;
D3D11SwapchainData *swapchainData; D3D11SwapchainData *swapchainData;
/* Render Pass */
uint8_t numBoundColorAttachments;
ID3D11RenderTargetView *rtViews[MAX_COLOR_TARGET_BINDINGS];
ID3D11DepthStencilView* dsView;
/* State */
SDL_threadID threadID; SDL_threadID threadID;
uint8_t recording; uint8_t recording;
uint8_t fixed; uint8_t fixed;
@ -349,6 +389,57 @@ static void D3D11_INTERNAL_LogError(
/* Swapchain Management */ /* Swapchain Management */
static uint8_t D3D11_INTERNAL_InitializeSwapchainTexture(
D3D11Renderer *renderer,
D3D11Texture *resultTexture,
IDXGISwapChain *swapchain
) {
ID3D11Texture2D *swapchainTexture;
D3D11_RENDER_TARGET_VIEW_DESC swapchainViewDesc;
D3D11_TEXTURE2D_DESC textureDesc;
HRESULT res;
/* Clear all the texture data. */
SDL_memset(resultTexture, 0, sizeof(D3D11Texture));
/* Grab the buffer from the swapchain */
res = IDXGISwapChain_GetBuffer(
swapchain,
0,
&D3D_IID_ID3D11Texture2D,
(void**) &swapchainTexture
);
ERROR_CHECK_RETURN("Could not get buffer from swapchain", 0);
/* Create the RTV for the swapchain */
swapchainViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapchainViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
swapchainViewDesc.Texture2D.MipSlice = 0;
res = ID3D11Device_CreateRenderTargetView(
renderer->device,
(ID3D11Resource*) swapchainTexture,
&swapchainViewDesc,
(ID3D11RenderTargetView**) &resultTexture->twod.targetView
);
ERROR_CHECK_RETURN("Swapchain RT view creation failed", 0);
/* Fill out the rest of the texture struct */
resultTexture->handle = NULL; /* FIXME: Is drawing the backbuffer to an offscreen RT allowed? If so we'll need to fill in this and shaderView. */
resultTexture->shaderView = NULL;
resultTexture->isRenderTarget = 1;
ID3D11Texture2D_GetDesc(swapchainTexture, &textureDesc);
resultTexture->levelCount = textureDesc.MipLevels;
resultTexture->twod.width = textureDesc.Width;
resultTexture->twod.height = textureDesc.Height;
/* Cleanup */
ID3D11Texture2D_Release(swapchainTexture);
return 1;
}
static uint8_t D3D11_INTERNAL_CreateSwapchain( static uint8_t D3D11_INTERNAL_CreateSwapchain(
D3D11Renderer *renderer, D3D11Renderer *renderer,
void *windowHandle void *windowHandle
@ -360,8 +451,6 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
D3D11SwapchainData *swapchainData; D3D11SwapchainData *swapchainData;
SDL_SysWMinfo info; SDL_SysWMinfo info;
HWND dxgiHandle; HWND dxgiHandle;
ID3D11Texture2D *swapchainTexture;
D3D11_RENDER_TARGET_VIEW_DESC swapchainViewDesc;
HRESULT res; HRESULT res;
SDL_VERSION(&info.version); SDL_VERSION(&info.version);
@ -437,7 +526,8 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
swapchainData = (D3D11SwapchainData*) SDL_malloc(sizeof(D3D11SwapchainData)); swapchainData = (D3D11SwapchainData*) SDL_malloc(sizeof(D3D11SwapchainData));
swapchainData->swapchain = swapchain; swapchainData->swapchain = swapchain;
swapchainData->windowHandle = windowHandle; swapchainData->windowHandle = windowHandle;
swapchainData->refreshTexture.rtv = NULL;
/* Add the swapchain data to the window data */
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData); SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData);
if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity) if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity)
{ {
@ -450,44 +540,23 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData; renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData;
renderer->swapchainDataCount += 1; renderer->swapchainDataCount += 1;
/* Create the RTV for the swapchain */ /* Create the Refresh-side texture for the swapchain */
swapchainViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; return D3D11_INTERNAL_InitializeSwapchainTexture(
swapchainViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderer,
swapchainViewDesc.Texture2D.MipSlice = 0; &swapchainData->refreshTexture,
swapchainData->swapchain
res = IDXGISwapChain_GetBuffer(
swapchainData->swapchain,
0,
&D3D_IID_ID3D11Texture2D,
(void**) &swapchainTexture
); );
ERROR_CHECK_RETURN("Could not get buffer from swapchain", 0);
res = ID3D11Device_CreateRenderTargetView(
renderer->device,
(ID3D11Resource*) swapchainTexture,
&swapchainViewDesc,
&swapchainData->refreshTexture.rtv
);
ERROR_CHECK_RETURN("Swapchain RT view creation failed", 0);
/* Cleanup */
ID3D11Texture2D_Release(swapchainTexture);
return 1;
} }
static uint8_t D3D11_INTERNAL_ResizeSwapchain( static uint8_t D3D11_INTERNAL_ResizeSwapchain(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11SwapchainData *swapchainData D3D11SwapchainData *swapchainData
) { ) {
ID3D11Texture2D *swapchainTexture;
D3D11_RENDER_TARGET_VIEW_DESC swapchainViewDesc;
int w, h; int w, h;
HRESULT res; HRESULT res;
/* Release the old RTV */ /* Release the old RTV */
ID3D11RenderTargetView_Release(swapchainData->refreshTexture.rtv); ID3D11RenderTargetView_Release(swapchainData->refreshTexture.twod.targetView);
/* Resize the swapchain */ /* Resize the swapchain */
SDL_GetWindowSize((SDL_Window*) swapchainData->windowHandle, &w, &h); SDL_GetWindowSize((SDL_Window*) swapchainData->windowHandle, &w, &h);
@ -501,31 +570,12 @@ static uint8_t D3D11_INTERNAL_ResizeSwapchain(
); );
ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0); ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0);
/* Recreate the RTV using the new swapchain buffer */ /* Create the Refresh-side texture for the swapchain */
swapchainViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; return D3D11_INTERNAL_InitializeSwapchainTexture(
swapchainViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderer,
swapchainViewDesc.Texture2D.MipSlice = 0; &swapchainData->refreshTexture,
swapchainData->swapchain
res = IDXGISwapChain_GetBuffer(
swapchainData->swapchain,
0,
&D3D_IID_ID3D11Texture2D,
&swapchainTexture
); );
ERROR_CHECK_RETURN("Could not get buffer from swapchain", 0);
res = ID3D11Device_CreateRenderTargetView(
renderer->device,
(ID3D11Resource*) swapchainTexture,
&swapchainViewDesc,
&swapchainData->refreshTexture.rtv
);
ERROR_CHECK_RETURN("Could not create render target view for swapchain", 0);
/* Cleanup */
ID3D11Texture2D_Release(swapchainTexture);
return 1;
} }
/* Quit */ /* Quit */
@ -554,7 +604,7 @@ static void D3D11_DestroyDevice(
/* Release swapchain */ /* Release swapchain */
for (i = 0; i < renderer->swapchainDataCount; i += 1) for (i = 0; i < renderer->swapchainDataCount; i += 1)
{ {
ID3D11RenderTargetView_Release(renderer->swapchainDatas[i]->refreshTexture.rtv); ID3D11RenderTargetView_Release(renderer->swapchainDatas[i]->refreshTexture.twod.targetView);
IDXGISwapChain_Release(renderer->swapchainDatas[i]->swapchain); IDXGISwapChain_Release(renderer->swapchainDatas[i]->swapchain);
SDL_free(renderer->swapchainDatas[i]); SDL_free(renderer->swapchainDatas[i]);
} }
@ -588,7 +638,54 @@ static void D3D11_Clear(
uint32_t colorCount, uint32_t colorCount,
Refresh_DepthStencilValue depthStencil Refresh_DepthStencilValue depthStencil
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
D3D11_CLEAR_FLAG dsClearFlags;
float clearColors[4];
uint32_t i;
/* FIXME: What should we do about clearRect? */
/* FIXME: Do we need to use colorCount or is it always the number of bound RTs? */
if (options & REFRESH_CLEAROPTIONS_COLOR)
{
/* Clear color attachments */
for (i = 0; i < cmdbuf->numBoundColorAttachments; i += 1)
{
clearColors[0] = colors[i].x;
clearColors[1] = colors[i].y;
clearColors[2] = colors[i].z;
clearColors[3] = colors[i].w;
ID3D11DeviceContext_ClearRenderTargetView(
cmdbuf->context,
cmdbuf->rtViews[i],
clearColors
);
}
}
/* Check which of depth/stencil need to be cleared (if either) */
dsClearFlags = 0;
if (options & REFRESH_CLEAROPTIONS_DEPTH)
{
dsClearFlags |= D3D11_CLEAR_DEPTH;
}
if (options & REFRESH_CLEAROPTIONS_STENCIL)
{
dsClearFlags |= D3D11_CLEAR_STENCIL;
}
if (dsClearFlags != 0)
{
ID3D11DeviceContext_ClearDepthStencilView(
cmdbuf->context,
cmdbuf->dsView,
dsClearFlags,
depthStencil.depth,
(uint8_t) depthStencil.stencil
);
}
} }
static void D3D11_DrawInstancedPrimitives( static void D3D11_DrawInstancedPrimitives(
@ -855,26 +952,37 @@ static void D3D11_BeginRenderPass(
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer; D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
D3D11Texture *texture; D3D11Texture *texture;
float clearColors[4]; float clearColors[4];
ID3D11RenderTargetView *rtViews[MAX_COLOR_TARGET_BINDINGS]; D3D11_CLEAR_FLAG dsClearFlags;
ID3D11DepthStencilView *dsView = NULL;
D3D11_VIEWPORT viewports[1]; D3D11_VIEWPORT viewports[1];
D3D11_RECT scissorRects[1]; D3D11_RECT scissorRects[1];
uint8_t i; uint8_t i;
/* Clear the list of attachments for the command buffer */
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
cmdbuf->rtViews[i] = NULL;
}
cmdbuf->dsView = NULL;
/* Get the RTVs for each color attachment. */ /* Get the RTVs for each color attachment. */
cmdbuf->numBoundColorAttachments = colorAttachmentCount;
for (i = 0; i < colorAttachmentCount; i += 1) for (i = 0; i < colorAttachmentCount; i += 1)
{ {
rtViews[i] = ((D3D11Texture*) colorAttachmentInfos[i].texture)->rtv; cmdbuf->rtViews[i] = (ID3D11RenderTargetView*) ((D3D11Texture*) colorAttachmentInfos[i].texture)->twod.targetView;
} }
/* FIXME: Get the DSV for the depth stencil attachment, if one exists! */ /* Get the DSV for the depth stencil attachment, if one exists */
if (depthStencilAttachmentInfo != NULL)
{
cmdbuf->dsView = (ID3D11DepthStencilView*) ((D3D11Texture*) depthStencilAttachmentInfo->texture)->twod.targetView;
}
/* Set the render targets. */ /* Set the render targets. */
ID3D11DeviceContext_OMSetRenderTargets( ID3D11DeviceContext_OMSetRenderTargets(
cmdbuf->context, cmdbuf->context,
colorAttachmentCount, colorAttachmentCount,
rtViews, cmdbuf->rtViews,
NULL cmdbuf->dsView
); );
/* Perform load ops on those render targets. */ /* Perform load ops on those render targets. */
@ -891,12 +999,36 @@ static void D3D11_BeginRenderPass(
ID3D11DeviceContext_ClearRenderTargetView( ID3D11DeviceContext_ClearRenderTargetView(
cmdbuf->context, cmdbuf->context,
texture->rtv, (ID3D11RenderTargetView*) texture->twod.targetView,
clearColors clearColors
); );
} }
} }
if (cmdbuf->dsView != NULL)
{
dsClearFlags = 0;
if (depthStencilAttachmentInfo->loadOp == REFRESH_LOADOP_CLEAR)
{
dsClearFlags |= D3D11_CLEAR_DEPTH;
}
if (depthStencilAttachmentInfo->stencilLoadOp == REFRESH_LOADOP_CLEAR)
{
dsClearFlags |= D3D11_CLEAR_STENCIL;
}
if (dsClearFlags != 0)
{
ID3D11DeviceContext_ClearDepthStencilView(
cmdbuf->context,
(ID3D11DepthStencilView*) ((D3D11Texture*) depthStencilAttachmentInfo->texture)->twod.targetView,
dsClearFlags,
depthStencilAttachmentInfo->depthStencilClearValue.depth,
(uint8_t) depthStencilAttachmentInfo->depthStencilClearValue.stencil
);
}
}
/* FIXME: Set viewport and scissor state */ /* FIXME: Set viewport and scissor state */
/* FIXME: What should we do with render area? */ /* FIXME: What should we do with render area? */
@ -1039,6 +1171,12 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
commandBuffer->fixed = fixed; commandBuffer->fixed = fixed;
commandBuffer->swapchainData = NULL; commandBuffer->swapchainData = NULL;
commandBuffer->commandList = NULL; commandBuffer->commandList = NULL;
commandBuffer->dsView = NULL;
commandBuffer->numBoundColorAttachments = 0;
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
commandBuffer->rtViews[i] = NULL;
}
SDL_UnlockMutex(renderer->commandBufferAcquisitionMutex); SDL_UnlockMutex(renderer->commandBufferAcquisitionMutex);