|  |  |  | @ -79,7 +79,8 @@ typedef struct VulkanExtensions | 
		
	
		
			
				|  |  |  |  | #define ALLOCATION_INCREMENT 16000000           /* 16MB */ | 
		
	
		
			
				|  |  |  |  | #define TRANSFER_BUFFER_STARTING_SIZE 8000000 	/* 8MB */ | 
		
	
		
			
				|  |  |  |  | #define POOLED_TRANSFER_BUFFER_SIZE 16000000    /* 16MB */ | 
		
	
		
			
				|  |  |  |  | #define UBO_BUFFER_SIZE 16000 			        /* 16KB */ | 
		
	
		
			
				|  |  |  |  | #define UBO_BUFFER_SIZE 16777216 				/* 16MB */ | 
		
	
		
			
				|  |  |  |  | #define UBO_SECTION_SIZE 4096 			        /* 4KB */ | 
		
	
		
			
				|  |  |  |  | #define DESCRIPTOR_POOL_STARTING_SIZE 128 | 
		
	
		
			
				|  |  |  |  | #define DEFRAG_TIME 200 | 
		
	
		
			
				|  |  |  |  | #define WINDOW_DATA "Refresh_VulkanWindowData" | 
		
	
	
		
			
				
					|  |  |  | @ -560,8 +561,8 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE */ | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 
		
	
		
			
				|  |  |  |  | 		VK_ACCESS_SHADER_READ_BIT, | 
		
	
		
			
				|  |  |  |  | 		VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, | 
		
	
		
			
				|  |  |  |  | 		VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, | 
		
	
		
			
				|  |  |  |  | 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL | 
		
	
		
			
				|  |  |  |  | 	}, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -707,6 +708,7 @@ struct VulkanBuffer | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 	VkBufferUsageFlags usage; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	uint8_t requireHostVisible; | 
		
	
		
			
				|  |  |  |  | 	uint8_t preferDeviceLocal; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	SDL_atomic_t referenceCount; /* Tracks command buffer usage */ | 
		
	
	
		
			
				
					|  |  |  | @ -719,8 +721,8 @@ typedef struct VulkanUniformBufferPool VulkanUniformBufferPool; | 
		
	
		
			
				|  |  |  |  | typedef struct VulkanUniformBuffer | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferPool *pool; | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer *vulkanBuffer; | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize offset; | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize poolOffset; /* memory offset relative to the pool buffer */ | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize offset; /* based on uniform pushes */ | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSet descriptorSet; | 
		
	
		
			
				|  |  |  |  | } VulkanUniformBuffer; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -746,10 +748,13 @@ typedef struct VulkanUniformDescriptorPool | 
		
	
		
			
				|  |  |  |  | 	uint32_t availableDescriptorSetCount; | 
		
	
		
			
				|  |  |  |  | } VulkanUniformDescriptorPool; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /* This is actually just one buffer that we carve slices out of. */ | 
		
	
		
			
				|  |  |  |  | struct VulkanUniformBufferPool | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferType type; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformDescriptorPool descriptorPool; | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer *buffer; | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize nextAvailableOffset; | 
		
	
		
			
				|  |  |  |  | 	SDL_mutex *lock; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer **availableBuffers; | 
		
	
	
		
			
				
					|  |  |  | @ -1776,6 +1781,8 @@ typedef struct VulkanRenderer | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSetLayout vertexUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSetLayout fragmentUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSetLayout computeUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer *dummyBuffer; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *dummyVertexUniformBuffer; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *dummyFragmentUniformBuffer; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *dummyComputeUniformBuffer; | 
		
	
	
		
			
				
					|  |  |  | @ -1973,59 +1980,51 @@ static inline uint32_t VULKAN_INTERNAL_BytesPerPixel(VkFormat format) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	switch (format) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 1; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R5G6B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8_SNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D16_UNORM: | 
		
	
		
			
				|  |  |  |  | 			return 2; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D16_UNORM_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 3; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_B8G8R8A8_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_SNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 			return 4; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D32_SFLOAT_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 5; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R32G32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: | 
		
	
		
			
				|  |  |  |  | 			return 8; | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R32G32B32A32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_BC2_UNORM_BLOCK: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_BC3_UNORM_BLOCK: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_BC7_UNORM_BLOCK: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 16; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_SNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_B8G8R8A8_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_B8G8R8A8_SNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8B8A8_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 4; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R5G6B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8_SNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D16_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8G8_UINT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 2; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_UNORM: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R32G32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R16G16B16A16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 8; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_R8_UNORM: | 
		
	
		
			
				|  |  |  |  | 			return 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D16_UNORM_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 3; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		case VK_FORMAT_D32_SFLOAT_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 			return 5; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		default: | 
		
	
		
			
				|  |  |  |  | 			Refresh_LogError("Invalid texture format!"); | 
		
	
		
			
				|  |  |  |  | 			Refresh_LogError("Texture format not recognized!"); | 
		
	
		
			
				|  |  |  |  | 			return 0; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static inline uint32_t VULKAN_INTERNAL_GetTextureBlockSize( | 
		
	
		
			
				|  |  |  |  | static inline uint32_t VULKAN_INTERNAL_TextureBlockSize( | 
		
	
		
			
				|  |  |  |  | 	VkFormat format | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	switch (format) | 
		
	
	
		
			
				
					|  |  |  | @ -2040,24 +2039,28 @@ static inline uint32_t VULKAN_INTERNAL_GetTextureBlockSize( | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R5G6B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_A1R5G5B5_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_B4G4R4A4_UNORM_PACK16: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8_SNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8B8A8_SNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_A2R10G10B10_UNORM_PACK32: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16_UNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16B16A16_UNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8_UNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32G32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32G32B32A32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8_SNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8B8A8_SNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16B16A16_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32G32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R32G32B32A32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R8G8B8A8_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_R16G16B16A16_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_D16_UNORM: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_D32_SFLOAT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_D16_UNORM_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 	case VK_FORMAT_D32_SFLOAT_S8_UINT: | 
		
	
		
			
				|  |  |  |  | 		return 1; | 
		
	
		
			
				|  |  |  |  | 	default: | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Unrecognized texture format!"); | 
		
	
	
		
			
				
					|  |  |  | @ -2070,17 +2073,8 @@ static inline VkDeviceSize VULKAN_INTERNAL_BytesPerImage( | 
		
	
		
			
				|  |  |  |  | 	uint32_t height, | 
		
	
		
			
				|  |  |  |  | 	VkFormat format | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	uint32_t blocksPerRow = width; | 
		
	
		
			
				|  |  |  |  | 	uint32_t blocksPerColumn = height; | 
		
	
		
			
				|  |  |  |  | 	uint32_t blockSize = VULKAN_INTERNAL_GetTextureBlockSize(format); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (blockSize > 1) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		blocksPerRow = (width + blockSize - 1) / blockSize; | 
		
	
		
			
				|  |  |  |  | 		blocksPerColumn = (height + blockSize - 1) / blockSize; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return blocksPerRow * blocksPerColumn * VULKAN_INTERNAL_BytesPerPixel(format); | 
		
	
		
			
				|  |  |  |  | 	uint32_t blockSize = VULKAN_INTERNAL_TextureBlockSize(format); | 
		
	
		
			
				|  |  |  |  | 	return (width * height * VULKAN_INTERNAL_BytesPerPixel(format)) / (blockSize * blockSize); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static inline Refresh_SampleCount VULKAN_INTERNAL_GetMaxMultiSampleCount( | 
		
	
	
		
			
				
					|  |  |  | @ -2398,12 +2392,6 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	Refresh_LogWarn( | 
		
	
		
			
				|  |  |  |  | 		"Failed to find memory type %X, required %X, ignored %X", | 
		
	
		
			
				|  |  |  |  | 		typeFilter, | 
		
	
		
			
				|  |  |  |  | 		requiredProperties, | 
		
	
		
			
				|  |  |  |  | 		ignoredProperties | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 	return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -2587,7 +2575,6 @@ static uint8_t VULKAN_INTERNAL_AllocateMemory( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		SDL_free(allocation); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogWarn("vkAllocateMemory: %s", VkErrorMessages(result)); | 
		
	
		
			
				|  |  |  |  | 		return 0; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -2821,7 +2808,6 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory( | 
		
	
		
			
				|  |  |  |  | 		SDL_UnlockMutex(renderer->allocatorLock); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		/* Responsibility of the caller to handle being out of memory */ | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogWarn("Failed to allocate memory!"); | 
		
	
		
			
				|  |  |  |  | 		return 2; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -2947,7 +2933,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage( | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		memoryTypeIndex = 0; | 
		
	
		
			
				|  |  |  |  | 		requiredMemoryPropertyFlags = 0; | 
		
	
		
			
				|  |  |  |  | 		ignoredMemoryPropertyFlags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT; | 
		
	
		
			
				|  |  |  |  | 		ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		if (isRenderTarget) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
	
		
			
				
					|  |  |  | @ -2993,23 +2979,32 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( | 
		
	
		
			
				|  |  |  |  | 	VulkanRenderer* renderer, | 
		
	
		
			
				|  |  |  |  | 	VkBuffer buffer, | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize size, | 
		
	
		
			
				|  |  |  |  | 	uint8_t requireHostVisible, | 
		
	
		
			
				|  |  |  |  | 	uint8_t preferDeviceLocal, | 
		
	
		
			
				|  |  |  |  | 	uint8_t isTransferBuffer, | 
		
	
		
			
				|  |  |  |  | 	uint8_t dedicatedAllocation, | 
		
	
		
			
				|  |  |  |  | 	VulkanMemoryUsedRegion** usedRegion | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	uint8_t bindResult = 0; | 
		
	
		
			
				|  |  |  |  | 	uint32_t memoryTypeIndex = 0; | 
		
	
		
			
				|  |  |  |  | 	VkMemoryPropertyFlags requiredMemoryPropertyFlags; | 
		
	
		
			
				|  |  |  |  | 	VkMemoryPropertyFlags ignoredMemoryPropertyFlags; | 
		
	
		
			
				|  |  |  |  | 	VkMemoryPropertyFlags requiredMemoryPropertyFlags = 0; | 
		
	
		
			
				|  |  |  |  | 	VkMemoryPropertyFlags ignoredMemoryPropertyFlags = 0; | 
		
	
		
			
				|  |  |  |  | 	VkMemoryRequirements2KHR memoryRequirements = | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, | 
		
	
		
			
				|  |  |  |  | 		NULL | 
		
	
		
			
				|  |  |  |  | 	}; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	requiredMemoryPropertyFlags = | 
		
	
		
			
				|  |  |  |  | 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | | 
		
	
		
			
				|  |  |  |  | 		VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; | 
		
	
		
			
				|  |  |  |  | 	if (requireHostVisible) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		requiredMemoryPropertyFlags = | 
		
	
		
			
				|  |  |  |  | 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | | 
		
	
		
			
				|  |  |  |  | 			VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		ignoredMemoryPropertyFlags = | 
		
	
		
			
				|  |  |  |  | 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (preferDeviceLocal) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
	
		
			
				
					|  |  |  | @ -3030,7 +3025,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			memoryTypeIndex, | 
		
	
		
			
				|  |  |  |  | 			&memoryRequirements, | 
		
	
		
			
				|  |  |  |  | 			isTransferBuffer, | 
		
	
		
			
				|  |  |  |  | 			dedicatedAllocation, | 
		
	
		
			
				|  |  |  |  | 			size, | 
		
	
		
			
				|  |  |  |  | 			buffer, | 
		
	
		
			
				|  |  |  |  | 			VK_NULL_HANDLE, | 
		
	
	
		
			
				
					|  |  |  | @ -3048,9 +3043,10 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Bind failed, try again if originally preferred device local */ | 
		
	
		
			
				|  |  |  |  | 	if (bindResult != 1 && preferDeviceLocal) | 
		
	
		
			
				|  |  |  |  | 	if (bindResult != 1) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		memoryTypeIndex = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		requiredMemoryPropertyFlags = | 
		
	
		
			
				|  |  |  |  | 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | | 
		
	
		
			
				|  |  |  |  | 			VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; | 
		
	
	
		
			
				
					|  |  |  | @ -3074,7 +3070,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( | 
		
	
		
			
				|  |  |  |  | 				renderer, | 
		
	
		
			
				|  |  |  |  | 				memoryTypeIndex, | 
		
	
		
			
				|  |  |  |  | 				&memoryRequirements, | 
		
	
		
			
				|  |  |  |  | 				isTransferBuffer, | 
		
	
		
			
				|  |  |  |  | 				dedicatedAllocation, | 
		
	
		
			
				|  |  |  |  | 				size, | 
		
	
		
			
				|  |  |  |  | 				buffer, | 
		
	
		
			
				|  |  |  |  | 				VK_NULL_HANDLE, | 
		
	
	
		
			
				
					|  |  |  | @ -3606,6 +3602,8 @@ static void VULKAN_INTERNAL_DestroyCommandPool( | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->transferBuffers); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->boundUniformBuffers); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->boundDescriptorSetDatas); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->boundComputeBuffers); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->boundComputeTextures); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->usedBuffers); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->usedTextures); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(commandBuffer->usedSamplers); | 
		
	
	
		
			
				
					|  |  |  | @ -4109,8 +4107,9 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 	VkDeviceSize size, | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 	VkBufferUsageFlags usage, | 
		
	
		
			
				|  |  |  |  | 	uint8_t requireHostVisible, | 
		
	
		
			
				|  |  |  |  | 	uint8_t preferDeviceLocal, | 
		
	
		
			
				|  |  |  |  | 	uint8_t isTransferBuffer | 
		
	
		
			
				|  |  |  |  | 	uint8_t dedicatedAllocation | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer* buffer; | 
		
	
		
			
				|  |  |  |  | 	VkResult vulkanResult; | 
		
	
	
		
			
				
					|  |  |  | @ -4122,6 +4121,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 	buffer->size = size; | 
		
	
		
			
				|  |  |  |  | 	buffer->resourceAccessType = resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 	buffer->usage = usage; | 
		
	
		
			
				|  |  |  |  | 	buffer->requireHostVisible = requireHostVisible; | 
		
	
		
			
				|  |  |  |  | 	buffer->preferDeviceLocal = preferDeviceLocal; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | 
		
	
	
		
			
				
					|  |  |  | @ -4145,8 +4145,9 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		buffer->buffer, | 
		
	
		
			
				|  |  |  |  | 		buffer->size, | 
		
	
		
			
				|  |  |  |  | 		buffer->requireHostVisible, | 
		
	
		
			
				|  |  |  |  | 		buffer->preferDeviceLocal, | 
		
	
		
			
				|  |  |  |  | 		isTransferBuffer, | 
		
	
		
			
				|  |  |  |  | 		dedicatedAllocation, | 
		
	
		
			
				|  |  |  |  | 		&buffer->usedRegion | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -4203,6 +4204,37 @@ static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool( | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferType uniformBufferType | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferPool* uniformBufferPool = SDL_malloc(sizeof(VulkanUniformBufferPool)); | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (uniformBufferType == UNIFORM_BUFFER_VERTEX) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (uniformBufferType == UNIFORM_BUFFER_FRAGMENT) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (uniformBufferType == UNIFORM_BUFFER_COMPUTE) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Unrecognized uniform buffer type!"); | 
		
	
		
			
				|  |  |  |  | 		return 0; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	uniformBufferPool->buffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE, | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		1 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	uniformBufferPool->nextAvailableOffset = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	uniformBufferPool->type = uniformBufferType; | 
		
	
		
			
				|  |  |  |  | 	uniformBufferPool->lock = SDL_CreateMutex(); | 
		
	
	
		
			
				
					|  |  |  | @ -4221,6 +4253,7 @@ static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool( | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 	VulkanRenderer *renderer, | 
		
	
		
			
				|  |  |  |  | 	VulkanCommandBuffer *commandBuffer, | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *uniformBuffer | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
	
		
			
				
					|  |  |  | @ -4237,26 +4270,58 @@ static void VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 	commandBuffer->boundUniformBufferCount += 1; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /* Buffer indirection so we can cleanly defrag */ | 
		
	
		
			
				|  |  |  |  | static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( | 
		
	
		
			
				|  |  |  |  | 	VulkanRenderer *renderer, | 
		
	
		
			
				|  |  |  |  | 	uint32_t sizeInBytes, | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 	VkBufferUsageFlags usageFlags | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanBufferContainer* bufferContainer; | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer* buffer; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* always set transfer bits so we can defrag */ | 
		
	
		
			
				|  |  |  |  | 	usageFlags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		sizeInBytes, | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 		usageFlags, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		0 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (buffer == NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Failed to create buffer!"); | 
		
	
		
			
				|  |  |  |  | 		return NULL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	bufferContainer = SDL_malloc(sizeof(VulkanBufferContainer)); | 
		
	
		
			
				|  |  |  |  | 	bufferContainer->vulkanBuffer = buffer; | 
		
	
		
			
				|  |  |  |  | 	buffer->container = bufferContainer; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return (VulkanBufferContainer*) bufferContainer; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static uint8_t VULKAN_INTERNAL_CreateUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 	VulkanRenderer *renderer, | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferPool *bufferPool | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSetLayout descriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (bufferPool->type == UNIFORM_BUFFER_VERTEX) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->vertexUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (bufferPool->type == UNIFORM_BUFFER_FRAGMENT) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->fragmentUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (bufferPool->type == UNIFORM_BUFFER_COMPUTE) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->computeUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
	
		
			
				
					|  |  |  | @ -4265,26 +4330,20 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		return 0; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *buffer = SDL_malloc(sizeof(VulkanUniformBuffer)); | 
		
	
		
			
				|  |  |  |  | 	buffer->pool = bufferPool; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer)); | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->pool = bufferPool; | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->poolOffset = bufferPool->nextAvailableOffset; | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->offset = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer->vulkanBuffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE, | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		0 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 	bufferPool->nextAvailableOffset += VULKAN_INTERNAL_NextHighestAlignment(UBO_SECTION_SIZE, renderer->minUBOAlignment); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (buffer->vulkanBuffer == NULL) | 
		
	
		
			
				|  |  |  |  | 	if (bufferPool->nextAvailableOffset >= UBO_BUFFER_SIZE) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Failed to create buffer for uniform buffer!"); | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Uniform buffer overflow!"); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(uniformBuffer); | 
		
	
		
			
				|  |  |  |  | 		return 0; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer->offset = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Allocate a descriptor set for the uniform buffer */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (bufferPool->descriptorPool.availableDescriptorSetCount == 0) | 
		
	
	
		
			
				
					|  |  |  | @ -4294,6 +4353,7 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			&bufferPool->descriptorPool | 
		
	
		
			
				|  |  |  |  | 		)) { | 
		
	
		
			
				|  |  |  |  | 			Refresh_LogError("Failed to add uniform descriptor pool!"); | 
		
	
		
			
				|  |  |  |  | 			SDL_free(uniformBuffer); | 
		
	
		
			
				|  |  |  |  | 			return 0; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
	
		
			
				
					|  |  |  | @ -4303,7 +4363,7 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		bufferPool->descriptorPool.descriptorPools[bufferPool->descriptorPool.descriptorPoolCount - 1], | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		&buffer->descriptorSet | 
		
	
		
			
				|  |  |  |  | 		&uniformBuffer->descriptorSet | 
		
	
		
			
				|  |  |  |  | 	)) { | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Failed to allocate uniform descriptor set!"); | 
		
	
		
			
				|  |  |  |  | 		return 0; | 
		
	
	
		
			
				
					|  |  |  | @ -4321,7 +4381,7 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	bufferPool->availableBuffers[bufferPool->availableBufferCount] = buffer; | 
		
	
		
			
				|  |  |  |  | 	bufferPool->availableBuffers[bufferPool->availableBufferCount] = uniformBuffer; | 
		
	
		
			
				|  |  |  |  | 	bufferPool->availableBufferCount += 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return 1; | 
		
	
	
		
			
				
					|  |  |  | @ -4331,24 +4391,20 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 	VulkanRenderer *renderer, | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBufferType uniformBufferType | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorSetLayout descriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	VkWriteDescriptorSet writeDescriptorSet; | 
		
	
		
			
				|  |  |  |  | 	VkDescriptorBufferInfo descriptorBufferInfo; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (uniformBufferType == UNIFORM_BUFFER_VERTEX) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->vertexUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (uniformBufferType == UNIFORM_BUFFER_FRAGMENT) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->fragmentUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if (uniformBufferType == UNIFORM_BUFFER_COMPUTE) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER; | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout = renderer->computeUniformDescriptorSetLayout; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
	
		
			
				
					|  |  |  | @ -4357,17 +4413,9 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		return NULL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *buffer = SDL_malloc(sizeof(VulkanUniformBuffer)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer->vulkanBuffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE, | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		0 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 	buffer->offset = 0; | 
		
	
		
			
				|  |  |  |  | 	VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer)); | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->poolOffset = 0; | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->offset = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Allocate a descriptor set for the uniform buffer */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -4376,12 +4424,12 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer->defaultDescriptorPool, | 
		
	
		
			
				|  |  |  |  | 		descriptorSetLayout, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		&buffer->descriptorSet | 
		
	
		
			
				|  |  |  |  | 		&uniformBuffer->descriptorSet | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Update the descriptor set for the first and last time! */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.buffer = buffer->vulkanBuffer->buffer; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.buffer = renderer->dummyBuffer->buffer; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.offset = 0; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.range = VK_WHOLE_SIZE; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -4391,7 +4439,7 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.dstArrayElement = 0; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.dstBinding = 0; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.dstSet = buffer->descriptorSet; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.dstSet = uniformBuffer->descriptorSet; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.pBufferInfo = &descriptorBufferInfo; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.pImageInfo = NULL; | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.pTexelBufferView = NULL; | 
		
	
	
		
			
				
					|  |  |  | @ -4404,9 +4452,9 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		NULL | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer->pool = NULL; /* No pool because this is a dummy */ | 
		
	
		
			
				|  |  |  |  | 	uniformBuffer->pool = NULL; /* No pool because this is a dummy */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return buffer; | 
		
	
		
			
				|  |  |  |  | 	return uniformBuffer; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void VULKAN_INTERNAL_DestroyUniformBufferPool( | 
		
	
	
		
			
				
					|  |  |  | @ -4428,10 +4476,11 @@ static void VULKAN_INTERNAL_DestroyUniformBufferPool( | 
		
	
		
			
				|  |  |  |  | 	/* This is always destroyed after submissions, so all buffers are available */ | 
		
	
		
			
				|  |  |  |  | 	for (i = 0; i < uniformBufferPool->availableBufferCount; i += 1) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->availableBuffers[i]->vulkanBuffer); | 
		
	
		
			
				|  |  |  |  | 		SDL_free(uniformBufferPool->availableBuffers[i]); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->buffer); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	SDL_DestroyMutex(uniformBufferPool->lock); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(uniformBufferPool->availableBuffers); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(uniformBufferPool); | 
		
	
	
		
			
				
					|  |  |  | @ -4466,8 +4515,8 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_AcquireUniformBufferFromPool( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Update the descriptor set with the correct range */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.buffer = uniformBuffer->vulkanBuffer->buffer; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.offset = 0; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.buffer = uniformBuffer->pool->buffer->buffer; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.offset = uniformBuffer->poolOffset; | 
		
	
		
			
				|  |  |  |  | 	descriptorBufferInfo.range = blockSize; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; | 
		
	
	
		
			
				
					|  |  |  | @ -5106,6 +5155,7 @@ static void VULKAN_INTERNAL_EndCommandBuffer( | 
		
	
		
			
				|  |  |  |  | 		commandBuffer->computeUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			commandBuffer, | 
		
	
		
			
				|  |  |  |  | 			commandBuffer->computeUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -5146,9 +5196,7 @@ static void VULKAN_DestroyDevice( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->submittedCommandBuffers); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBuffer); | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyFragmentUniformBuffer->vulkanBuffer); | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyComputeUniformBuffer->vulkanBuffer); | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyBuffer); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->dummyVertexUniformBuffer); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->dummyFragmentUniformBuffer); | 
		
	
	
		
			
				
					|  |  |  | @ -5371,6 +5419,7 @@ static void VULKAN_DestroyDevice( | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->computePipelinesToDestroy); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->shaderModulesToDestroy); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->samplersToDestroy); | 
		
	
		
			
				|  |  |  |  | 	SDL_free(renderer->framebuffersToDestroy); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	SDL_DestroyMutex(renderer->allocatorLock); | 
		
	
		
			
				|  |  |  |  | 	SDL_DestroyMutex(renderer->disposeLock); | 
		
	
	
		
			
				
					|  |  |  | @ -7035,8 +7084,6 @@ static Refresh_Buffer* VULKAN_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 	Refresh_BufferUsageFlags usageFlags, | 
		
	
		
			
				|  |  |  |  | 	uint32_t sizeInBytes | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  | 	VulkanBufferContainer* bufferContainer; | 
		
	
		
			
				|  |  |  |  | 	VulkanBuffer* buffer; | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType resourceAccessType; | 
		
	
		
			
				|  |  |  |  | 	VkBufferUsageFlags vulkanUsageFlags = | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; | 
		
	
	
		
			
				
					|  |  |  | @ -7070,26 +7117,12 @@ static Refresh_Buffer* VULKAN_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	buffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		(VulkanRenderer*)driverData, | 
		
	
		
			
				|  |  |  |  | 	return (Refresh_Buffer*) VULKAN_INTERNAL_CreateBufferContainer( | 
		
	
		
			
				|  |  |  |  | 		(VulkanRenderer*) driverData, | 
		
	
		
			
				|  |  |  |  | 		sizeInBytes, | 
		
	
		
			
				|  |  |  |  | 		resourceAccessType, | 
		
	
		
			
				|  |  |  |  | 		vulkanUsageFlags, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		0 | 
		
	
		
			
				|  |  |  |  | 		vulkanUsageFlags | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (buffer == NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		Refresh_LogError("Failed to create buffer!"); | 
		
	
		
			
				|  |  |  |  | 		return NULL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	bufferContainer = SDL_malloc(sizeof(VulkanBufferContainer)); | 
		
	
		
			
				|  |  |  |  | 	bufferContainer->vulkanBuffer = buffer; | 
		
	
		
			
				|  |  |  |  | 	buffer->container = bufferContainer; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return (Refresh_Buffer*) bufferContainer; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /* Setters */ | 
		
	
	
		
			
				
					|  |  |  | @ -7170,6 +7203,7 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer( | 
		
	
		
			
				|  |  |  |  | 		RESOURCE_ACCESS_TRANSFER_READ_WRITE, | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, | 
		
	
		
			
				|  |  |  |  | 		1, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		1 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 	transferBuffer->fromPool = 0; | 
		
	
	
		
			
				
					|  |  |  | @ -7209,7 +7243,7 @@ static void VULKAN_SetTextureData( | 
		
	
		
			
				|  |  |  |  | 	VulkanTransferBuffer *transferBuffer; | 
		
	
		
			
				|  |  |  |  | 	VkBufferImageCopy imageCopy; | 
		
	
		
			
				|  |  |  |  | 	uint8_t *stagingBufferPointer; | 
		
	
		
			
				|  |  |  |  | 	uint32_t blockSize = VULKAN_INTERNAL_GetTextureBlockSize(vulkanTexture->format); | 
		
	
		
			
				|  |  |  |  | 	uint32_t blockSize = VULKAN_INTERNAL_TextureBlockSize(vulkanTexture->format); | 
		
	
		
			
				|  |  |  |  | 	uint32_t bufferRowLength; | 
		
	
		
			
				|  |  |  |  | 	uint32_t bufferImageHeight; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -7788,10 +7822,11 @@ static uint32_t VULKAN_PushVertexShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	if ( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer->offset + | 
		
	
		
			
				|  |  |  |  | 		graphicsPipeline->vertexUniformBlockSize >= | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE | 
		
	
		
			
				|  |  |  |  | 		UBO_SECTION_SIZE | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		/* We're out of space in this buffer, bind the old one and acquire a new one */ | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->vertexUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -7805,8 +7840,8 @@ static uint32_t VULKAN_PushVertexShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	offset = vulkanCommandBuffer->vertexUniformBuffer->offset; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_SetBufferData( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer->vulkanBuffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer->pool->buffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer->poolOffset + vulkanCommandBuffer->vertexUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		data, | 
		
	
		
			
				|  |  |  |  | 		dataLengthInBytes | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
	
		
			
				
					|  |  |  | @ -7831,10 +7866,11 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	if ( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer->offset + | 
		
	
		
			
				|  |  |  |  | 		graphicsPipeline->fragmentUniformBlockSize >= | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE | 
		
	
		
			
				|  |  |  |  | 		UBO_SECTION_SIZE | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		/* We're out of space in this buffer, bind the old one and acquire a new one */ | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->fragmentUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -7848,8 +7884,8 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	offset = vulkanCommandBuffer->fragmentUniformBuffer->offset; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_SetBufferData( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer->vulkanBuffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer->pool->buffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer->poolOffset + vulkanCommandBuffer->fragmentUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		data, | 
		
	
		
			
				|  |  |  |  | 		dataLengthInBytes | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
	
		
			
				
					|  |  |  | @ -7873,10 +7909,11 @@ static uint32_t VULKAN_PushComputeShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	if ( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer->offset + | 
		
	
		
			
				|  |  |  |  | 		computePipeline->uniformBlockSize >= | 
		
	
		
			
				|  |  |  |  | 		UBO_BUFFER_SIZE | 
		
	
		
			
				|  |  |  |  | 		UBO_SECTION_SIZE | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		/* We're out of space in this buffer, bind the old one and acquire a new one */ | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->computeUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -7890,8 +7927,8 @@ static uint32_t VULKAN_PushComputeShaderUniforms( | 
		
	
		
			
				|  |  |  |  | 	offset = vulkanCommandBuffer->computeUniformBuffer->offset; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	VULKAN_INTERNAL_SetBufferData( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer->vulkanBuffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer->pool->buffer, | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer->poolOffset + vulkanCommandBuffer->computeUniformBuffer->offset, | 
		
	
		
			
				|  |  |  |  | 		data, | 
		
	
		
			
				|  |  |  |  | 		dataLengthInBytes | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
	
		
			
				
					|  |  |  | @ -8816,7 +8853,7 @@ static void VULKAN_BeginRenderPass( | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_ImageMemoryBarrier( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->commandBuffer, | 
		
	
		
			
				|  |  |  |  | 			RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, | 
		
	
		
			
				|  |  |  |  | 			RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, | 
		
	
		
			
				|  |  |  |  | 			VK_IMAGE_ASPECT_COLOR_BIT, | 
		
	
		
			
				|  |  |  |  | 			0, | 
		
	
		
			
				|  |  |  |  | 			texture->layerCount, | 
		
	
	
		
			
				
					|  |  |  | @ -8849,7 +8886,7 @@ static void VULKAN_BeginRenderPass( | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_ImageMemoryBarrier( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->commandBuffer, | 
		
	
		
			
				|  |  |  |  | 			RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE, | 
		
	
		
			
				|  |  |  |  | 			RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_WRITE, | 
		
	
		
			
				|  |  |  |  | 			depthAspectFlags, | 
		
	
		
			
				|  |  |  |  | 			0, | 
		
	
		
			
				|  |  |  |  | 			texture->layerCount, | 
		
	
	
		
			
				
					|  |  |  | @ -8971,6 +9008,7 @@ static void VULKAN_EndRenderPass( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->vertexUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -8981,6 +9019,7 @@ static void VULKAN_EndRenderPass( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->fragmentUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -9066,6 +9105,7 @@ static void VULKAN_BindGraphicsPipeline( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->vertexUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->vertexUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -9088,6 +9128,7 @@ static void VULKAN_BindGraphicsPipeline( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->fragmentUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->fragmentUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -9219,6 +9260,7 @@ static void VULKAN_BindComputePipeline( | 
		
	
		
			
				|  |  |  |  | 		vulkanCommandBuffer->computeUniformBuffer != NULL | 
		
	
		
			
				|  |  |  |  | 	) { | 
		
	
		
			
				|  |  |  |  | 		VULKAN_INTERNAL_BindUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 			renderer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer, | 
		
	
		
			
				|  |  |  |  | 			vulkanCommandBuffer->computeUniformBuffer | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
	
		
			
				
					|  |  |  | @ -9756,6 +9798,11 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | 
		
	
		
			
				|  |  |  |  | 	VulkanPresentData *presentData; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	windowData = VULKAN_INTERNAL_FetchWindowData(windowHandle); | 
		
	
		
			
				|  |  |  |  | 	if (windowData == NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		return NULL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	swapchainData = windowData->swapchainData; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Window is claimed but swapchain is invalid! */ | 
		
	
	
		
			
				
					|  |  |  | @ -10509,7 +10556,6 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( | 
		
	
		
			
				|  |  |  |  | 	VkBufferCopy bufferCopy; | 
		
	
		
			
				|  |  |  |  | 	VkImageCopy *imageCopyRegions; | 
		
	
		
			
				|  |  |  |  | 	VulkanCommandBuffer *commandBuffer; | 
		
	
		
			
				|  |  |  |  | 	VkCommandBufferBeginInfo beginInfo; | 
		
	
		
			
				|  |  |  |  | 	uint32_t i, level; | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType copyResourceAccessType = RESOURCE_ACCESS_NONE; | 
		
	
		
			
				|  |  |  |  | 	VulkanResourceAccessType originalResourceAccessType; | 
		
	
	
		
			
				
					|  |  |  | @ -10519,11 +10565,6 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( | 
		
	
		
			
				|  |  |  |  | 	renderer->needDefrag = 0; | 
		
	
		
			
				|  |  |  |  | 	renderer->defragInProgress = 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | 
		
	
		
			
				|  |  |  |  | 	beginInfo.pNext = NULL; | 
		
	
		
			
				|  |  |  |  | 	beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; | 
		
	
		
			
				|  |  |  |  | 	beginInfo.pInheritanceInfo = NULL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	commandBuffer = (VulkanCommandBuffer*) VULKAN_AcquireCommandBuffer((Refresh_Renderer *) renderer); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (VULKAN_INTERNAL_FindAllocationToDefragment( | 
		
	
	
		
			
				
					|  |  |  | @ -10556,6 +10597,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( | 
		
	
		
			
				|  |  |  |  | 					currentRegion->vulkanBuffer->size, | 
		
	
		
			
				|  |  |  |  | 					RESOURCE_ACCESS_NONE, | 
		
	
		
			
				|  |  |  |  | 					currentRegion->vulkanBuffer->usage, | 
		
	
		
			
				|  |  |  |  | 					currentRegion->vulkanBuffer->requireHostVisible, | 
		
	
		
			
				|  |  |  |  | 					currentRegion->vulkanBuffer->preferDeviceLocal, | 
		
	
		
			
				|  |  |  |  | 					0 | 
		
	
		
			
				|  |  |  |  | 				); | 
		
	
	
		
			
				
					|  |  |  | @ -11528,6 +11570,9 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void VULKAN_INTERNAL_LoadEntryPoints(void) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	/* Required for MoltenVK support */ | 
		
	
		
			
				|  |  |  |  | 	SDL_setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Load Vulkan entry points */ | 
		
	
		
			
				|  |  |  |  | 	if (SDL_Vulkan_LoadLibrary(NULL) < 0) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
	
		
			
				
					|  |  |  | @ -11700,14 +11745,6 @@ static Refresh_Device* VULKAN_CreateDevice( | 
		
	
		
			
				|  |  |  |  | 		renderer->physicalDeviceDriverProperties.conformanceVersion.minor, | 
		
	
		
			
				|  |  |  |  | 		renderer->physicalDeviceDriverProperties.conformanceVersion.patch | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 	Refresh_LogWarn( | 
		
	
		
			
				|  |  |  |  | 		"\n" | 
		
	
		
			
				|  |  |  |  | 		"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" | 
		
	
		
			
				|  |  |  |  | 		"! Refresh Vulkan is still in development!	!\n" | 
		
	
		
			
				|  |  |  |  | 		"! The API is unstable and subject to change	!\n" | 
		
	
		
			
				|  |  |  |  | 		"! You have been warned!			!\n" | 
		
	
		
			
				|  |  |  |  | 		"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (!VULKAN_INTERNAL_CreateLogicalDevice( | 
		
	
		
			
				|  |  |  |  | 		renderer | 
		
	
	
		
			
				
					|  |  |  | @ -11963,6 +12000,16 @@ static Refresh_Device* VULKAN_CreateDevice( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Dummy Uniform Buffers */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	renderer->dummyBuffer = VULKAN_INTERNAL_CreateBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		16, | 
		
	
		
			
				|  |  |  |  | 		RESOURCE_ACCESS_GENERAL, | 
		
	
		
			
				|  |  |  |  | 		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		0, | 
		
	
		
			
				|  |  |  |  | 		1 | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	renderer->dummyVertexUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer( | 
		
	
		
			
				|  |  |  |  | 		renderer, | 
		
	
		
			
				|  |  |  |  | 		UNIFORM_BUFFER_VERTEX | 
		
	
	
		
			
				
					|  |  |  | @ -12076,6 +12123,7 @@ static Refresh_Device* VULKAN_CreateDevice( | 
		
	
		
			
				|  |  |  |  | 			RESOURCE_ACCESS_TRANSFER_READ_WRITE, | 
		
	
		
			
				|  |  |  |  | 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, | 
		
	
		
			
				|  |  |  |  | 			1, | 
		
	
		
			
				|  |  |  |  | 			0, | 
		
	
		
			
				|  |  |  |  | 			1 | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |