forked from MoonsideGames/Refresh
				
			Compare commits
	
		
			11 Commits 
		
	
	
		
			9e7589d844
			...
			4fecc829bf
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 4fecc829bf | |
|  | ff41afb04a | |
|  | cb467c7b1a | |
|  | d5a3438547 | |
|  | 287d3a7a6e | |
|  | 433c70eb8c | |
|  | 8c98889f46 | |
|  | 0e5da8a2ea | |
|  | 8b999aca93 | |
|  | 2498e2d7c4 | |
|  | a15e26b124 | 
|  | @ -298,7 +298,6 @@ typedef struct D3D11CommandBuffer | ||||||
| { | { | ||||||
| 	/* D3D11 Object References */ | 	/* D3D11 Object References */ | ||||||
| 	ID3D11DeviceContext *context; | 	ID3D11DeviceContext *context; | ||||||
| 	ID3D11CommandList *commandList; |  | ||||||
| 	D3D11SwapchainData *swapchainData; | 	D3D11SwapchainData *swapchainData; | ||||||
| 
 | 
 | ||||||
| 	/* Render Pass */ | 	/* Render Pass */ | ||||||
|  | @ -308,7 +307,7 @@ typedef struct D3D11CommandBuffer | ||||||
| 
 | 
 | ||||||
| 	/* State */ | 	/* State */ | ||||||
| 	SDL_threadID threadID; | 	SDL_threadID threadID; | ||||||
| 	uint8_t recording; | 	ID3D11Query *completionQuery; | ||||||
| } D3D11CommandBuffer; | } D3D11CommandBuffer; | ||||||
| 
 | 
 | ||||||
| typedef struct D3D11CommandBufferPool | typedef struct D3D11CommandBufferPool | ||||||
|  | @ -339,7 +338,11 @@ typedef struct D3D11Renderer | ||||||
| 	D3D11CommandBufferPool *commandBufferPool; | 	D3D11CommandBufferPool *commandBufferPool; | ||||||
| 
 | 
 | ||||||
| 	SDL_mutex *contextLock; | 	SDL_mutex *contextLock; | ||||||
| 	SDL_mutex *commandBufferAcquisitionLock; | 	SDL_mutex *acquireCommandBufferLock; | ||||||
|  | 
 | ||||||
|  | 	D3D11CommandBuffer **submittedCommandBuffers; | ||||||
|  | 	uint32_t submittedCommandBufferCount; | ||||||
|  | 	uint32_t submittedCommandBufferCapacity; | ||||||
| } D3D11Renderer; | } D3D11Renderer; | ||||||
| 
 | 
 | ||||||
| /* Logging */ | /* Logging */ | ||||||
|  | @ -690,65 +693,82 @@ static void D3D11_QueueDestroyGraphicsPipeline( | ||||||
| 
 | 
 | ||||||
| /* Graphics State */ | /* Graphics State */ | ||||||
| 
 | 
 | ||||||
|  | static void D3D11_INTERNAL_AllocateCommandBuffers( | ||||||
|  | 	D3D11Renderer *renderer, | ||||||
|  | 	uint32_t allocateCount | ||||||
|  | ) { | ||||||
|  | 	D3D11CommandBufferPool *pool = renderer->commandBufferPool; | ||||||
|  | 	D3D11CommandBuffer *commandBuffer; | ||||||
|  | 	D3D11_QUERY_DESC queryDesc; | ||||||
|  | 	HRESULT res; | ||||||
|  | 
 | ||||||
|  | 	pool->capacity += allocateCount; | ||||||
|  | 
 | ||||||
|  | 	pool->elements = SDL_realloc( | ||||||
|  | 		pool->elements, | ||||||
|  | 		sizeof(D3D11CommandBuffer*) * pool->capacity | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	for (uint32_t i = 0; i < allocateCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		commandBuffer = SDL_malloc(sizeof(D3D11CommandBuffer)); | ||||||
|  | 
 | ||||||
|  | 		res = ID3D11Device_CreateDeferredContext( | ||||||
|  | 			renderer->device, | ||||||
|  | 			0, | ||||||
|  | 			&commandBuffer->context | ||||||
|  | 		); | ||||||
|  | 		ERROR_CHECK("Could not create deferred context! Error Code: %08X"); | ||||||
|  | 
 | ||||||
|  | 		queryDesc.Query = D3D11_QUERY_EVENT; | ||||||
|  | 		queryDesc.MiscFlags = 0; | ||||||
|  | 		res = ID3D11Device_CreateQuery( | ||||||
|  | 			renderer->device, | ||||||
|  | 			&queryDesc, | ||||||
|  | 			&commandBuffer->completionQuery | ||||||
|  | 		); | ||||||
|  | 		ERROR_CHECK("Could not create query! Error Code: %08X"); | ||||||
|  | 
 | ||||||
|  | 		/* FIXME: Resource tracking? */ | ||||||
|  | 
 | ||||||
|  | 		pool->elements[pool->count] = commandBuffer; | ||||||
|  | 		pool->count += 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static D3D11CommandBuffer* D3D11_INTERNAL_GetInactiveCommandBufferFromPool( | ||||||
|  | 	D3D11Renderer *renderer | ||||||
|  | ) { | ||||||
|  | 	D3D11CommandBufferPool *commandPool = renderer->commandBufferPool; | ||||||
|  | 	D3D11CommandBuffer *commandBuffer; | ||||||
|  | 
 | ||||||
|  | 	if (commandPool->count == 0) | ||||||
|  | 	{ | ||||||
|  | 		D3D11_INTERNAL_AllocateCommandBuffers( | ||||||
|  | 			renderer, | ||||||
|  | 			commandPool->capacity | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commandBuffer = commandPool->elements[commandPool->count - 1]; | ||||||
|  | 	commandPool->count -= 1; | ||||||
|  | 
 | ||||||
|  | 	return commandBuffer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( | static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( | ||||||
| 	Refresh_Renderer *driverData | 	Refresh_Renderer *driverData | ||||||
| ) { | ) { | ||||||
| 	D3D11Renderer *renderer = (D3D11Renderer*) driverData; | 	D3D11Renderer *renderer = (D3D11Renderer*) driverData; | ||||||
| 	D3D11CommandBuffer *commandBuffer = NULL; | 	D3D11CommandBuffer *commandBuffer; | ||||||
| 	uint32_t i; | 	uint32_t i; | ||||||
| 	HRESULT res; |  | ||||||
| 
 | 
 | ||||||
| 	/* Make sure multiple threads can't acquire the same command buffer. */ | 	SDL_LockMutex(renderer->acquireCommandBufferLock); | ||||||
| 	SDL_LockMutex(renderer->commandBufferAcquisitionLock); |  | ||||||
| 
 |  | ||||||
| 	/* Try to use an existing command buffer, if one is available. */ |  | ||||||
| 	for (i = 0; i < renderer->commandBufferPool->count; i += 1) |  | ||||||
| 	{ |  | ||||||
| 		/* Search for a command buffer in the pool that is not recording. */ |  | ||||||
| 		if (!renderer->commandBufferPool->elements[i]->recording) |  | ||||||
| 		{ |  | ||||||
| 			commandBuffer = renderer->commandBufferPool->elements[i]; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* If there are no free command buffers, make a new one. */ |  | ||||||
| 	if (commandBuffer == NULL) |  | ||||||
| 	{ |  | ||||||
| 		/* Expand the capacity as needed */ |  | ||||||
| 		EXPAND_ELEMENTS_IF_NEEDED( |  | ||||||
| 			renderer->commandBufferPool, |  | ||||||
| 			2, |  | ||||||
| 			D3D11CommandBuffer* |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		/* Create a new command buffer */ |  | ||||||
| 		renderer->commandBufferPool->elements[i] = (D3D11CommandBuffer*) SDL_malloc( |  | ||||||
| 			sizeof(D3D11CommandBuffer) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		/* Assign it a new deferred context */ |  | ||||||
| 		res = ID3D11Device_CreateDeferredContext( |  | ||||||
| 			renderer->device, |  | ||||||
| 			0, |  | ||||||
| 			&renderer->commandBufferPool->elements[i]->context |  | ||||||
| 		); |  | ||||||
| 		if (FAILED(res)) |  | ||||||
| 		{ |  | ||||||
| 			SDL_UnlockMutex(renderer->commandBufferAcquisitionLock); |  | ||||||
| 			ERROR_CHECK_RETURN("Could not create deferred context for command buffer", NULL); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		/* Now we have a new command buffer we can use! */ |  | ||||||
| 		commandBuffer = renderer->commandBufferPool->elements[i]; |  | ||||||
| 		renderer->commandBufferPool->count += 1; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/* Set up the command buffer */ | 	/* Set up the command buffer */ | ||||||
|  | 	commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer); | ||||||
| 	commandBuffer->threadID = SDL_ThreadID(); | 	commandBuffer->threadID = SDL_ThreadID(); | ||||||
| 	commandBuffer->recording = 1; |  | ||||||
| 	commandBuffer->swapchainData = NULL; | 	commandBuffer->swapchainData = NULL; | ||||||
| 	commandBuffer->commandList = NULL; |  | ||||||
| 	commandBuffer->dsView = NULL; | 	commandBuffer->dsView = NULL; | ||||||
| 	commandBuffer->numBoundColorAttachments = 0; | 	commandBuffer->numBoundColorAttachments = 0; | ||||||
| 	for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) | 	for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) | ||||||
|  | @ -756,7 +776,7 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( | ||||||
| 		commandBuffer->rtViews[i] = NULL; | 		commandBuffer->rtViews[i] = NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	SDL_UnlockMutex(renderer->commandBufferAcquisitionLock); | 	SDL_UnlockMutex(renderer->acquireCommandBufferLock); | ||||||
| 
 | 
 | ||||||
| 	return (Refresh_CommandBuffer*) commandBuffer; | 	return (Refresh_CommandBuffer*) commandBuffer; | ||||||
| } | } | ||||||
|  | @ -1335,6 +1355,41 @@ static void D3D11_SetSwapchainPresentMode( | ||||||
| 
 | 
 | ||||||
| /* Submission and Fences */ | /* Submission and Fences */ | ||||||
| 
 | 
 | ||||||
|  | static void D3D11_INTERNAL_CleanCommandBuffer( | ||||||
|  | 	D3D11Renderer *renderer, | ||||||
|  | 	D3D11CommandBuffer *commandBuffer | ||||||
|  | ) { | ||||||
|  | 	uint32_t i; | ||||||
|  | 
 | ||||||
|  | 	/* FIXME: All kinds of stuff should go here... */ | ||||||
|  | 
 | ||||||
|  | 	SDL_LockMutex(renderer->acquireCommandBufferLock); | ||||||
|  | 
 | ||||||
|  | 	if (renderer->commandBufferPool->count == renderer->commandBufferPool->capacity) | ||||||
|  | 	{ | ||||||
|  | 		renderer->commandBufferPool->capacity += 1; | ||||||
|  | 		renderer->commandBufferPool->elements = SDL_realloc( | ||||||
|  | 			renderer->commandBufferPool->elements, | ||||||
|  | 			renderer->commandBufferPool->capacity * sizeof(D3D11CommandBuffer*) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderer->commandBufferPool->elements[renderer->commandBufferPool->count] = commandBuffer; | ||||||
|  | 	renderer->commandBufferPool->count += 1; | ||||||
|  | 
 | ||||||
|  | 	SDL_UnlockMutex(renderer->acquireCommandBufferLock); | ||||||
|  | 
 | ||||||
|  | 	/* Remove this command buffer from the submitted list */ | ||||||
|  | 	for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		if (renderer->submittedCommandBuffers[i] == commandBuffer) | ||||||
|  | 		{ | ||||||
|  | 			renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1]; | ||||||
|  | 			renderer->submittedCommandBufferCount -= 1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void D3D11_Submit( | static void D3D11_Submit( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer | 	Refresh_CommandBuffer *commandBuffer | ||||||
|  | @ -1346,6 +1401,8 @@ static void D3D11_Submit( | ||||||
| 
 | 
 | ||||||
| 	/* FIXME: Should add sanity check that current thread ID matches the command buffer's threadID. */ | 	/* FIXME: Should add sanity check that current thread ID matches the command buffer's threadID. */ | ||||||
| 
 | 
 | ||||||
|  | 	SDL_LockMutex(renderer->contextLock); | ||||||
|  | 
 | ||||||
| 	/* Serialize the commands into the command list */ | 	/* Serialize the commands into the command list */ | ||||||
| 	res = ID3D11DeviceContext_FinishCommandList( | 	res = ID3D11DeviceContext_FinishCommandList( | ||||||
| 		d3d11CommandBuffer->context, | 		d3d11CommandBuffer->context, | ||||||
|  | @ -1355,31 +1412,40 @@ static void D3D11_Submit( | ||||||
| 	ERROR_CHECK("Could not finish command list recording!"); | 	ERROR_CHECK("Could not finish command list recording!"); | ||||||
| 
 | 
 | ||||||
| 	/* Submit the command list to the immediate context */ | 	/* Submit the command list to the immediate context */ | ||||||
| 	SDL_LockMutex(renderer->contextLock); |  | ||||||
| 	ID3D11DeviceContext_ExecuteCommandList( | 	ID3D11DeviceContext_ExecuteCommandList( | ||||||
| 		renderer->immediateContext, | 		renderer->immediateContext, | ||||||
| 		commandList, | 		commandList, | ||||||
| 		0 | 		0 | ||||||
| 	); | 	); | ||||||
| 	SDL_UnlockMutex(renderer->contextLock); |  | ||||||
| 
 |  | ||||||
| 	/* Now that we're done with the command list, release it! */ |  | ||||||
| 	ID3D11CommandList_Release(commandList); | 	ID3D11CommandList_Release(commandList); | ||||||
| 
 | 
 | ||||||
| 	/* Mark the command buffer as not-recording so that it can be used to record again. */ | 	/* Mark the command buffer as submitted */ | ||||||
| 	d3d11CommandBuffer->recording = 0; | 	if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity) | ||||||
|  | 	{ | ||||||
|  | 		renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1; | ||||||
|  | 
 | ||||||
|  | 		renderer->submittedCommandBuffers = SDL_realloc( | ||||||
|  | 			renderer->submittedCommandBuffers, | ||||||
|  | 			sizeof(D3D11CommandBuffer*) * renderer->submittedCommandBufferCapacity | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = d3d11CommandBuffer; | ||||||
|  | 	renderer->submittedCommandBufferCount += 1; | ||||||
|  | 
 | ||||||
|  | 	SDL_UnlockMutex(renderer->contextLock); | ||||||
| 
 | 
 | ||||||
| 	/* Present, if applicable */ | 	/* Present, if applicable */ | ||||||
| 	if (d3d11CommandBuffer->swapchainData) | 	if (d3d11CommandBuffer->swapchainData) | ||||||
| 	{ | 	{ | ||||||
| 		SDL_LockMutex(renderer->contextLock); |  | ||||||
| 		IDXGISwapChain_Present( | 		IDXGISwapChain_Present( | ||||||
| 			d3d11CommandBuffer->swapchainData->swapchain, | 			d3d11CommandBuffer->swapchainData->swapchain, | ||||||
| 			1, /* FIXME: Assumes vsync! */ | 			1, /* FIXME: Assumes vsync! */ | ||||||
| 			0 | 			0 | ||||||
| 		); | 		); | ||||||
| 		SDL_UnlockMutex(renderer->contextLock); |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	SDL_UnlockMutex(renderer->contextLock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Refresh_Fence* D3D11_SubmitAndAcquireFence( | static Refresh_Fence* D3D11_SubmitAndAcquireFence( | ||||||
|  | @ -1393,7 +1459,38 @@ static Refresh_Fence* D3D11_SubmitAndAcquireFence( | ||||||
| static void D3D11_Wait( | static void D3D11_Wait( | ||||||
| 	Refresh_Renderer *driverData | 	Refresh_Renderer *driverData | ||||||
| ) { | ) { | ||||||
| 	/* FIXME: Anything we need to do here? */ | 	D3D11Renderer *renderer = (D3D11Renderer*) driverData; | ||||||
|  | 	D3D11CommandBuffer *commandBuffer; | ||||||
|  | 	BOOL queryData; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Wait for all submitted command buffers to complete. | ||||||
|  | 	 * Sort of equivalent to vkDeviceWaitIdle. | ||||||
|  | 	 */ | ||||||
|  | 	for (uint32_t i = 0; i < renderer->submittedCommandBufferCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		while (S_OK != ID3D11DeviceContext_GetData( | ||||||
|  | 			renderer->immediateContext, | ||||||
|  | 			(ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->completionQuery, | ||||||
|  | 			&queryData, | ||||||
|  | 			sizeof(queryData), | ||||||
|  | 			0 | ||||||
|  | 		)) { | ||||||
|  | 			/* Spin until we get a result back... */ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SDL_LockMutex(renderer->contextLock); | ||||||
|  | 
 | ||||||
|  | 	for (int32_t i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) | ||||||
|  | 	{ | ||||||
|  | 		commandBuffer = renderer->submittedCommandBuffers[i]; | ||||||
|  | 		D3D11_INTERNAL_CleanCommandBuffer(renderer, commandBuffer); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* FIXME: D3D11_INTERNAL_PerformPendingDestroys(renderer); */ | ||||||
|  | 
 | ||||||
|  | 	SDL_UnlockMutex(renderer->contextLock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void D3D11_WaitForFences( | static void D3D11_WaitForFences( | ||||||
|  | @ -1673,7 +1770,7 @@ tryCreateDevice: | ||||||
| 
 | 
 | ||||||
| 	/* Create mutexes */ | 	/* Create mutexes */ | ||||||
| 	renderer->contextLock = SDL_CreateMutex(); | 	renderer->contextLock = SDL_CreateMutex(); | ||||||
| 	renderer->commandBufferAcquisitionLock = SDL_CreateMutex(); | 	renderer->acquireCommandBufferLock = SDL_CreateMutex(); | ||||||
| 
 | 
 | ||||||
| 	/* Initialize miscellaneous renderer members */ | 	/* Initialize miscellaneous renderer members */ | ||||||
| 	renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG); | 	renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue