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

Caleb Cornett 2022-03-10 00:30:28 -05:00
parent f638e05ed1
commit e44aee7101
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
{
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;
typedef struct D3D11SwapchainData
@ -247,9 +279,17 @@ typedef struct D3D11SwapchainData
typedef struct D3D11CommandBuffer
{
/* D3D11 Object References */
ID3D11DeviceContext *context;
ID3D11CommandList *commandList;
D3D11SwapchainData *swapchainData;
/* Render Pass */
uint8_t numBoundColorAttachments;
ID3D11RenderTargetView *rtViews[MAX_COLOR_TARGET_BINDINGS];
ID3D11DepthStencilView* dsView;
/* State */
SDL_threadID threadID;
uint8_t recording;
uint8_t fixed;
@ -349,6 +389,57 @@ static void D3D11_INTERNAL_LogError(
/* 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(
D3D11Renderer *renderer,
void *windowHandle
@ -360,8 +451,6 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
D3D11SwapchainData *swapchainData;
SDL_SysWMinfo info;
HWND dxgiHandle;
ID3D11Texture2D *swapchainTexture;
D3D11_RENDER_TARGET_VIEW_DESC swapchainViewDesc;
HRESULT res;
SDL_VERSION(&info.version);
@ -437,7 +526,8 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
swapchainData = (D3D11SwapchainData*) SDL_malloc(sizeof(D3D11SwapchainData));
swapchainData->swapchain = swapchain;
swapchainData->windowHandle = windowHandle;
swapchainData->refreshTexture.rtv = NULL;
/* Add the swapchain data to the window data */
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData);
if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity)
{
@ -450,44 +540,23 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData;
renderer->swapchainDataCount += 1;
/* Create the RTV for the swapchain */
swapchainViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapchainViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
swapchainViewDesc.Texture2D.MipSlice = 0;
res = IDXGISwapChain_GetBuffer(
swapchainData->swapchain,
0,
&D3D_IID_ID3D11Texture2D,
(void**) &swapchainTexture
/* Create the Refresh-side texture for the swapchain */
return D3D11_INTERNAL_InitializeSwapchainTexture(
renderer,
&swapchainData->refreshTexture,
swapchainData->swapchain
);
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(
D3D11Renderer *renderer,
D3D11SwapchainData *swapchainData
) {
ID3D11Texture2D *swapchainTexture;
D3D11_RENDER_TARGET_VIEW_DESC swapchainViewDesc;
int w, h;
HRESULT res;
/* Release the old RTV */
ID3D11RenderTargetView_Release(swapchainData->refreshTexture.rtv);
ID3D11RenderTargetView_Release(swapchainData->refreshTexture.twod.targetView);
/* Resize the swapchain */
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);
/* Recreate the RTV using the new swapchain buffer */
swapchainViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapchainViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
swapchainViewDesc.Texture2D.MipSlice = 0;
res = IDXGISwapChain_GetBuffer(
swapchainData->swapchain,
0,
&D3D_IID_ID3D11Texture2D,
&swapchainTexture
/* Create the Refresh-side texture for the swapchain */
return D3D11_INTERNAL_InitializeSwapchainTexture(
renderer,
&swapchainData->refreshTexture,
swapchainData->swapchain
);
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 */
@ -554,7 +604,7 @@ static void D3D11_DestroyDevice(
/* Release swapchain */
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);
SDL_free(renderer->swapchainDatas[i]);
}
@ -588,7 +638,54 @@ static void D3D11_Clear(
uint32_t colorCount,
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(
@ -855,26 +952,37 @@ static void D3D11_BeginRenderPass(
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
D3D11Texture *texture;
float clearColors[4];
ID3D11RenderTargetView *rtViews[MAX_COLOR_TARGET_BINDINGS];
ID3D11DepthStencilView *dsView = NULL;
D3D11_CLEAR_FLAG dsClearFlags;
D3D11_VIEWPORT viewports[1];
D3D11_RECT scissorRects[1];
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. */
cmdbuf->numBoundColorAttachments = colorAttachmentCount;
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. */
ID3D11DeviceContext_OMSetRenderTargets(
cmdbuf->context,
colorAttachmentCount,
rtViews,
NULL
cmdbuf->rtViews,
cmdbuf->dsView
);
/* Perform load ops on those render targets. */
@ -891,12 +999,36 @@ static void D3D11_BeginRenderPass(
ID3D11DeviceContext_ClearRenderTargetView(
cmdbuf->context,
texture->rtv,
(ID3D11RenderTargetView*) texture->twod.targetView,
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: What should we do with render area? */
@ -1039,6 +1171,12 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
commandBuffer->fixed = fixed;
commandBuffer->swapchainData = 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);