forked from MoonsideGames/Refresh
Implemented Clear, fleshed out D3D11Texture, added depth-stencil clear support in BeginRenderPass
parent
d6ccca3dc3
commit
5315e1c435
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue