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