forked from MoonsideGames/Refresh
				
			Implemented Clear, fleshed out D3D11Texture, added depth-stencil clear support in BeginRenderPass
							parent
							
								
									5ebbd8ac63
								
							
						
					
					
						commit
						3b0774579f
					
				|  | @ -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