forked from MoonsideGames/Refresh
				
			Compare commits
	
		
			5 Commits 
		
	
	
		
			63edebef6d
			...
			55eb8375df
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 55eb8375df | |
|  | 0787ebf904 | |
|  | 134925dce7 | |
|  | eb5617f40e | |
|  | 0380a96817 | 
|  | @ -40,6 +40,11 @@ endif() | ||||||
| add_definitions( | add_definitions( | ||||||
| 	-DREFRESH_DRIVER_VULKAN | 	-DREFRESH_DRIVER_VULKAN | ||||||
| ) | ) | ||||||
|  | if (WIN32) | ||||||
|  | 	add_definitions( | ||||||
|  | 		-DREFRESH_DRIVER_D3D11 | ||||||
|  | 	) | ||||||
|  | endif() | ||||||
| 
 | 
 | ||||||
| # Source lists | # Source lists | ||||||
| add_library(Refresh | add_library(Refresh | ||||||
|  | @ -49,8 +54,10 @@ add_library(Refresh | ||||||
| 	# Internal Headers | 	# Internal Headers | ||||||
| 	src/Refresh_Driver.h | 	src/Refresh_Driver.h | ||||||
| 	src/Refresh_Driver_Vulkan_vkfuncs.h | 	src/Refresh_Driver_Vulkan_vkfuncs.h | ||||||
|  | 	src/Refresh_Driver_D3D11_cdefines.h | ||||||
| 	# Source Files | 	# Source Files | ||||||
| 	src/Refresh.c | 	src/Refresh.c | ||||||
|  | 	src/Refresh_Driver_D3D11.c | ||||||
| 	src/Refresh_Driver_Vulkan.c | 	src/Refresh_Driver_Vulkan.c | ||||||
| 	src/Refresh_Image.c | 	src/Refresh_Image.c | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -988,6 +988,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline( | ||||||
|  * 		The area affected by the render pass. |  * 		The area affected by the render pass. | ||||||
|  * 		All load, store and resolve operations are restricted |  * 		All load, store and resolve operations are restricted | ||||||
|  * 		to the given rectangle. |  * 		to the given rectangle. | ||||||
|  |  * 		If NULL, a sensible default will be chosen. | ||||||
|  * colorAttachmentInfos: |  * colorAttachmentInfos: | ||||||
|  * 		A pointer to an array of Refresh_ColorAttachmentInfo structures |  * 		A pointer to an array of Refresh_ColorAttachmentInfo structures | ||||||
|  * 		that contains render targets and clear values. May be NULL. |  * 		that contains render targets and clear values. May be NULL. | ||||||
|  |  | ||||||
|  | @ -34,7 +34,12 @@ | ||||||
| /* Drivers */ | /* Drivers */ | ||||||
| 
 | 
 | ||||||
| static const Refresh_Driver *drivers[] = { | static const Refresh_Driver *drivers[] = { | ||||||
|  | #if REFRESH_DRIVER_VULKAN | ||||||
| 	&VulkanDriver, | 	&VulkanDriver, | ||||||
|  | #endif | ||||||
|  | #if REFRESH_DRIVER_D3D11 | ||||||
|  | 	&D3D11Driver, | ||||||
|  | #endif | ||||||
| 	NULL | 	NULL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -124,21 +129,42 @@ uint32_t Refresh_LinkedVersion(void) | ||||||
| 
 | 
 | ||||||
| /* Driver Functions */ | /* Driver Functions */ | ||||||
| 
 | 
 | ||||||
| static int32_t selectedDriver = 0; | static int32_t selectedDriver = -1; | ||||||
| 
 | 
 | ||||||
| Refresh_Device* Refresh_CreateDevice( | Refresh_Device* Refresh_CreateDevice( | ||||||
| 	Refresh_PresentationParameters *presentationParameters, | 	Refresh_PresentationParameters *presentationParameters, | ||||||
| 	uint8_t debugMode | 	uint8_t debugMode | ||||||
| ) { | ) { | ||||||
| 	if (selectedDriver < 0) | 	uint32_t result = 0; | ||||||
|  | 	uint32_t i; | ||||||
|  | 	const char *hint = SDL_GetHint("REFRESH_FORCE_DRIVER"); | ||||||
|  | 	for (i = 0; drivers[i] != NULL; i += 1) | ||||||
| 	{ | 	{ | ||||||
| 		return NULL; | 		if (hint != NULL) | ||||||
|  | 		{ | ||||||
|  | 			if (SDL_strcmp(hint, drivers[i]->Name) != 0) | ||||||
|  | 			{ | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* FIXME: add fallback driver handling */ | ||||||
|  | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return drivers[selectedDriver]->CreateDevice( | 	if (drivers[i] == NULL) | ||||||
| 		presentationParameters, | 	{ | ||||||
| 		debugMode | 		Refresh_LogError("No supported Refresh driver found!"); | ||||||
| 	); | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		selectedDriver = i; | ||||||
|  | 		return drivers[selectedDriver]->CreateDevice( | ||||||
|  | 			presentationParameters, | ||||||
|  | 			debugMode | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Refresh_DestroyDevice(Refresh_Device *device) | void Refresh_DestroyDevice(Refresh_Device *device) | ||||||
|  |  | ||||||
|  | @ -531,6 +531,7 @@ typedef struct Refresh_Driver | ||||||
| } Refresh_Driver; | } Refresh_Driver; | ||||||
| 
 | 
 | ||||||
| extern Refresh_Driver VulkanDriver; | extern Refresh_Driver VulkanDriver; | ||||||
|  | extern Refresh_Driver D3D11Driver; | ||||||
| 
 | 
 | ||||||
| #endif /* REFRESH_DRIVER_H */ | #endif /* REFRESH_DRIVER_H */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,215 @@ | ||||||
|  | /* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
 | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2020 Evan Hemsley | ||||||
|  |  * | ||||||
|  |  * This software is provided 'as-is', without any express or implied warranty. | ||||||
|  |  * In no event will the authors be held liable for any damages arising from | ||||||
|  |  * the use of this software. | ||||||
|  |  * | ||||||
|  |  * Permission is granted to anyone to use this software for any purpose, | ||||||
|  |  * including commercial applications, and to alter it and redistribute it | ||||||
|  |  * freely, subject to the following restrictions: | ||||||
|  |  * | ||||||
|  |  * 1. The origin of this software must not be misrepresented; you must not | ||||||
|  |  * claim that you wrote the original software. If you use this software in a | ||||||
|  |  * product, an acknowledgment in the product documentation would be | ||||||
|  |  * appreciated but is not required. | ||||||
|  |  * | ||||||
|  |  * 2. Altered source versions must be plainly marked as such, and must not be | ||||||
|  |  * misrepresented as being the original software. | ||||||
|  |  * | ||||||
|  |  * 3. This notice may not be removed or altered from any source distribution. | ||||||
|  |  * | ||||||
|  |  * Evan "cosmonaut" Hemsley <evan@moonside.games> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Function Pointer Signatures */ | ||||||
|  | typedef HRESULT(WINAPI* PFN_CREATE_DXGI_FACTORY)(const GUID* riid, void** ppFactory); | ||||||
|  | 
 | ||||||
|  |  /* IIDs (from https://magnumdb.com) */ | ||||||
|  | 
 | ||||||
|  | static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78,0xf26f,0x4dba,{0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87} }; | ||||||
|  | static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f,0xff09,0x44a9,{0xb0,0x3c,0x77,0x90,0x0a,0x0a,0x1d,0x17} }; | ||||||
|  | static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61,0x3839,0x4626,{0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05} }; | ||||||
|  | static const IID D3D_IID_ID3D11Texture2D = { 0x6f15aaf2,0xd208,0x4e89,{0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c} }; | ||||||
|  | 
 | ||||||
|  | /* IDXGIFactory6 (taken from dxgi1_6.h, cleaned up a bit) */ | ||||||
|  | typedef enum | ||||||
|  | { | ||||||
|  | 	DXGI_FEATURE_PRESENT_ALLOW_TEARING = 0 | ||||||
|  | } DXGI_FEATURE; | ||||||
|  | 
 | ||||||
|  | typedef enum | ||||||
|  | { | ||||||
|  | 	DXGI_GPU_PREFERENCE_UNSPECIFIED = 0, | ||||||
|  | 	DXGI_GPU_PREFERENCE_MINIMUM_POWER = (DXGI_GPU_PREFERENCE_UNSPECIFIED + 1), | ||||||
|  | 	DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE = (DXGI_GPU_PREFERENCE_MINIMUM_POWER + 1) | ||||||
|  | } DXGI_GPU_PREFERENCE; | ||||||
|  | 
 | ||||||
|  | typedef struct IDXGIFactory6 IDXGIFactory6; | ||||||
|  | typedef struct IDXGIFactory6Vtbl | ||||||
|  | { | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* QueryInterface)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFIID riid, | ||||||
|  | 		void** ppvObject); | ||||||
|  | 
 | ||||||
|  | 	ULONG(STDMETHODCALLTYPE* AddRef)( | ||||||
|  | 		IDXGIFactory6* This); | ||||||
|  | 
 | ||||||
|  | 	ULONG(STDMETHODCALLTYPE* Release)( | ||||||
|  | 		IDXGIFactory6* This); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* SetPrivateData)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFGUID Name, | ||||||
|  | 		UINT DataSize, | ||||||
|  | 		const void* pData); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* SetPrivateDataInterface)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFGUID Name, | ||||||
|  | 		const IUnknown* pUnknown); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* GetPrivateData)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFGUID Name, | ||||||
|  | 		UINT* pDataSize, | ||||||
|  | 		void* pData); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* GetParent)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFIID riid, | ||||||
|  | 		void** ppParent); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* EnumAdapters)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		UINT Adapter, | ||||||
|  | 		IDXGIAdapter** ppAdapter); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* MakeWindowAssociation)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HWND WindowHandle, | ||||||
|  | 		UINT Flags); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* GetWindowAssociation)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HWND* pWindowHandle); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CreateSwapChain)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		IUnknown* pDevice, | ||||||
|  | 		DXGI_SWAP_CHAIN_DESC* pDesc, | ||||||
|  | 		IDXGISwapChain** ppSwapChain); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CreateSoftwareAdapter)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HMODULE Module, | ||||||
|  | 		IDXGIAdapter** ppAdapter); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* EnumAdapters1)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		UINT Adapter, | ||||||
|  | 		IDXGIAdapter1** ppAdapter); | ||||||
|  | 
 | ||||||
|  | 	BOOL(STDMETHODCALLTYPE* IsCurrent)( | ||||||
|  | 		IDXGIFactory6* This); | ||||||
|  | 
 | ||||||
|  | 	BOOL(STDMETHODCALLTYPE* IsWindowedStereoEnabled)( | ||||||
|  | 		IDXGIFactory6* This); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CreateSwapChainForHwnd)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		IUnknown* pDevice, | ||||||
|  | 		HWND hWnd, | ||||||
|  | 		void* pDesc, | ||||||
|  | 		void* pFullscreenDesc, | ||||||
|  | 		void* pRestrictToOutput, | ||||||
|  | 		void** ppSwapChain); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CreateSwapChainForCoreWindow)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		IUnknown* pDevice, | ||||||
|  | 		IUnknown* pWindow, | ||||||
|  | 		void* pDesc, | ||||||
|  | 		void* pRestrictToOutput, | ||||||
|  | 		void** ppSwapChain); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* GetSharedResourceAdapterLuid)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HANDLE hResource, | ||||||
|  | 		LUID* pLuid); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* RegisterStereoStatusWindow)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HWND WindowHandle, | ||||||
|  | 		UINT wMsg, | ||||||
|  | 		DWORD* pdwCookie); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* RegisterStereoStatusEvent)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HANDLE hEvent, | ||||||
|  | 		DWORD* pdwCookie); | ||||||
|  | 
 | ||||||
|  | 	void (STDMETHODCALLTYPE* UnregisterStereoStatus)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		DWORD dwCookie); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* RegisterOcclusionStatusWindow)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HWND WindowHandle, | ||||||
|  | 		UINT wMsg, | ||||||
|  | 		DWORD* pdwCookie); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* RegisterOcclusionStatusEvent)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		HANDLE hEvent, | ||||||
|  | 		DWORD* pdwCookie); | ||||||
|  | 
 | ||||||
|  | 	void (STDMETHODCALLTYPE* UnregisterOcclusionStatus)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		DWORD dwCookie); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CreateSwapChainForComposition)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		IUnknown* pDevice, | ||||||
|  | 		void* pDesc, | ||||||
|  | 		void* pRestrictToOutput, | ||||||
|  | 		void** ppSwapChain); | ||||||
|  | 
 | ||||||
|  | 	UINT(STDMETHODCALLTYPE* GetCreationFlags)( | ||||||
|  | 		IDXGIFactory6* This); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* EnumAdapterByLuid)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		LUID AdapterLuid, | ||||||
|  | 		REFIID riid, | ||||||
|  | 		void** ppvAdapter); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* EnumWarpAdapter)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		REFIID riid, | ||||||
|  | 		void** ppvAdapter); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* CheckFeatureSupport)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		DXGI_FEATURE Feature, | ||||||
|  | 		void* pFeatureSupportData, | ||||||
|  | 		UINT FeatureSupportDataSize); | ||||||
|  | 
 | ||||||
|  | 	HRESULT(STDMETHODCALLTYPE* EnumAdapterByGpuPreference)( | ||||||
|  | 		IDXGIFactory6* This, | ||||||
|  | 		UINT Adapter, | ||||||
|  | 		DXGI_GPU_PREFERENCE GpuPreference, | ||||||
|  | 		REFIID riid, | ||||||
|  | 		void** ppvAdapter); | ||||||
|  | } IDXGIFactory6Vtbl; | ||||||
|  | 
 | ||||||
|  | struct IDXGIFactory6 | ||||||
|  | { | ||||||
|  | 	struct IDXGIFactory6Vtbl* lpVtbl; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define IDXGIFactory6_EnumAdapterByGpuPreference(This,Adapter,GpuPreference,riid,ppvAdapter)	\ | ||||||
|  | 	( (This)->lpVtbl -> EnumAdapterByGpuPreference(This,Adapter,GpuPreference,riid,ppvAdapter) )  | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
| static TEMPLATE_SURFACE_FORMAT_TYPE RefreshToTEMPLATE_SurfaceFormat[] = | static TEMPLATE_SURFACE_FORMAT_TYPE RefreshToTEMPLATE_SurfaceFormat[] = | ||||||
| { | { | ||||||
| 	0,	/* R8G8B8A8 */ | 	0,	/* R8G8B8A8 */ | ||||||
|  | 	0,	/* B8G8R8A8 */ | ||||||
| 	0,	/* R5G6B5 */ | 	0,	/* R5G6B5 */ | ||||||
| 	0,	/* A1R5G5B5 */ | 	0,	/* A1R5G5B5 */ | ||||||
| 	0,	/* B4G4R4A4 */ | 	0,	/* B4G4R4A4 */ | ||||||
|  | @ -96,7 +97,6 @@ static TEMPLATE_POLYGON_MODE_TYPE RefreshToTEMPLATE_PolygonMode[] = | ||||||
| { | { | ||||||
| 	0,	/* FILL */ | 	0,	/* FILL */ | ||||||
| 	0,	/* LINE */ | 	0,	/* LINE */ | ||||||
| 	0	/* POINT */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static TEMPLATE_CULL_MODE_TYPE RefreshToTEMPLATE_CullMode[] = | static TEMPLATE_CULL_MODE_TYPE RefreshToTEMPLATE_CullMode[] = | ||||||
|  | @ -104,7 +104,6 @@ static TEMPLATE_CULL_MODE_TYPE RefreshToTEMPLATE_CullMode[] = | ||||||
| 	0,	/* NONE */ | 	0,	/* NONE */ | ||||||
| 	0,	/* FRONT */ | 	0,	/* FRONT */ | ||||||
| 	0,	/* BACK */ | 	0,	/* BACK */ | ||||||
| 	0	/* FRONT_AND_BACK */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static TEMPLATE_FRONT_FACE_TYPE RefreshToTEMPLATE_FrontFace[] = | static TEMPLATE_FRONT_FACE_TYPE RefreshToTEMPLATE_FrontFace[] = | ||||||
|  | @ -127,8 +126,6 @@ static TEMPLATE_BLEND_FACTOR_TYPE RefreshToTEMPLATE_BlendFactor[] = | ||||||
| 	0,	/* ONE_MINUS_DST_ALPHA */ | 	0,	/* ONE_MINUS_DST_ALPHA */ | ||||||
| 	0,	/* CONSTANT_COLOR */ | 	0,	/* CONSTANT_COLOR */ | ||||||
| 	0,	/* ONE_MINUS_CONSTANT_COLOR */ | 	0,	/* ONE_MINUS_CONSTANT_COLOR */ | ||||||
| 	0,	/* CONSTANT_ALPHA */ |  | ||||||
| 	0,	/* ONE_MINUS_CONSTANT_ALPHA */ |  | ||||||
| 	0,	/* SRC_ALPHA_SATURATE */ | 	0,	/* SRC_ALPHA_SATURATE */ | ||||||
| 	0,	/* SRC1_COLOR */ | 	0,	/* SRC1_COLOR */ | ||||||
| 	0,	/* ONE_MINUS_SRC1_COLOR */ | 	0,	/* ONE_MINUS_SRC1_COLOR */ | ||||||
|  | @ -145,26 +142,6 @@ static TEMPLATE_BLEND_OP_TYPE RefreshToTEMPLATE_BlendOp[] = | ||||||
| 	0	/* MAX */ | 	0	/* MAX */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static TEMPLATE_LOGIC_OP_TYPE RefreshToTEMPLATE_LogicOp[] = |  | ||||||
| { |  | ||||||
| 	0,	/* CLEAR */ |  | ||||||
| 	0,	/* AND */ |  | ||||||
| 	0,	/* AND_REVERSE */ |  | ||||||
| 	0,	/* COPY */ |  | ||||||
| 	0,	/* AND_INVERTED */ |  | ||||||
| 	0,	/* NO_OP */ |  | ||||||
| 	0,	/* XOR */ |  | ||||||
| 	0,	/* OR */ |  | ||||||
| 	0,	/* NOR */ |  | ||||||
| 	0,	/* EQUIVALENT */ |  | ||||||
| 	0,	/* INVERT */ |  | ||||||
| 	0,	/* OR_REVERSE */ |  | ||||||
| 	0,	/* COPY_INVERTED */ |  | ||||||
| 	0,	/* OR_INVERTED */ |  | ||||||
| 	0,	/* NAND */ |  | ||||||
| 	0	/* SET */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static TEMPLATE_COMPARE_OP_TYPE RefreshToTEMPLATE_CompareOp[] = | static TEMPLATE_COMPARE_OP_TYPE RefreshToTEMPLATE_CompareOp[] = | ||||||
| { | { | ||||||
| 	0,	/* NEVER */ | 	0,	/* NEVER */ | ||||||
|  | @ -223,7 +200,6 @@ static TEMPLATE_FILTER_TYPE RefreshToTEMPLATE_Filter[] = | ||||||
| { | { | ||||||
| 	0,	/* NEAREST */ | 	0,	/* NEAREST */ | ||||||
| 	0,	/* LINEAR */ | 	0,	/* LINEAR */ | ||||||
| 	0	/* CUBIC */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static TEMPLATE_SAMPLER_MIPMAP_MODE_TYPE RefreshToTEMPLATE_SamplerMipmapMode[] = | static TEMPLATE_SAMPLER_MIPMAP_MODE_TYPE RefreshToTEMPLATE_SamplerMipmapMode[] = | ||||||
|  | @ -324,7 +300,7 @@ static void TEMPLATE_DispatchCompute( | ||||||
| 
 | 
 | ||||||
| static Refresh_ComputePipeline* TEMPLATE_CreateComputePipeline( | static Refresh_ComputePipeline* TEMPLATE_CreateComputePipeline( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_ComputePipelineCreateInfo *pipelineCreateInfo | 	Refresh_ComputeShaderInfo *computeShaderInfo | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
|  | @ -357,14 +333,6 @@ static Refresh_Texture* TEMPLATE_CreateTexture( | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Refresh_RenderTarget* TEMPLATE_CreateRenderTarget( |  | ||||||
| 	Refresh_Renderer *driverData, |  | ||||||
| 	Refresh_TextureSlice *textureSlice, |  | ||||||
| 	Refresh_SampleCount multisampleCount |  | ||||||
| ) { |  | ||||||
| 	NOT_IMPLEMENTED |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Refresh_Buffer* TEMPLATE_CreateBuffer( | static Refresh_Buffer* TEMPLATE_CreateBuffer( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_BufferUsageFlags usageFlags, | 	Refresh_BufferUsageFlags usageFlags, | ||||||
|  | @ -491,7 +459,6 @@ static void TEMPLATE_GetBufferData( | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueueDestroyTexture( | static void TEMPLATE_QueueDestroyTexture( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_Texture *texture | 	Refresh_Texture *texture | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
|  | @ -499,7 +466,6 @@ static void TEMPLATE_QueueDestroyTexture( | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueueDestroySampler( | static void TEMPLATE_QueueDestroySampler( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_Sampler *sampler | 	Refresh_Sampler *sampler | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
|  | @ -507,33 +473,20 @@ static void TEMPLATE_QueueDestroySampler( | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueueDestroyBuffer( | static void TEMPLATE_QueueDestroyBuffer( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_Buffer *buffer | 	Refresh_Buffer *buffer | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueueDestroyRenderTarget( |  | ||||||
| 	Refresh_Renderer *driverData, |  | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_RenderTarget *renderTarget |  | ||||||
| ) { |  | ||||||
| 	NOT_IMPLEMENTED |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void TEMPLATE_QueueDestroyShaderModule( | static void TEMPLATE_QueueDestroyShaderModule( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 
 |  | ||||||
| 	Refresh_ShaderModule *shaderModule | 	Refresh_ShaderModule *shaderModule | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static void TEMPLATE_QueueDestroyComputePipeline( | static void TEMPLATE_QueueDestroyComputePipeline( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_ComputePipeline *computePipeline | 	Refresh_ComputePipeline *computePipeline | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
|  | @ -541,7 +494,6 @@ static void TEMPLATE_QueueDestroyComputePipeline( | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueueDestroyGraphicsPipeline( | static void TEMPLATE_QueueDestroyGraphicsPipeline( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, |  | ||||||
| 	Refresh_GraphicsPipeline *graphicsPipeline | 	Refresh_GraphicsPipeline *graphicsPipeline | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
|  | @ -575,6 +527,22 @@ static void TEMPLATE_BindGraphicsPipeline( | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void TEMPLATE_SetViewport( | ||||||
|  | 	Refresh_Renderer *driverData, | ||||||
|  | 	Refresh_CommandBuffer *commandBuffer, | ||||||
|  | 	Refresh_Viewport *viewport | ||||||
|  | ) { | ||||||
|  | 	NOT_IMPLEMENTED | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void TEMPLATE_SetScissor( | ||||||
|  | 	Refresh_Renderer *driverData, | ||||||
|  | 	Refresh_CommandBuffer *commandBuffer, | ||||||
|  | 	Refresh_Rect *scissor | ||||||
|  | ) { | ||||||
|  | 	NOT_IMPLEMENTED | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void TEMPLATE_BindVertexBuffers( | static void TEMPLATE_BindVertexBuffers( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, | 	Refresh_CommandBuffer *commandBuffer, | ||||||
|  | @ -627,12 +595,16 @@ static Refresh_CommandBuffer* TEMPLATE_AcquireCommandBuffer( | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void TEMPLATE_QueuePresent( | Refresh_Texture* TEMPLATE_AcquireSwapchainTexture( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, | 	Refresh_CommandBuffer *commandBuffer, | ||||||
| 	Refresh_TextureSlice *textureSlice, | 	void *windowHandle | ||||||
| 	Refresh_Rect *destinationRectangle, | ) { | ||||||
| 	Refresh_Filter filter, | 	NOT_IMPLEMENTED | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Refresh_TextureFormat TEMPLATE_GetSwapchainFormat( | ||||||
|  | 	Refresh_Renderer *driverData, | ||||||
| 	void *windowHandle | 	void *windowHandle | ||||||
| ) { | ) { | ||||||
| 	NOT_IMPLEMENTED | 	NOT_IMPLEMENTED | ||||||
|  |  | ||||||
|  | @ -169,13 +169,6 @@ typedef enum VulkanResourceAccessType | ||||||
| 	RESOURCE_ACCESS_TYPES_COUNT | 	RESOURCE_ACCESS_TYPES_COUNT | ||||||
| } VulkanResourceAccessType; | } VulkanResourceAccessType; | ||||||
| 
 | 
 | ||||||
| typedef enum CreateSwapchainResult |  | ||||||
| { |  | ||||||
| 	CREATE_SWAPCHAIN_FAIL, |  | ||||||
| 	CREATE_SWAPCHAIN_SUCCESS, |  | ||||||
| 	CREATE_SWAPCHAIN_SURFACE_ZERO, |  | ||||||
| } CreateSwapchainResult; |  | ||||||
| 
 |  | ||||||
| /* Conversions */ | /* Conversions */ | ||||||
| 
 | 
 | ||||||
| static const uint8_t DEVICE_PRIORITY[] = | static const uint8_t DEVICE_PRIORITY[] = | ||||||
|  | @ -751,6 +744,12 @@ typedef struct VulkanRenderTarget | ||||||
| 	VkSampleCountFlags multisampleCount; | 	VkSampleCountFlags multisampleCount; | ||||||
| } VulkanRenderTarget; | } VulkanRenderTarget; | ||||||
| 
 | 
 | ||||||
|  | typedef struct VulkanFramebuffer | ||||||
|  | { | ||||||
|  | 	VkFramebuffer framebuffer; | ||||||
|  | 	SDL_atomic_t referenceCount; | ||||||
|  | } VulkanFramebuffer; | ||||||
|  | 
 | ||||||
| typedef struct VulkanSwapchainData | typedef struct VulkanSwapchainData | ||||||
| { | { | ||||||
| 	/* Window surface */ | 	/* Window surface */ | ||||||
|  | @ -769,9 +768,6 @@ typedef struct VulkanSwapchainData | ||||||
| 	VulkanTexture *textures; | 	VulkanTexture *textures; | ||||||
| 	uint32_t imageCount; | 	uint32_t imageCount; | ||||||
| 
 | 
 | ||||||
| 	/* Recreate flag */ |  | ||||||
| 	uint8_t needsRecreate; |  | ||||||
| 
 |  | ||||||
| 	/* Synchronization primitives */ | 	/* Synchronization primitives */ | ||||||
| 	VkSemaphore imageAvailableSemaphore; | 	VkSemaphore imageAvailableSemaphore; | ||||||
| 	VkSemaphore renderFinishedSemaphore; | 	VkSemaphore renderFinishedSemaphore; | ||||||
|  | @ -1051,7 +1047,7 @@ typedef struct FramebufferHash | ||||||
| typedef struct FramebufferHashMap | typedef struct FramebufferHashMap | ||||||
| { | { | ||||||
| 	FramebufferHash key; | 	FramebufferHash key; | ||||||
| 	VkFramebuffer value; | 	VulkanFramebuffer *value; | ||||||
| } FramebufferHashMap; | } FramebufferHashMap; | ||||||
| 
 | 
 | ||||||
| typedef struct FramebufferHashArray | typedef struct FramebufferHashArray | ||||||
|  | @ -1103,7 +1099,7 @@ static inline uint8_t FramebufferHash_Compare( | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline VkFramebuffer FramebufferHashArray_Fetch( | static inline VulkanFramebuffer* FramebufferHashArray_Fetch( | ||||||
| 	FramebufferHashArray *arr, | 	FramebufferHashArray *arr, | ||||||
| 	FramebufferHash *key | 	FramebufferHash *key | ||||||
| ) { | ) { | ||||||
|  | @ -1124,7 +1120,7 @@ static inline VkFramebuffer FramebufferHashArray_Fetch( | ||||||
| static inline void FramebufferHashArray_Insert( | static inline void FramebufferHashArray_Insert( | ||||||
| 	FramebufferHashArray *arr, | 	FramebufferHashArray *arr, | ||||||
| 	FramebufferHash key, | 	FramebufferHash key, | ||||||
| 	VkFramebuffer value | 	VulkanFramebuffer *value | ||||||
| ) { | ) { | ||||||
| 	FramebufferHashMap map; | 	FramebufferHashMap map; | ||||||
| 	map.key = key; | 	map.key = key; | ||||||
|  | @ -1520,6 +1516,10 @@ typedef struct VulkanCommandBuffer | ||||||
| 	uint32_t usedComputePipelineCount; | 	uint32_t usedComputePipelineCount; | ||||||
| 	uint32_t usedComputePipelineCapacity; | 	uint32_t usedComputePipelineCapacity; | ||||||
| 
 | 
 | ||||||
|  | 	VulkanFramebuffer **usedFramebuffers; | ||||||
|  | 	uint32_t usedFramebufferCount; | ||||||
|  | 	uint32_t usedFramebufferCapacity; | ||||||
|  | 
 | ||||||
| 	/* Shader modules have references tracked by pipelines */ | 	/* Shader modules have references tracked by pipelines */ | ||||||
| 
 | 
 | ||||||
| 	VkFence inFlightFence; | 	VkFence inFlightFence; | ||||||
|  | @ -1697,6 +1697,10 @@ typedef struct VulkanRenderer | ||||||
| 	uint32_t shaderModulesToDestroyCount; | 	uint32_t shaderModulesToDestroyCount; | ||||||
| 	uint32_t shaderModulesToDestroyCapacity; | 	uint32_t shaderModulesToDestroyCapacity; | ||||||
| 
 | 
 | ||||||
|  | 	VulkanFramebuffer **framebuffersToDestroy; | ||||||
|  | 	uint32_t framebuffersToDestroyCount; | ||||||
|  | 	uint32_t framebuffersToDestroyCapacity; | ||||||
|  | 
 | ||||||
| 	SDL_mutex *allocatorLock; | 	SDL_mutex *allocatorLock; | ||||||
| 	SDL_mutex *disposeLock; | 	SDL_mutex *disposeLock; | ||||||
| 	SDL_mutex *submitLock; | 	SDL_mutex *submitLock; | ||||||
|  | @ -2719,10 +2723,57 @@ static void VULKAN_INTERNAL_TrackComputePipeline( | ||||||
| 	) | 	) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void VULKAN_INTERNAL_TrackFramebuffer( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	VulkanCommandBuffer *commandBuffer, | ||||||
|  | 	VulkanFramebuffer *framebuffer | ||||||
|  | ) { | ||||||
|  | 	TRACK_RESOURCE( | ||||||
|  | 		framebuffer, | ||||||
|  | 		VulkanFramebuffer*, | ||||||
|  | 		usedFramebuffers, | ||||||
|  | 		usedFramebufferCount, | ||||||
|  | 		usedFramebufferCapacity | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #undef TRACK_RESOURCE | #undef TRACK_RESOURCE | ||||||
| 
 | 
 | ||||||
| /* Resource Disposal */ | /* Resource Disposal */ | ||||||
| 
 | 
 | ||||||
|  | static void VULKAN_INTERNAL_QueueDestroyFramebuffer( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	VulkanFramebuffer *framebuffer | ||||||
|  | ) { | ||||||
|  | 	SDL_LockMutex(renderer->disposeLock); | ||||||
|  | 
 | ||||||
|  | 	EXPAND_ARRAY_IF_NEEDED( | ||||||
|  | 		renderer->framebuffersToDestroy, | ||||||
|  | 		VulkanFramebuffer*, | ||||||
|  | 		renderer->framebuffersToDestroyCount + 1, | ||||||
|  | 		renderer->framebuffersToDestroyCapacity, | ||||||
|  | 		renderer->framebuffersToDestroyCapacity * 2 | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	renderer->framebuffersToDestroy[renderer->framebuffersToDestroyCount] = framebuffer; | ||||||
|  | 	renderer->framebuffersToDestroyCount += 1; | ||||||
|  | 
 | ||||||
|  | 	SDL_UnlockMutex(renderer->disposeLock); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void VULKAN_INTERNAL_DestroyFramebuffer( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	VulkanFramebuffer *framebuffer | ||||||
|  | ) { | ||||||
|  | 	renderer->vkDestroyFramebuffer( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		framebuffer->framebuffer, | ||||||
|  | 		NULL | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	SDL_free(framebuffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void VULKAN_INTERNAL_RemoveFramebuffersContainingView( | static void VULKAN_INTERNAL_RemoveFramebuffersContainingView( | ||||||
| 	VulkanRenderer *renderer, | 	VulkanRenderer *renderer, | ||||||
| 	VkImageView view | 	VkImageView view | ||||||
|  | @ -2740,10 +2791,9 @@ static void VULKAN_INTERNAL_RemoveFramebuffersContainingView( | ||||||
| 		{ | 		{ | ||||||
| 			if (hash->colorAttachmentViews[i] == view) | 			if (hash->colorAttachmentViews[i] == view) | ||||||
| 			{ | 			{ | ||||||
| 				renderer->vkDestroyFramebuffer( | 				VULKAN_INTERNAL_QueueDestroyFramebuffer( | ||||||
| 					renderer->logicalDevice, | 					renderer, | ||||||
| 					renderer->framebufferHashArray.elements[i].value, | 					renderer->framebufferHashArray.elements[i].value | ||||||
| 					NULL |  | ||||||
| 				); | 				); | ||||||
| 
 | 
 | ||||||
| 				FramebufferHashArray_Remove( | 				FramebufferHashArray_Remove( | ||||||
|  | @ -2945,6 +2995,7 @@ static void VULKAN_INTERNAL_DestroyCommandPool( | ||||||
| 		SDL_free(commandBuffer->usedSamplers); | 		SDL_free(commandBuffer->usedSamplers); | ||||||
| 		SDL_free(commandBuffer->usedGraphicsPipelines); | 		SDL_free(commandBuffer->usedGraphicsPipelines); | ||||||
| 		SDL_free(commandBuffer->usedComputePipelines); | 		SDL_free(commandBuffer->usedComputePipelines); | ||||||
|  | 		SDL_free(commandBuffer->usedFramebuffers); | ||||||
| 
 | 
 | ||||||
| 		SDL_free(commandBuffer); | 		SDL_free(commandBuffer); | ||||||
| 	} | 	} | ||||||
|  | @ -4037,7 +4088,7 @@ static uint8_t VULKAN_INTERNAL_ChooseSwapPresentMode( | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | static uint8_t VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 	VulkanRenderer *renderer, | 	VulkanRenderer *renderer, | ||||||
| 	void *windowHandle | 	void *windowHandle | ||||||
| ) { | ) { | ||||||
|  | @ -4066,7 +4117,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 			"SDL_Vulkan_CreateSurface failed: %s", | 			"SDL_Vulkan_CreateSurface failed: %s", | ||||||
| 			SDL_GetError() | 			SDL_GetError() | ||||||
| 		); | 		); | ||||||
| 		return CREATE_SWAPCHAIN_FAIL; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!VULKAN_INTERNAL_QuerySwapChainSupport( | 	if (!VULKAN_INTERNAL_QuerySwapChainSupport( | ||||||
|  | @ -4091,7 +4142,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 		} | 		} | ||||||
| 		SDL_free(swapchainData); | 		SDL_free(swapchainData); | ||||||
| 		Refresh_LogError("Device does not support swap chain creation"); | 		Refresh_LogError("Device does not support swap chain creation"); | ||||||
| 		return CREATE_SWAPCHAIN_FAIL; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	swapchainData->swapchainFormat = VK_FORMAT_R8G8B8A8_UNORM; | 	swapchainData->swapchainFormat = VK_FORMAT_R8G8B8A8_UNORM; | ||||||
|  | @ -4133,7 +4184,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 			} | 			} | ||||||
| 			SDL_free(swapchainData); | 			SDL_free(swapchainData); | ||||||
| 			Refresh_LogError("Device does not support swap chain format"); | 			Refresh_LogError("Device does not support swap chain format"); | ||||||
| 			return CREATE_SWAPCHAIN_FAIL; | 			return 0; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -4158,7 +4209,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 		} | 		} | ||||||
| 		SDL_free(swapchainData); | 		SDL_free(swapchainData); | ||||||
| 		Refresh_LogError("Device does not support swap chain present mode"); | 		Refresh_LogError("Device does not support swap chain present mode"); | ||||||
| 		return CREATE_SWAPCHAIN_FAIL; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	SDL_Vulkan_GetDrawableSize( | 	SDL_Vulkan_GetDrawableSize( | ||||||
|  | @ -4189,7 +4240,8 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 				SDL_free(swapchainSupportDetails.presentModes); | 				SDL_free(swapchainSupportDetails.presentModes); | ||||||
| 			} | 			} | ||||||
| 			SDL_free(swapchainData); | 			SDL_free(swapchainData); | ||||||
| 			return CREATE_SWAPCHAIN_SURFACE_ZERO; | 			/* Not an error, just Windows minimize behavior! */ | ||||||
|  | 			return 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (swapchainSupportDetails.capabilities.currentExtent.width != UINT32_MAX) | 		if (swapchainSupportDetails.capabilities.currentExtent.width != UINT32_MAX) | ||||||
|  | @ -4222,7 +4274,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 			} | 			} | ||||||
| 			SDL_free(swapchainData); | 			SDL_free(swapchainData); | ||||||
| 			Refresh_LogError("No fallback swapchain size available!"); | 			Refresh_LogError("No fallback swapchain size available!"); | ||||||
| 			return CREATE_SWAPCHAIN_FAIL; | 			return 0; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -4295,7 +4347,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 		); | 		); | ||||||
| 		SDL_free(swapchainData); | 		SDL_free(swapchainData); | ||||||
| 		LogVulkanResultAsError("vkCreateSwapchainKHR", vulkanResult); | 		LogVulkanResultAsError("vkCreateSwapchainKHR", vulkanResult); | ||||||
| 		return CREATE_SWAPCHAIN_FAIL; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	renderer->vkGetSwapchainImagesKHR( | 	renderer->vkGetSwapchainImagesKHR( | ||||||
|  | @ -4318,7 +4370,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 			NULL | 			NULL | ||||||
| 		); | 		); | ||||||
| 		SDL_free(swapchainData); | 		SDL_free(swapchainData); | ||||||
| 		return CREATE_SWAPCHAIN_FAIL; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	swapchainImages = SDL_stack_alloc(VkImage, swapchainData->imageCount); | 	swapchainImages = SDL_stack_alloc(VkImage, swapchainData->imageCount); | ||||||
|  | @ -4366,7 +4418,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 			SDL_free(swapchainData->textures); | 			SDL_free(swapchainData->textures); | ||||||
| 			SDL_free(swapchainData); | 			SDL_free(swapchainData); | ||||||
| 			LogVulkanResultAsError("vkCreateImageView", vulkanResult); | 			LogVulkanResultAsError("vkCreateImageView", vulkanResult); | ||||||
| 			return CREATE_SWAPCHAIN_FAIL; | 			return 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE; | 		swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE; | ||||||
|  | @ -4408,8 +4460,6 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 		&swapchainData->renderFinishedSemaphore | 		&swapchainData->renderFinishedSemaphore | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	swapchainData->needsRecreate = 0; |  | ||||||
| 
 |  | ||||||
| 	SDL_SetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData); | 	SDL_SetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData); | ||||||
| 
 | 
 | ||||||
| 	if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity) | 	if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity) | ||||||
|  | @ -4424,26 +4474,16 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||||
| 	renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData; | 	renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData; | ||||||
| 	renderer->swapchainDataCount += 1; | 	renderer->swapchainDataCount += 1; | ||||||
| 
 | 
 | ||||||
| 	return CREATE_SWAPCHAIN_SUCCESS; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void VULKAN_INTERNAL_RecreateSwapchain( | static void VULKAN_INTERNAL_RecreateSwapchain( | ||||||
| 	VulkanRenderer* renderer, | 	VulkanRenderer* renderer, | ||||||
| 	void *windowHandle | 	void *windowHandle | ||||||
| ) { | ) { | ||||||
| 	CreateSwapchainResult createSwapchainResult; | 	VULKAN_Wait((Refresh_Renderer*) renderer); | ||||||
| 
 |  | ||||||
| 	VULKAN_Wait((Refresh_Renderer*)renderer); |  | ||||||
| 
 |  | ||||||
| 	VULKAN_INTERNAL_DestroySwapchain(renderer, windowHandle); | 	VULKAN_INTERNAL_DestroySwapchain(renderer, windowHandle); | ||||||
| 	createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | 	VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | ||||||
| 
 |  | ||||||
| 	if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL) |  | ||||||
| 	{ |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	VULKAN_Wait((Refresh_Renderer*)renderer); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Command Buffers */ | /* Command Buffers */ | ||||||
|  | @ -4516,6 +4556,15 @@ static void VULKAN_DestroyDevice( | ||||||
| 
 | 
 | ||||||
| 	VULKAN_Wait(device->driverData); | 	VULKAN_Wait(device->driverData); | ||||||
| 
 | 
 | ||||||
|  | 	for (i = renderer->swapchainDataCount - 1; i >= 0; i -= 1) | ||||||
|  | 	{ | ||||||
|  | 		VULKAN_INTERNAL_DestroySwapchain(renderer, renderer->swapchainDatas[i]->windowHandle); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SDL_free(renderer->swapchainDatas); | ||||||
|  | 
 | ||||||
|  | 	VULKAN_Wait(device->driverData); | ||||||
|  | 
 | ||||||
| 	SDL_free(renderer->submittedCommandBuffers); | 	SDL_free(renderer->submittedCommandBuffers); | ||||||
| 
 | 
 | ||||||
| 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBuffer); | 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBuffer); | ||||||
|  | @ -4675,19 +4724,11 @@ static void VULKAN_DestroyDevice( | ||||||
| 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->fragmentUniformBufferPool); | 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->fragmentUniformBufferPool); | ||||||
| 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->computeUniformBufferPool); | 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->computeUniformBufferPool); | ||||||
| 
 | 
 | ||||||
| 	for (i = renderer->swapchainDataCount - 1; i >= 0; i -= 1) |  | ||||||
| 	{ |  | ||||||
| 		VULKAN_INTERNAL_DestroySwapchain(renderer, renderer->swapchainDatas[i]->windowHandle); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SDL_free(renderer->swapchainDatas); |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < renderer->framebufferHashArray.count; i += 1) | 	for (i = 0; i < renderer->framebufferHashArray.count; i += 1) | ||||||
| 	{ | 	{ | ||||||
| 		renderer->vkDestroyFramebuffer( | 		VULKAN_INTERNAL_DestroyFramebuffer( | ||||||
| 			renderer->logicalDevice, | 			renderer, | ||||||
| 			renderer->framebufferHashArray.elements[i].value, | 			renderer->framebufferHashArray.elements[i].value | ||||||
| 			NULL |  | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -7779,7 +7820,7 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( | ||||||
| 	return renderPass; | 	return renderPass; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer( | ||||||
| 	VulkanRenderer *renderer, | 	VulkanRenderer *renderer, | ||||||
| 	VkRenderPass renderPass, | 	VkRenderPass renderPass, | ||||||
| 	Refresh_ColorAttachmentInfo *colorAttachmentInfos, | 	Refresh_ColorAttachmentInfo *colorAttachmentInfos, | ||||||
|  | @ -7788,7 +7829,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | ||||||
| 	uint32_t width, | 	uint32_t width, | ||||||
| 	uint32_t height | 	uint32_t height | ||||||
| ) { | ) { | ||||||
| 	VkFramebuffer framebuffer; | 	VulkanFramebuffer *vulkanFramebuffer; | ||||||
| 	VkFramebufferCreateInfo framebufferInfo; | 	VkFramebufferCreateInfo framebufferInfo; | ||||||
| 	VkResult result; | 	VkResult result; | ||||||
| 	VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1]; | 	VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1]; | ||||||
|  | @ -7850,17 +7891,21 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | ||||||
| 	hash.width = width; | 	hash.width = width; | ||||||
| 	hash.height = height; | 	hash.height = height; | ||||||
| 
 | 
 | ||||||
| 	framebuffer = FramebufferHashArray_Fetch( | 	vulkanFramebuffer = FramebufferHashArray_Fetch( | ||||||
| 		&renderer->framebufferHashArray, | 		&renderer->framebufferHashArray, | ||||||
| 		&hash | 		&hash | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	if (framebuffer != VK_NULL_HANDLE) | 	if (vulkanFramebuffer != NULL) | ||||||
| 	{ | 	{ | ||||||
| 		SDL_UnlockMutex(renderer->framebufferFetchLock); | 		SDL_UnlockMutex(renderer->framebufferFetchLock); | ||||||
| 		return framebuffer; | 		return vulkanFramebuffer; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	vulkanFramebuffer = SDL_malloc(sizeof(VulkanFramebuffer)); | ||||||
|  | 
 | ||||||
|  | 	SDL_AtomicSet(&vulkanFramebuffer->referenceCount, 0); | ||||||
|  | 
 | ||||||
| 	/* Create a new framebuffer */ | 	/* Create a new framebuffer */ | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < colorAttachmentCount; i += 1) | 	for (i = 0; i < colorAttachmentCount; i += 1) | ||||||
|  | @ -7918,7 +7963,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | ||||||
| 		renderer->logicalDevice, | 		renderer->logicalDevice, | ||||||
| 		&framebufferInfo, | 		&framebufferInfo, | ||||||
| 		NULL, | 		NULL, | ||||||
| 		&framebuffer | 		&vulkanFramebuffer->framebuffer | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	if (result == VK_SUCCESS) | 	if (result == VK_SUCCESS) | ||||||
|  | @ -7926,17 +7971,18 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | ||||||
| 		FramebufferHashArray_Insert( | 		FramebufferHashArray_Insert( | ||||||
| 			&renderer->framebufferHashArray, | 			&renderer->framebufferHashArray, | ||||||
| 			hash, | 			hash, | ||||||
| 			framebuffer | 			vulkanFramebuffer | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		LogVulkanResultAsError("vkCreateFramebuffer", result); | 		LogVulkanResultAsError("vkCreateFramebuffer", result); | ||||||
| 		framebuffer = VK_NULL_HANDLE; | 		SDL_free(vulkanFramebuffer); | ||||||
|  | 		vulkanFramebuffer = NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	SDL_UnlockMutex(renderer->framebufferFetchLock); | 	SDL_UnlockMutex(renderer->framebufferFetchLock); | ||||||
| 	return framebuffer; | 	return vulkanFramebuffer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void VULKAN_INTERNAL_SetCurrentViewport( | static void VULKAN_INTERNAL_SetCurrentViewport( | ||||||
|  | @ -8028,7 +8074,7 @@ static void VULKAN_BeginRenderPass( | ||||||
| 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | ||||||
| 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | ||||||
| 	VkRenderPass renderPass; | 	VkRenderPass renderPass; | ||||||
| 	VkFramebuffer framebuffer; | 	VulkanFramebuffer *framebuffer; | ||||||
| 
 | 
 | ||||||
| 	VulkanTexture *texture; | 	VulkanTexture *texture; | ||||||
| 	VkClearValue *clearValues; | 	VkClearValue *clearValues; | ||||||
|  | @ -8095,6 +8141,8 @@ static void VULKAN_BeginRenderPass( | ||||||
| 		framebufferHeight | 		framebufferHeight | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
|  | 	VULKAN_INTERNAL_TrackFramebuffer(renderer, vulkanCommandBuffer, framebuffer); | ||||||
|  | 
 | ||||||
| 	/* Layout transitions */ | 	/* Layout transitions */ | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < colorAttachmentCount; i += 1) | 	for (i = 0; i < colorAttachmentCount; i += 1) | ||||||
|  | @ -8169,15 +8217,26 @@ static void VULKAN_BeginRenderPass( | ||||||
| 	VkRenderPassBeginInfo renderPassBeginInfo; | 	VkRenderPassBeginInfo renderPassBeginInfo; | ||||||
| 	renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | 	renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | ||||||
| 	renderPassBeginInfo.pNext = NULL; | 	renderPassBeginInfo.pNext = NULL; | ||||||
| 	renderPassBeginInfo.renderPass = (VkRenderPass) renderPass; | 	renderPassBeginInfo.renderPass = renderPass; | ||||||
| 	renderPassBeginInfo.framebuffer = framebuffer; | 	renderPassBeginInfo.framebuffer = framebuffer->framebuffer; | ||||||
| 	renderPassBeginInfo.renderArea.extent.width = renderArea->w; |  | ||||||
| 	renderPassBeginInfo.renderArea.extent.height = renderArea->h; |  | ||||||
| 	renderPassBeginInfo.renderArea.offset.x = renderArea->x; |  | ||||||
| 	renderPassBeginInfo.renderArea.offset.y = renderArea->y; |  | ||||||
| 	renderPassBeginInfo.pClearValues = clearValues; | 	renderPassBeginInfo.pClearValues = clearValues; | ||||||
| 	renderPassBeginInfo.clearValueCount = clearCount; | 	renderPassBeginInfo.clearValueCount = clearCount; | ||||||
| 
 | 
 | ||||||
|  | 	if (renderArea != NULL) | ||||||
|  | 	{ | ||||||
|  | 		renderPassBeginInfo.renderArea.extent.width = renderArea->w; | ||||||
|  | 		renderPassBeginInfo.renderArea.extent.height = renderArea->h; | ||||||
|  | 		renderPassBeginInfo.renderArea.offset.x = renderArea->x; | ||||||
|  | 		renderPassBeginInfo.renderArea.offset.y = renderArea->y; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		renderPassBeginInfo.renderArea.extent.width = framebufferWidth; | ||||||
|  | 		renderPassBeginInfo.renderArea.extent.height = framebufferHeight; | ||||||
|  | 		renderPassBeginInfo.renderArea.offset.x = 0; | ||||||
|  | 		renderPassBeginInfo.renderArea.offset.y = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	renderer->vkCmdBeginRenderPass( | 	renderer->vkCmdBeginRenderPass( | ||||||
| 		vulkanCommandBuffer->commandBuffer, | 		vulkanCommandBuffer->commandBuffer, | ||||||
| 		&renderPassBeginInfo, | 		&renderPassBeginInfo, | ||||||
|  | @ -8715,6 +8774,12 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( | ||||||
| 			commandBuffer->usedComputePipelineCapacity * sizeof(VulkanComputePipeline*) | 			commandBuffer->usedComputePipelineCapacity * sizeof(VulkanComputePipeline*) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | 		commandBuffer->usedFramebufferCapacity = 4; | ||||||
|  | 		commandBuffer->usedFramebufferCount = 0; | ||||||
|  | 		commandBuffer->usedFramebuffers = SDL_malloc( | ||||||
|  | 			commandBuffer->usedFramebufferCapacity * sizeof(VulkanFramebuffer*) | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
| 		vulkanCommandPool->inactiveCommandBuffers[ | 		vulkanCommandPool->inactiveCommandBuffers[ | ||||||
| 			vulkanCommandPool->inactiveCommandBufferCount | 			vulkanCommandPool->inactiveCommandBufferCount | ||||||
| 		] = commandBuffer; | 		] = commandBuffer; | ||||||
|  | @ -8867,6 +8932,25 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( | ||||||
| 	return (Refresh_CommandBuffer*) commandBuffer; | 	return (Refresh_CommandBuffer*) commandBuffer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static VulkanSwapchainData* VULKAN_INTERNAL_FetchSwapchainData( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	void *windowHandle | ||||||
|  | ) { | ||||||
|  | 	VulkanSwapchainData *swapchainData = NULL; | ||||||
|  | 
 | ||||||
|  | 	swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||||
|  | 
 | ||||||
|  | 	if (swapchainData == NULL) | ||||||
|  | 	{ | ||||||
|  | 		if (VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle)) | ||||||
|  | 		{ | ||||||
|  | 			swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return swapchainData; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | ||||||
| 	Refresh_Renderer *driverData, | 	Refresh_Renderer *driverData, | ||||||
| 	Refresh_CommandBuffer *commandBuffer, | 	Refresh_CommandBuffer *commandBuffer, | ||||||
|  | @ -8875,35 +8959,39 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | ||||||
| 	VulkanRenderer *renderer = (VulkanRenderer*) driverData; | 	VulkanRenderer *renderer = (VulkanRenderer*) driverData; | ||||||
| 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | ||||||
| 	uint32_t swapchainImageIndex; | 	uint32_t swapchainImageIndex; | ||||||
| 	VulkanSwapchainData *swapchainData = NULL; | 	VulkanSwapchainData *swapchainData; | ||||||
| 	CreateSwapchainResult createSwapchainResult = 0; |  | ||||||
| 	uint8_t validSwapchainExists = 1; |  | ||||||
| 	VkResult acquireResult = VK_SUCCESS; | 	VkResult acquireResult = VK_SUCCESS; | ||||||
| 	VulkanTexture *swapchainTexture = NULL; | 	VulkanTexture *swapchainTexture = NULL; | ||||||
| 	VulkanPresentData *presentData; | 	VulkanPresentData *presentData; | ||||||
| 
 | 
 | ||||||
| 	swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | 	swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle); | ||||||
| 
 | 
 | ||||||
| 	if (swapchainData == NULL) | 	if (swapchainData == NULL) | ||||||
| 	{ | 	{ | ||||||
| 		createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | 		return NULL; | ||||||
| 
 |  | ||||||
| 		if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL) |  | ||||||
| 		{ |  | ||||||
| 			validSwapchainExists = 0; |  | ||||||
| 		} |  | ||||||
| 		else if (createSwapchainResult == CREATE_SWAPCHAIN_SURFACE_ZERO) |  | ||||||
| 		{ |  | ||||||
| 			validSwapchainExists = 0; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (validSwapchainExists) | 	acquireResult = renderer->vkAcquireNextImageKHR( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		swapchainData->swapchain, | ||||||
|  | 		UINT64_MAX, | ||||||
|  | 		swapchainData->imageAvailableSemaphore, | ||||||
|  | 		VK_NULL_HANDLE, | ||||||
|  | 		&swapchainImageIndex | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	/* Swapchain is suboptimal, let's try to recreate */ | ||||||
|  | 	if (acquireResult == VK_SUBOPTIMAL_KHR) | ||||||
| 	{ | 	{ | ||||||
|  | 		VULKAN_INTERNAL_RecreateSwapchain(renderer, windowHandle); | ||||||
|  | 
 | ||||||
|  | 		swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle); | ||||||
|  | 
 | ||||||
|  | 		if (swapchainData == NULL) | ||||||
|  | 		{ | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		acquireResult = renderer->vkAcquireNextImageKHR( | 		acquireResult = renderer->vkAcquireNextImageKHR( | ||||||
| 			renderer->logicalDevice, | 			renderer->logicalDevice, | ||||||
| 			swapchainData->swapchain, | 			swapchainData->swapchain, | ||||||
|  | @ -8913,74 +9001,71 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | ||||||
| 			&swapchainImageIndex | 			&swapchainImageIndex | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		if (acquireResult == VK_SUCCESS || acquireResult == VK_SUBOPTIMAL_KHR) | 		if (acquireResult != VK_SUCCESS) | ||||||
| 		{ | 		{ | ||||||
| 			swapchainTexture = &swapchainData->textures[swapchainImageIndex]; | 			return NULL; | ||||||
| 
 |  | ||||||
| 			VULKAN_INTERNAL_ImageMemoryBarrier( |  | ||||||
| 				renderer, |  | ||||||
| 				vulkanCommandBuffer->commandBuffer, |  | ||||||
| 				RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, |  | ||||||
| 				VK_IMAGE_ASPECT_COLOR_BIT, |  | ||||||
| 				0, |  | ||||||
| 				1, |  | ||||||
| 				0, |  | ||||||
| 				1, |  | ||||||
| 				0, |  | ||||||
| 				swapchainTexture->image, |  | ||||||
| 				&swapchainTexture->resourceAccessType |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			/* Set up present struct */ |  | ||||||
| 
 |  | ||||||
| 			if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity) |  | ||||||
| 			{ |  | ||||||
| 				vulkanCommandBuffer->presentDataCapacity += 1; |  | ||||||
| 				vulkanCommandBuffer->presentDatas = SDL_realloc( |  | ||||||
| 					vulkanCommandBuffer->presentDatas, |  | ||||||
| 					vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount]; |  | ||||||
| 			vulkanCommandBuffer->presentDataCount += 1; |  | ||||||
| 
 |  | ||||||
| 			presentData->swapchainData = swapchainData; |  | ||||||
| 			presentData->swapchainImageIndex = swapchainImageIndex; |  | ||||||
| 
 |  | ||||||
| 			/* Set up present semaphores */ |  | ||||||
| 
 |  | ||||||
| 			if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity) |  | ||||||
| 			{ |  | ||||||
| 				vulkanCommandBuffer->waitSemaphoreCapacity += 1; |  | ||||||
| 				vulkanCommandBuffer->waitSemaphores = SDL_realloc( |  | ||||||
| 					vulkanCommandBuffer->waitSemaphores, |  | ||||||
| 					vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore; |  | ||||||
| 			vulkanCommandBuffer->waitSemaphoreCount += 1; |  | ||||||
| 
 |  | ||||||
| 			if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity) |  | ||||||
| 			{ |  | ||||||
| 				vulkanCommandBuffer->signalSemaphoreCapacity += 1; |  | ||||||
| 				vulkanCommandBuffer->signalSemaphores = SDL_realloc( |  | ||||||
| 					vulkanCommandBuffer->signalSemaphores, |  | ||||||
| 					vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore; |  | ||||||
| 			vulkanCommandBuffer->signalSemaphoreCount += 1; |  | ||||||
| 
 |  | ||||||
| 			if (acquireResult == VK_SUBOPTIMAL_KHR) |  | ||||||
| 			{ |  | ||||||
| 				swapchainData->needsRecreate = 1; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	swapchainTexture = &swapchainData->textures[swapchainImageIndex]; | ||||||
|  | 
 | ||||||
|  | 	VULKAN_INTERNAL_ImageMemoryBarrier( | ||||||
|  | 		renderer, | ||||||
|  | 		vulkanCommandBuffer->commandBuffer, | ||||||
|  | 		RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, | ||||||
|  | 		VK_IMAGE_ASPECT_COLOR_BIT, | ||||||
|  | 		0, | ||||||
|  | 		1, | ||||||
|  | 		0, | ||||||
|  | 		1, | ||||||
|  | 		0, | ||||||
|  | 		swapchainTexture->image, | ||||||
|  | 		&swapchainTexture->resourceAccessType | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	/* Set up present struct */ | ||||||
|  | 
 | ||||||
|  | 	if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity) | ||||||
|  | 	{ | ||||||
|  | 		vulkanCommandBuffer->presentDataCapacity += 1; | ||||||
|  | 		vulkanCommandBuffer->presentDatas = SDL_realloc( | ||||||
|  | 			vulkanCommandBuffer->presentDatas, | ||||||
|  | 			vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount]; | ||||||
|  | 	vulkanCommandBuffer->presentDataCount += 1; | ||||||
|  | 
 | ||||||
|  | 	presentData->swapchainData = swapchainData; | ||||||
|  | 	presentData->swapchainImageIndex = swapchainImageIndex; | ||||||
|  | 
 | ||||||
|  | 	/* Set up present semaphores */ | ||||||
|  | 
 | ||||||
|  | 	if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity) | ||||||
|  | 	{ | ||||||
|  | 		vulkanCommandBuffer->waitSemaphoreCapacity += 1; | ||||||
|  | 		vulkanCommandBuffer->waitSemaphores = SDL_realloc( | ||||||
|  | 			vulkanCommandBuffer->waitSemaphores, | ||||||
|  | 			vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore; | ||||||
|  | 	vulkanCommandBuffer->waitSemaphoreCount += 1; | ||||||
|  | 
 | ||||||
|  | 	if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity) | ||||||
|  | 	{ | ||||||
|  | 		vulkanCommandBuffer->signalSemaphoreCapacity += 1; | ||||||
|  | 		vulkanCommandBuffer->signalSemaphores = SDL_realloc( | ||||||
|  | 			vulkanCommandBuffer->signalSemaphores, | ||||||
|  | 			vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore; | ||||||
|  | 	vulkanCommandBuffer->signalSemaphoreCount += 1; | ||||||
|  | 
 | ||||||
| 	return (Refresh_Texture*) swapchainTexture; | 	return (Refresh_Texture*) swapchainTexture; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -9104,6 +9189,20 @@ static void VULKAN_INTERNAL_PerformPendingDestroys( | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	for (i = renderer->framebuffersToDestroyCount - 1; i >= 0; i -= 1) | ||||||
|  | 	{ | ||||||
|  | 		if (SDL_AtomicGet(&renderer->framebuffersToDestroy[i]->referenceCount) == 0) | ||||||
|  | 		{ | ||||||
|  | 			VULKAN_INTERNAL_DestroyFramebuffer( | ||||||
|  | 				renderer, | ||||||
|  | 				renderer->framebuffersToDestroy[i] | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			renderer->framebuffersToDestroy[i] = renderer->framebuffersToDestroy[renderer->framebuffersToDestroyCount - 1]; | ||||||
|  | 			renderer->framebuffersToDestroyCount -= 1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	SDL_UnlockMutex(renderer->disposeLock); | 	SDL_UnlockMutex(renderer->disposeLock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -9217,6 +9316,12 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( | ||||||
| 	} | 	} | ||||||
| 	commandBuffer->usedComputePipelineCount = 0; | 	commandBuffer->usedComputePipelineCount = 0; | ||||||
| 
 | 
 | ||||||
|  | 	for (i = 0; i < commandBuffer->usedFramebufferCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		SDL_AtomicDecRef(&commandBuffer->usedFramebuffers[i]->referenceCount); | ||||||
|  | 	} | ||||||
|  | 	commandBuffer->usedFramebufferCount = 0; | ||||||
|  | 
 | ||||||
| 	/* Return command buffer to pool */ | 	/* Return command buffer to pool */ | ||||||
| 
 | 
 | ||||||
| 	SDL_LockMutex(renderer->acquireCommandBufferLock); | 	SDL_LockMutex(renderer->acquireCommandBufferLock); | ||||||
|  | @ -9378,7 +9483,7 @@ static void VULKAN_Submit( | ||||||
| 				&presentInfo | 				&presentInfo | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			if (presentResult != VK_SUCCESS || presentData->swapchainData->needsRecreate) | 			if (presentResult != VK_SUCCESS) | ||||||
| 			{ | 			{ | ||||||
| 				VULKAN_INTERNAL_RecreateSwapchain(renderer, presentData->swapchainData->windowHandle); | 				VULKAN_INTERNAL_RecreateSwapchain(renderer, presentData->swapchainData->windowHandle); | ||||||
| 			} | 			} | ||||||
|  | @ -10239,7 +10344,7 @@ static Refresh_Device* VULKAN_CreateDevice( | ||||||
| 		renderer->swapchainDataCapacity * sizeof(VulkanSwapchainData*) | 		renderer->swapchainDataCapacity * sizeof(VulkanSwapchainData*) | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	if (VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle) != CREATE_SWAPCHAIN_SUCCESS) | 	if (!VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle)) | ||||||
| 	{ | 	{ | ||||||
| 		Refresh_LogError("Failed to create swapchain"); | 		Refresh_LogError("Failed to create swapchain"); | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | @ -10624,6 +10729,13 @@ static Refresh_Device* VULKAN_CreateDevice( | ||||||
| 		renderer->shaderModulesToDestroyCapacity | 		renderer->shaderModulesToDestroyCapacity | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
|  | 	renderer->framebuffersToDestroyCapacity = 16; | ||||||
|  | 	renderer->framebuffersToDestroyCount = 0; | ||||||
|  | 	renderer->framebuffersToDestroy = SDL_malloc( | ||||||
|  | 		sizeof(VulkanFramebuffer*) * | ||||||
|  | 		renderer->framebuffersToDestroyCapacity | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -61,7 +61,7 @@ | ||||||
|     <ClCompile> |     <ClCompile> | ||||||
|       <WarningLevel>Level3</WarningLevel> |       <WarningLevel>Level3</WarningLevel> | ||||||
|       <Optimization>Disabled</Optimization> |       <Optimization>Disabled</Optimization> | ||||||
|       <PreprocessorDefinitions>REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> |       <PreprocessorDefinitions>REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <Link> |     <Link> | ||||||
|       <GenerateDebugInformation>DebugFull</GenerateDebugInformation> |       <GenerateDebugInformation>DebugFull</GenerateDebugInformation> | ||||||
|  | @ -72,7 +72,7 @@ | ||||||
|     <ClCompile> |     <ClCompile> | ||||||
|       <WarningLevel>Level3</WarningLevel> |       <WarningLevel>Level3</WarningLevel> | ||||||
|       <Optimization>MaxSpeed</Optimization> |       <Optimization>MaxSpeed</Optimization> | ||||||
|       <PreprocessorDefinitions>REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> |       <PreprocessorDefinitions>REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> |       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> |       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -84,6 +84,7 @@ | ||||||
|   </ItemDefinitionGroup> |   </ItemDefinitionGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\Refresh.c" /> |     <ClCompile Include="..\src\Refresh.c" /> | ||||||
|  |     <ClCompile Include="..\src\Refresh_Driver_D3D11.c" /> | ||||||
|     <ClCompile Include="..\src\Refresh_Driver_Vulkan.c" /> |     <ClCompile Include="..\src\Refresh_Driver_Vulkan.c" /> | ||||||
|     <ClCompile Include="..\src\Refresh_Image.c" /> |     <ClCompile Include="..\src\Refresh_Image.c" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  | @ -91,6 +92,7 @@ | ||||||
|     <ClInclude Include="..\include\Refresh.h" /> |     <ClInclude Include="..\include\Refresh.h" /> | ||||||
|     <ClInclude Include="..\include\Refresh_Image.h" /> |     <ClInclude Include="..\include\Refresh_Image.h" /> | ||||||
|     <ClInclude Include="..\src\Refresh_Driver.h" /> |     <ClInclude Include="..\src\Refresh_Driver.h" /> | ||||||
|  |     <ClInclude Include="..\src\Refresh_Driver_D3D11_cdefines.h" /> | ||||||
|     <ClInclude Include="..\src\Refresh_Driver_Vulkan_vkfuncs.h" /> |     <ClInclude Include="..\src\Refresh_Driver_Vulkan_vkfuncs.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||||
|  |  | ||||||
|  | @ -10,6 +10,9 @@ | ||||||
|     <ClCompile Include="..\src\Refresh_Image.c"> |     <ClCompile Include="..\src\Refresh_Image.c"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\Refresh_Driver_D3D11.c"> | ||||||
|  |       <Filter>Source Files</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\include\Refresh.h"> |     <ClInclude Include="..\include\Refresh.h"> | ||||||
|  | @ -24,6 +27,9 @@ | ||||||
|     <ClInclude Include="..\include\Refresh_Image.h"> |     <ClInclude Include="..\include\Refresh_Image.h"> | ||||||
|       <Filter>Header Files</Filter> |       <Filter>Header Files</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\Refresh_Driver_D3D11_cdefines.h"> | ||||||
|  |       <Filter>Header Files</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Filter Include="Header Files"> |     <Filter Include="Header Files"> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue