forked from MoonsideGames/Refresh
				
			cacheing descriptor set layouts and pipeline layouts
							parent
							
								
									1b22664756
								
							
						
					
					
						commit
						d23b2a6a75
					
				|  | @ -450,9 +450,7 @@ typedef struct REFRESH_ColorTargetBlendState | ||||||
| typedef struct REFRESH_PipelineLayoutCreateInfo | typedef struct REFRESH_PipelineLayoutCreateInfo | ||||||
| { | { | ||||||
| 	uint32_t vertexSamplerBindingCount; | 	uint32_t vertexSamplerBindingCount; | ||||||
| 	const uint32_t *vertexSamplerBindings; |  | ||||||
| 	uint32_t fragmentSamplerBindingCount; | 	uint32_t fragmentSamplerBindingCount; | ||||||
| 	const uint32_t *fragmentSamplerBindings; |  | ||||||
| } REFRESH_PipelineLayoutCreateInfo; | } REFRESH_PipelineLayoutCreateInfo; | ||||||
| 
 | 
 | ||||||
| typedef struct REFRESH_ColorTargetDescription | typedef struct REFRESH_ColorTargetDescription | ||||||
|  |  | ||||||
|  | @ -86,8 +86,27 @@ static uint32_t deviceExtensionCount = SDL_arraysize(deviceExtensionNames); | ||||||
| 	VK_COMPONENT_SWIZZLE_IDENTITY \ | 	VK_COMPONENT_SWIZZLE_IDENTITY \ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define NULL_DESC_LAYOUT (VkDescriptorSetLayout) 0 | ||||||
|  | #define NULL_PIPELINE_LAYOUT (VkPipelineLayout) 0 | ||||||
| #define NULL_RENDER_PASS (REFRESH_RenderPass*) 0 | #define NULL_RENDER_PASS (REFRESH_RenderPass*) 0 | ||||||
| 
 | 
 | ||||||
|  | #define EXPAND_ARRAY_IF_NEEDED(arr, initialValue, type)	\ | ||||||
|  | 	if (arr->count == arr->capacity)		\ | ||||||
|  | 	{						\ | ||||||
|  | 		if (arr->capacity == 0)			\ | ||||||
|  | 		{					\ | ||||||
|  | 			arr->capacity = initialValue;	\ | ||||||
|  | 		}					\ | ||||||
|  | 		else					\ | ||||||
|  | 		{					\ | ||||||
|  | 			arr->capacity *= 2;		\ | ||||||
|  | 		}					\ | ||||||
|  | 		arr->elements = (type*) SDL_realloc(	\ | ||||||
|  | 			arr->elements,			\ | ||||||
|  | 			arr->capacity * sizeof(type)	\ | ||||||
|  | 		);					\ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| /* Enums */ | /* Enums */ | ||||||
| 
 | 
 | ||||||
| typedef enum VulkanResourceAccessType | typedef enum VulkanResourceAccessType | ||||||
|  | @ -584,6 +603,8 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /* Memory structures */ | ||||||
|  | 
 | ||||||
| typedef struct VulkanBuffer VulkanBuffer; | typedef struct VulkanBuffer VulkanBuffer; | ||||||
| 
 | 
 | ||||||
| typedef struct VulkanSubBuffer | typedef struct VulkanSubBuffer | ||||||
|  | @ -630,16 +651,21 @@ typedef struct SwapChainSupportDetails | ||||||
| 	uint32_t presentModesLength; | 	uint32_t presentModesLength; | ||||||
| } SwapChainSupportDetails; | } SwapChainSupportDetails; | ||||||
| 
 | 
 | ||||||
| typedef struct VulkanGraphicsPipeline | typedef struct VulkanGraphicsPipelineLayout | ||||||
| { | { | ||||||
| 	VkPipeline pipeline; | 	VkPipelineLayout pipelineLayout; | ||||||
| 	VkPipelineLayout layout; |  | ||||||
| 	REFRESH_PrimitiveType primitiveType; |  | ||||||
| 	VkDescriptorPool descriptorPool; |  | ||||||
| 	VkDescriptorSetLayout vertexSamplerLayout; | 	VkDescriptorSetLayout vertexSamplerLayout; | ||||||
| 	uint32_t vertexSamplerBindingCount; | 	uint32_t vertexSamplerBindingCount; | ||||||
| 	VkDescriptorSetLayout fragmentSamplerLayout; | 	VkDescriptorSetLayout fragmentSamplerLayout; | ||||||
| 	uint32_t fragmentSamplerBindingCount; | 	uint32_t fragmentSamplerBindingCount; | ||||||
|  | 	VkDescriptorPool descriptorPool; | ||||||
|  | } VulkanGraphicsPipelineLayout; | ||||||
|  | 
 | ||||||
|  | typedef struct VulkanGraphicsPipeline | ||||||
|  | { | ||||||
|  | 	VkPipeline pipeline; | ||||||
|  | 	VulkanGraphicsPipelineLayout *pipelineLayout; | ||||||
|  | 	REFRESH_PrimitiveType primitiveType; | ||||||
| 	VkDescriptorSet vertexSamplerDescriptorSet; /* updated by SetVertexSamplers */ | 	VkDescriptorSet vertexSamplerDescriptorSet; /* updated by SetVertexSamplers */ | ||||||
| 	VkDescriptorSet fragmentSamplerDescriptorSet; /* updated by SetFragmentSamplers */ | 	VkDescriptorSet fragmentSamplerDescriptorSet; /* updated by SetFragmentSamplers */ | ||||||
| 
 | 
 | ||||||
|  | @ -701,6 +727,167 @@ typedef struct VulkanFramebuffer | ||||||
| 	VulkanDepthStencilTarget *depthStencilTarget; | 	VulkanDepthStencilTarget *depthStencilTarget; | ||||||
| } VulkanFramebuffer; | } VulkanFramebuffer; | ||||||
| 
 | 
 | ||||||
|  | /* Cache structures */ | ||||||
|  | 
 | ||||||
|  | typedef struct SamplerDescriptorSetLayoutHash | ||||||
|  | { | ||||||
|  | 	VkDescriptorType descriptorType; | ||||||
|  | 	uint32_t samplerBindingCount; | ||||||
|  | 	VkShaderStageFlagBits stageFlag; | ||||||
|  | } SamplerDescriptorSetLayoutHash; | ||||||
|  | 
 | ||||||
|  | typedef struct SamplerDescriptorSetLayoutHashMap | ||||||
|  | { | ||||||
|  | 	SamplerDescriptorSetLayoutHash key; | ||||||
|  | 	VkDescriptorSetLayout value; | ||||||
|  | } SamplerDescriptorSetLayoutHashMap; | ||||||
|  | 
 | ||||||
|  | typedef struct SamplerDescriptorSetLayoutHashArray | ||||||
|  | { | ||||||
|  | 	SamplerDescriptorSetLayoutHashMap *elements; | ||||||
|  | 	int32_t count; | ||||||
|  | 	int32_t capacity; | ||||||
|  | } SamplerDescriptorSetLayoutHashArray; | ||||||
|  | 
 | ||||||
|  | #define NUM_DESCRIPTOR_SET_LAYOUT_BUCKETS 1031 | ||||||
|  | 
 | ||||||
|  | typedef struct SamplerDescriptorSetLayoutHashTable | ||||||
|  | { | ||||||
|  | 	SamplerDescriptorSetLayoutHashArray buckets[NUM_DESCRIPTOR_SET_LAYOUT_BUCKETS]; | ||||||
|  | } SamplerDescriptorSetLayoutHashTable; | ||||||
|  | 
 | ||||||
|  | static inline uint64_t SamplerDescriptorSetLayoutHashTable_GetHashCode(SamplerDescriptorSetLayoutHash key) | ||||||
|  | { | ||||||
|  | 	const uint64_t HASH_FACTOR = 97; | ||||||
|  | 	uint64_t result = 1; | ||||||
|  | 	result = result * HASH_FACTOR + key.descriptorType; | ||||||
|  | 	result = result * HASH_FACTOR + key.samplerBindingCount; | ||||||
|  | 	result = result * HASH_FACTOR + key.stageFlag; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline VkDescriptorSetLayout SamplerDescriptorSetLayoutHashTable_Fetch( | ||||||
|  | 	SamplerDescriptorSetLayoutHashTable *table, | ||||||
|  | 	SamplerDescriptorSetLayoutHash key | ||||||
|  | ) { | ||||||
|  | 	int32_t i; | ||||||
|  | 	uint64_t hashcode = SamplerDescriptorSetLayoutHashTable_GetHashCode(key); | ||||||
|  | 	SamplerDescriptorSetLayoutHashArray *arr = &table->buckets[hashcode % NUM_DESCRIPTOR_SET_LAYOUT_BUCKETS]; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < arr->count; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		const SamplerDescriptorSetLayoutHash *e = &arr->elements[i].key; | ||||||
|  | 		if (    key.descriptorType == e->descriptorType && | ||||||
|  | 			key.samplerBindingCount == e->samplerBindingCount && | ||||||
|  | 			key.stageFlag == e->stageFlag   ) | ||||||
|  | 		{ | ||||||
|  | 			return arr->elements[i].value; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return VK_NULL_HANDLE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void SamplerDescriptorSetLayoutHashTable_Insert( | ||||||
|  | 	SamplerDescriptorSetLayoutHashTable *table, | ||||||
|  | 	SamplerDescriptorSetLayoutHash key, | ||||||
|  | 	VkDescriptorSetLayout value | ||||||
|  | ) { | ||||||
|  | 	uint64_t hashcode = SamplerDescriptorSetLayoutHashTable_GetHashCode(key); | ||||||
|  | 	SamplerDescriptorSetLayoutHashArray *arr = &table->buckets[hashcode % NUM_DESCRIPTOR_SET_LAYOUT_BUCKETS]; | ||||||
|  | 
 | ||||||
|  | 	SamplerDescriptorSetLayoutHashMap map; | ||||||
|  | 	map.key = key; | ||||||
|  | 	map.value = value; | ||||||
|  | 
 | ||||||
|  | 	EXPAND_ARRAY_IF_NEEDED(arr, 4, SamplerDescriptorSetLayoutHashMap); | ||||||
|  | 
 | ||||||
|  | 	arr->elements[arr->count] = map; | ||||||
|  | 	arr->count += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | typedef struct PipelineLayoutHash | ||||||
|  | { | ||||||
|  | 	VkDescriptorSetLayout vertexSamplerLayout; | ||||||
|  | 	VkDescriptorSetLayout fragmentSamplerLayout; | ||||||
|  | 	VkDescriptorSetLayout vertexUniformLayout; | ||||||
|  | 	VkDescriptorSetLayout fragmentUniformLayout; | ||||||
|  | } PipelineLayoutHash; | ||||||
|  | 
 | ||||||
|  | typedef struct PipelineLayoutHashMap | ||||||
|  | { | ||||||
|  | 	PipelineLayoutHash key; | ||||||
|  | 	VulkanGraphicsPipelineLayout *value; | ||||||
|  | } PipelineLayoutHashMap; | ||||||
|  | 
 | ||||||
|  | typedef struct PipelineLayoutHashArray | ||||||
|  | { | ||||||
|  | 	PipelineLayoutHashMap *elements; | ||||||
|  | 	int32_t count; | ||||||
|  | 	int32_t capacity; | ||||||
|  | } PipelineLayoutHashArray; | ||||||
|  | 
 | ||||||
|  | #define NUM_PIPELINE_LAYOUT_BUCKETS 1031 | ||||||
|  | 
 | ||||||
|  | typedef struct PipelineLayoutHashTable | ||||||
|  | { | ||||||
|  | 	PipelineLayoutHashArray buckets[NUM_PIPELINE_LAYOUT_BUCKETS]; | ||||||
|  | } PipelineLayoutHashTable; | ||||||
|  | 
 | ||||||
|  | static inline uint64_t PipelineLayoutHashTable_GetHashCode(PipelineLayoutHash key) | ||||||
|  | { | ||||||
|  | 	const uint64_t HASH_FACTOR = 97; | ||||||
|  | 	uint64_t result = 1; | ||||||
|  | 	result = result * HASH_FACTOR + (uint64_t) key.vertexSamplerLayout; | ||||||
|  | 	result = result * HASH_FACTOR + (uint64_t) key.fragmentSamplerLayout; | ||||||
|  | 	result = result * HASH_FACTOR + (uint64_t) key.vertexUniformLayout; | ||||||
|  | 	result = result * HASH_FACTOR + (uint64_t) key.fragmentUniformLayout; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline VulkanGraphicsPipelineLayout* PipelineLayoutHashArray_Fetch( | ||||||
|  | 	PipelineLayoutHashTable *table, | ||||||
|  | 	PipelineLayoutHash key | ||||||
|  | ) { | ||||||
|  | 	int32_t i; | ||||||
|  | 	uint64_t hashcode = PipelineLayoutHashTable_GetHashCode(key); | ||||||
|  | 	PipelineLayoutHashArray *arr = &table->buckets[hashcode % NUM_PIPELINE_LAYOUT_BUCKETS]; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < arr->count; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		const PipelineLayoutHash *e = &arr->elements[i].key; | ||||||
|  | 		if (	key.vertexSamplerLayout == e->vertexSamplerLayout && | ||||||
|  | 			key.fragmentSamplerLayout == e->fragmentSamplerLayout && | ||||||
|  | 			key.vertexUniformLayout == e->vertexUniformLayout && | ||||||
|  | 			key.fragmentUniformLayout == e->fragmentUniformLayout	) | ||||||
|  | 		{ | ||||||
|  | 			return arr->elements[i].value; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void PipelineLayoutHashArray_Insert( | ||||||
|  | 	PipelineLayoutHashTable *table, | ||||||
|  | 	PipelineLayoutHash key, | ||||||
|  | 	VulkanGraphicsPipelineLayout *value | ||||||
|  | ) { | ||||||
|  | 	uint64_t hashcode = PipelineLayoutHashTable_GetHashCode(key); | ||||||
|  | 	PipelineLayoutHashArray *arr = &table->buckets[hashcode % NUM_PIPELINE_LAYOUT_BUCKETS]; | ||||||
|  | 
 | ||||||
|  | 	PipelineLayoutHashMap map; | ||||||
|  | 	map.key = key; | ||||||
|  | 	map.value = value; | ||||||
|  | 
 | ||||||
|  | 	EXPAND_ARRAY_IF_NEEDED(arr, 4, PipelineLayoutHashMap) | ||||||
|  | 
 | ||||||
|  | 	arr->elements[arr->count] = map; | ||||||
|  | 	arr->count += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Context */ | ||||||
|  | 
 | ||||||
| typedef struct VulkanRenderer | typedef struct VulkanRenderer | ||||||
| { | { | ||||||
|     VkInstance instance; |     VkInstance instance; | ||||||
|  | @ -755,6 +942,9 @@ typedef struct VulkanRenderer | ||||||
| 
 | 
 | ||||||
| 	VulkanGraphicsPipeline *currentGraphicsPipeline; | 	VulkanGraphicsPipeline *currentGraphicsPipeline; | ||||||
| 
 | 
 | ||||||
|  | 	SamplerDescriptorSetLayoutHashTable samplerDescriptorSetLayoutHashTable; | ||||||
|  | 	PipelineLayoutHashTable pipelineLayoutHashTable; | ||||||
|  | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * TODO: we can get rid of this reference when we | 	 * TODO: we can get rid of this reference when we | ||||||
| 	 * come up with a clever descriptor set reuse system | 	 * come up with a clever descriptor set reuse system | ||||||
|  | @ -2276,7 +2466,7 @@ static void VULKAN_DrawInstancedPrimitives( | ||||||
| 	RECORD_CMD(renderer->vkCmdBindDescriptorSets( | 	RECORD_CMD(renderer->vkCmdBindDescriptorSets( | ||||||
| 		renderer->currentCommandBuffer, | 		renderer->currentCommandBuffer, | ||||||
| 		VK_PIPELINE_BIND_POINT_GRAPHICS, | 		VK_PIPELINE_BIND_POINT_GRAPHICS, | ||||||
| 		renderer->currentGraphicsPipeline->layout, | 		renderer->currentGraphicsPipeline->pipelineLayout->pipelineLayout, | ||||||
| 		0, | 		0, | ||||||
| 		4, | 		4, | ||||||
| 		descriptorSets, | 		descriptorSets, | ||||||
|  | @ -2340,7 +2530,7 @@ static void VULKAN_DrawPrimitives( | ||||||
| 	RECORD_CMD(renderer->vkCmdBindDescriptorSets( | 	RECORD_CMD(renderer->vkCmdBindDescriptorSets( | ||||||
| 		renderer->currentCommandBuffer, | 		renderer->currentCommandBuffer, | ||||||
| 		VK_PIPELINE_BIND_POINT_GRAPHICS, | 		VK_PIPELINE_BIND_POINT_GRAPHICS, | ||||||
| 		renderer->currentGraphicsPipeline->layout, | 		renderer->currentGraphicsPipeline->pipelineLayout->pipelineLayout, | ||||||
| 		0, | 		0, | ||||||
| 		4, | 		4, | ||||||
| 		descriptorSets, | 		descriptorSets, | ||||||
|  | @ -2567,7 +2757,6 @@ static REFRESH_RenderPass* VULKAN_CreateRenderPass( | ||||||
| 
 | 
 | ||||||
| static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool( | static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool( | ||||||
| 	VulkanRenderer *renderer, | 	VulkanRenderer *renderer, | ||||||
| 	REFRESH_PipelineLayoutCreateInfo *pipelineLayoutCreateInfo, |  | ||||||
| 	VkDescriptorPool *pDescriptorPool | 	VkDescriptorPool *pDescriptorPool | ||||||
| ) { | ) { | ||||||
| 	VkResult vulkanResult; | 	VkResult vulkanResult; | ||||||
|  | @ -2604,6 +2793,177 @@ static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool( | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static VkDescriptorSetLayout VULKAN_INTERNAL_FetchSamplerDescriptorSetLayout( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	VkShaderStageFlagBits shaderStageFlagBit, | ||||||
|  | 	uint32_t samplerBindingCount | ||||||
|  | ) { | ||||||
|  | 	SamplerDescriptorSetLayoutHash descriptorSetLayoutHash; | ||||||
|  | 	VkDescriptorSetLayout descriptorSetLayout; | ||||||
|  | 
 | ||||||
|  | 	VkDescriptorSetLayoutBinding setLayoutBindings[MAX_TEXTURE_SAMPLERS]; | ||||||
|  | 	VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo; | ||||||
|  | 
 | ||||||
|  | 	VkResult vulkanResult; | ||||||
|  | 	uint32_t i; | ||||||
|  | 
 | ||||||
|  | 	if (samplerBindingCount == 0) | ||||||
|  | 	{ | ||||||
|  | 		if (shaderStageFlagBit == VK_SHADER_STAGE_VERTEX_BIT) | ||||||
|  | 		{ | ||||||
|  | 			return renderer->emptyVertexSamplerLayout; | ||||||
|  | 		} | ||||||
|  | 		else if (shaderStageFlagBit == VK_SHADER_STAGE_FRAGMENT_BIT) | ||||||
|  | 		{ | ||||||
|  | 			return renderer->emptyFragmentSamplerLayout; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			REFRESH_LogError("Invalid shader stage flag bit: ", shaderStageFlagBit); | ||||||
|  | 			return NULL_DESC_LAYOUT; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	descriptorSetLayoutHash.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; | ||||||
|  | 	descriptorSetLayoutHash.stageFlag = shaderStageFlagBit; | ||||||
|  | 	descriptorSetLayoutHash.samplerBindingCount = samplerBindingCount; | ||||||
|  | 
 | ||||||
|  | 	descriptorSetLayout = SamplerDescriptorSetLayoutHashTable_Fetch( | ||||||
|  | 		&renderer->samplerDescriptorSetLayoutHashTable, | ||||||
|  | 		descriptorSetLayoutHash | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	if (descriptorSetLayout != VK_NULL_HANDLE) | ||||||
|  | 	{ | ||||||
|  | 		return descriptorSetLayout; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < samplerBindingCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		setLayoutBindings[i].binding = i; | ||||||
|  | 		setLayoutBindings[i].descriptorCount = 1; | ||||||
|  | 		setLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; | ||||||
|  | 		setLayoutBindings[i].stageFlags = shaderStageFlagBit; | ||||||
|  | 		setLayoutBindings[i].pImmutableSamplers = NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	setLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; | ||||||
|  | 	setLayoutCreateInfo.pNext = NULL; | ||||||
|  | 	setLayoutCreateInfo.flags = 0; | ||||||
|  | 	setLayoutCreateInfo.bindingCount = samplerBindingCount; | ||||||
|  | 	setLayoutCreateInfo.pBindings = setLayoutBindings; | ||||||
|  | 
 | ||||||
|  | 	vulkanResult = renderer->vkCreateDescriptorSetLayout( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		&setLayoutCreateInfo, | ||||||
|  | 		NULL, | ||||||
|  | 		&descriptorSetLayout | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	if (vulkanResult != VK_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 		LogVulkanResult("vkCreateDescriptorSetLayout", vulkanResult); | ||||||
|  | 		return NULL_DESC_LAYOUT; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SamplerDescriptorSetLayoutHashTable_Insert( | ||||||
|  | 		&renderer->samplerDescriptorSetLayoutHashTable, | ||||||
|  | 		descriptorSetLayoutHash, | ||||||
|  | 		descriptorSetLayout | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	return descriptorSetLayout; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static VulkanGraphicsPipelineLayout* VULKAN_INTERNAL_FetchGraphicsPipelineLayout( | ||||||
|  | 	VulkanRenderer *renderer, | ||||||
|  | 	uint32_t vertexSamplerBindingCount, | ||||||
|  | 	uint32_t fragmentSamplerBindingCount | ||||||
|  | ) { | ||||||
|  | 	VkDescriptorSetLayout setLayouts[4]; | ||||||
|  | 
 | ||||||
|  | 	PipelineLayoutHash pipelineLayoutHash; | ||||||
|  | 	VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo; | ||||||
|  | 	VkResult vulkanResult; | ||||||
|  | 
 | ||||||
|  | 	VulkanGraphicsPipelineLayout *vulkanGraphicsPipelineLayout; | ||||||
|  | 
 | ||||||
|  | 	pipelineLayoutHash.vertexSamplerLayout = VULKAN_INTERNAL_FetchSamplerDescriptorSetLayout( | ||||||
|  | 		renderer, | ||||||
|  | 		VK_SHADER_STAGE_VERTEX_BIT, | ||||||
|  | 		vertexSamplerBindingCount | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	pipelineLayoutHash.fragmentSamplerLayout = VULKAN_INTERNAL_FetchSamplerDescriptorSetLayout( | ||||||
|  | 		renderer, | ||||||
|  | 		VK_SHADER_STAGE_FRAGMENT_BIT, | ||||||
|  | 		fragmentSamplerBindingCount | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	pipelineLayoutHash.vertexUniformLayout = renderer->vertexParamLayout; | ||||||
|  | 	pipelineLayoutHash.fragmentUniformLayout = renderer->fragmentParamLayout; | ||||||
|  | 
 | ||||||
|  | 	vulkanGraphicsPipelineLayout = PipelineLayoutHashArray_Fetch( | ||||||
|  | 		&renderer->pipelineLayoutHashTable, | ||||||
|  | 		pipelineLayoutHash | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	if (vulkanGraphicsPipelineLayout != VK_NULL_HANDLE) | ||||||
|  | 	{ | ||||||
|  | 		return vulkanGraphicsPipelineLayout; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	vulkanGraphicsPipelineLayout = SDL_malloc(sizeof(VulkanGraphicsPipelineLayout)); | ||||||
|  | 
 | ||||||
|  | 	setLayouts[0] = pipelineLayoutHash.vertexSamplerLayout; | ||||||
|  | 	setLayouts[1] = pipelineLayoutHash.fragmentSamplerLayout; | ||||||
|  | 	setLayouts[2] = renderer->vertexParamLayout; | ||||||
|  | 	setLayouts[3] = renderer->fragmentParamLayout; | ||||||
|  | 
 | ||||||
|  | 	pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; | ||||||
|  | 	pipelineLayoutCreateInfo.pNext = NULL; | ||||||
|  | 	pipelineLayoutCreateInfo.flags = 0; | ||||||
|  | 	pipelineLayoutCreateInfo.setLayoutCount = 4; | ||||||
|  | 	pipelineLayoutCreateInfo.pSetLayouts = setLayouts; | ||||||
|  | 	pipelineLayoutCreateInfo.pushConstantRangeCount = 0; | ||||||
|  | 	pipelineLayoutCreateInfo.pPushConstantRanges = NULL; | ||||||
|  | 
 | ||||||
|  | 	vulkanResult = renderer->vkCreatePipelineLayout( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		&pipelineLayoutCreateInfo, | ||||||
|  | 		NULL, | ||||||
|  | 		&vulkanGraphicsPipelineLayout->pipelineLayout | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	if (vulkanResult != VK_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 		LogVulkanResult("vkCreatePipelineLayout", vulkanResult); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	PipelineLayoutHashArray_Insert( | ||||||
|  | 		&renderer->pipelineLayoutHashTable, | ||||||
|  | 		pipelineLayoutHash, | ||||||
|  | 		vulkanGraphicsPipelineLayout | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	vulkanGraphicsPipelineLayout->vertexSamplerLayout = pipelineLayoutHash.vertexSamplerLayout; | ||||||
|  | 	vulkanGraphicsPipelineLayout->vertexSamplerBindingCount = vertexSamplerBindingCount; | ||||||
|  | 	vulkanGraphicsPipelineLayout->fragmentSamplerLayout = pipelineLayoutHash.fragmentSamplerLayout; | ||||||
|  | 	vulkanGraphicsPipelineLayout->fragmentSamplerBindingCount = fragmentSamplerBindingCount; | ||||||
|  | 
 | ||||||
|  | 	/* Create sampler descriptor pool */ | ||||||
|  | 	if (!VULKAN_INTERNAL_CreateSamplerDescriptorPool( | ||||||
|  | 		renderer, | ||||||
|  | 		&vulkanGraphicsPipelineLayout->descriptorPool | ||||||
|  | 	)) { | ||||||
|  | 		REFRESH_LogError("Failed to create descriptor pool!"); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return vulkanGraphicsPipelineLayout; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 	REFRESH_Renderer *driverData, | 	REFRESH_Renderer *driverData, | ||||||
| 	REFRESH_GraphicsPipelineCreateInfo *pipelineCreateInfo | 	REFRESH_GraphicsPipelineCreateInfo *pipelineCreateInfo | ||||||
|  | @ -2640,20 +3000,6 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 		pipelineCreateInfo->colorBlendState.blendStateCount | 		pipelineCreateInfo->colorBlendState.blendStateCount | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo; |  | ||||||
| 	VkPipelineLayout pipelineLayout; |  | ||||||
| 	VkDescriptorSetLayout setLayouts[4]; |  | ||||||
| 	VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo; |  | ||||||
| 
 |  | ||||||
| 	VkDescriptorSetLayoutBinding *vertexSamplerLayoutBindings = SDL_stack_alloc( |  | ||||||
| 		VkDescriptorSetLayoutBinding, |  | ||||||
| 		pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount |  | ||||||
| 	); |  | ||||||
| 	VkDescriptorSetLayoutBinding *fragmentSamplerLayoutBindings = SDL_stack_alloc( |  | ||||||
| 		VkDescriptorSetLayoutBinding, |  | ||||||
| 		pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	VkDescriptorSetAllocateInfo vertexUBODescriptorAllocateInfo; | 	VkDescriptorSetAllocateInfo vertexUBODescriptorAllocateInfo; | ||||||
| 	VkDescriptorSetAllocateInfo fragmentUBODescriptorAllocateInfo; | 	VkDescriptorSetAllocateInfo fragmentUBODescriptorAllocateInfo; | ||||||
| 
 | 
 | ||||||
|  | @ -2732,6 +3078,8 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 		pipelineCreateInfo->topologyState.topology | 		pipelineCreateInfo->topologyState.topology | ||||||
| 	]; | 	]; | ||||||
| 
 | 
 | ||||||
|  | 	graphicsPipeline->primitiveType = pipelineCreateInfo->topologyState.topology; | ||||||
|  | 
 | ||||||
| 	/* Viewport */ | 	/* Viewport */ | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < pipelineCreateInfo->viewportState.viewportCount; i += 1) | 	for (i = 0; i < pipelineCreateInfo->viewportState.viewportCount; i += 1) | ||||||
|  | @ -2914,123 +3262,14 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 		pipelineCreateInfo->colorBlendState.blendConstants[3]; | 		pipelineCreateInfo->colorBlendState.blendConstants[3]; | ||||||
| 
 | 
 | ||||||
| 	/* Pipeline Layout */ | 	/* Pipeline Layout */ | ||||||
| 	/* TODO: should we hash these? */ |  | ||||||
| 
 | 
 | ||||||
| 	setLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; |  | ||||||
| 	setLayoutCreateInfo.pNext = NULL; |  | ||||||
| 	setLayoutCreateInfo.flags = 0; |  | ||||||
| 
 | 
 | ||||||
| 	/* Vertex sampler layout */ | 	graphicsPipeline->pipelineLayout = VULKAN_INTERNAL_FetchGraphicsPipelineLayout( | ||||||
| 	if (pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount == 0) | 		renderer, | ||||||
| 	{ | 		pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount, | ||||||
| 		setLayouts[0] = renderer->emptyVertexSamplerLayout; | 		pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		for (i = 0; i < pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount; i += 1) |  | ||||||
| 		{ |  | ||||||
| 			vertexSamplerLayoutBindings[i].binding = |  | ||||||
| 				pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindings[i]; |  | ||||||
| 			vertexSamplerLayoutBindings[i].descriptorCount = 1; |  | ||||||
| 			vertexSamplerLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |  | ||||||
| 			vertexSamplerLayoutBindings[i].stageFlags = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; |  | ||||||
| 			vertexSamplerLayoutBindings[i].pImmutableSamplers = NULL; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		setLayoutCreateInfo.bindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount; |  | ||||||
| 		setLayoutCreateInfo.pBindings = vertexSamplerLayoutBindings; |  | ||||||
| 
 |  | ||||||
| 		vulkanResult = renderer->vkCreateDescriptorSetLayout( |  | ||||||
| 			renderer->logicalDevice, |  | ||||||
| 			&setLayoutCreateInfo, |  | ||||||
| 			NULL, |  | ||||||
| 			&setLayouts[0] |  | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 		if (vulkanResult != VK_SUCCESS) |  | ||||||
| 		{ |  | ||||||
| 			LogVulkanResult("vkCreateDescriptorSetLayout", vulkanResult); |  | ||||||
| 			REFRESH_LogError("Failed to create vertex sampler layout!"); |  | ||||||
| 
 |  | ||||||
| 			SDL_stack_free(vertexInputBindingDescriptions); |  | ||||||
| 			SDL_stack_free(vertexInputAttributeDescriptions); |  | ||||||
| 			SDL_stack_free(viewports); |  | ||||||
| 			SDL_stack_free(scissors); |  | ||||||
| 			SDL_stack_free(colorBlendAttachmentStates); |  | ||||||
| 			SDL_stack_free(vertexSamplerLayoutBindings); |  | ||||||
| 			SDL_stack_free(fragmentSamplerLayoutBindings); |  | ||||||
| 			return NULL; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Frag sampler layout */ |  | ||||||
| 	if (pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount == 0) |  | ||||||
| 	{ |  | ||||||
| 		setLayouts[1] = renderer->emptyFragmentSamplerLayout; |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		for (i = 0; i < pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount; i += 1) |  | ||||||
| 		{ |  | ||||||
| 			fragmentSamplerLayoutBindings[i].binding = |  | ||||||
| 				pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindings[i]; |  | ||||||
| 			fragmentSamplerLayoutBindings[i].descriptorCount = 1; |  | ||||||
| 			fragmentSamplerLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |  | ||||||
| 			fragmentSamplerLayoutBindings[i].stageFlags = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; |  | ||||||
| 			fragmentSamplerLayoutBindings[i].pImmutableSamplers = NULL; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		setLayoutCreateInfo.bindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount; |  | ||||||
| 		setLayoutCreateInfo.pBindings = fragmentSamplerLayoutBindings; |  | ||||||
| 
 |  | ||||||
| 		vulkanResult = renderer->vkCreateDescriptorSetLayout( |  | ||||||
| 			renderer->logicalDevice, |  | ||||||
| 			&setLayoutCreateInfo, |  | ||||||
| 			NULL, |  | ||||||
| 			&setLayouts[1] |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		if (vulkanResult != VK_SUCCESS) |  | ||||||
| 		{ |  | ||||||
| 			LogVulkanResult("vkCreateDescriptorSetLayout", vulkanResult); |  | ||||||
| 			REFRESH_LogError("Failed to create fragment sampler layout!"); |  | ||||||
| 
 |  | ||||||
| 			SDL_stack_free(vertexInputBindingDescriptions); |  | ||||||
| 			SDL_stack_free(vertexInputAttributeDescriptions); |  | ||||||
| 			SDL_stack_free(viewports); |  | ||||||
| 			SDL_stack_free(scissors); |  | ||||||
| 			SDL_stack_free(colorBlendAttachmentStates); |  | ||||||
| 			SDL_stack_free(vertexSamplerLayoutBindings); |  | ||||||
| 			SDL_stack_free(fragmentSamplerLayoutBindings); |  | ||||||
| 			return NULL; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	setLayouts[2] = renderer->vertexParamLayout; |  | ||||||
| 	setLayouts[3] = renderer->fragmentParamLayout; |  | ||||||
| 
 |  | ||||||
| 	pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; |  | ||||||
| 	pipelineLayoutCreateInfo.pNext = NULL; |  | ||||||
| 	pipelineLayoutCreateInfo.flags = 0; |  | ||||||
| 	pipelineLayoutCreateInfo.pPushConstantRanges = NULL; |  | ||||||
| 	pipelineLayoutCreateInfo.pushConstantRangeCount = 0; |  | ||||||
| 	pipelineLayoutCreateInfo.setLayoutCount = 4; |  | ||||||
| 	pipelineLayoutCreateInfo.pSetLayouts = setLayouts; |  | ||||||
| 
 |  | ||||||
| 	vulkanResult = renderer->vkCreatePipelineLayout( |  | ||||||
| 		renderer->logicalDevice, |  | ||||||
| 		&pipelineLayoutCreateInfo, |  | ||||||
| 		NULL, |  | ||||||
| 		&pipelineLayout |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	graphicsPipeline->vertexSamplerLayout = setLayouts[0]; |  | ||||||
| 	graphicsPipeline->fragmentSamplerLayout = setLayouts[1]; |  | ||||||
| 	graphicsPipeline->vertexSamplerBindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount; |  | ||||||
| 	graphicsPipeline->fragmentSamplerBindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount; |  | ||||||
| 	graphicsPipeline->layout = pipelineLayout; |  | ||||||
| 	graphicsPipeline->primitiveType = pipelineCreateInfo->topologyState.topology; |  | ||||||
| 
 |  | ||||||
| 	/* Pipeline */ | 	/* Pipeline */ | ||||||
| 
 | 
 | ||||||
| 	vkPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | 	vkPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | ||||||
|  | @ -3047,7 +3286,7 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 	vkPipelineCreateInfo.pDepthStencilState = &depthStencilStateCreateInfo; | 	vkPipelineCreateInfo.pDepthStencilState = &depthStencilStateCreateInfo; | ||||||
| 	vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo; | 	vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo; | ||||||
| 	vkPipelineCreateInfo.pDynamicState = VK_NULL_HANDLE; | 	vkPipelineCreateInfo.pDynamicState = VK_NULL_HANDLE; | ||||||
| 	vkPipelineCreateInfo.layout = pipelineLayout; | 	vkPipelineCreateInfo.layout = graphicsPipeline->pipelineLayout->pipelineLayout; | ||||||
| 	vkPipelineCreateInfo.renderPass = (VkRenderPass) pipelineCreateInfo->renderPass; | 	vkPipelineCreateInfo.renderPass = (VkRenderPass) pipelineCreateInfo->renderPass; | ||||||
| 	vkPipelineCreateInfo.subpass = 0; | 	vkPipelineCreateInfo.subpass = 0; | ||||||
| 	vkPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; | 	vkPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; | ||||||
|  | @ -3086,23 +3325,6 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( | ||||||
| 	SDL_stack_free(vertexSamplerLayoutBindings); | 	SDL_stack_free(vertexSamplerLayoutBindings); | ||||||
| 	SDL_stack_free(fragmentSamplerLayoutBindings); | 	SDL_stack_free(fragmentSamplerLayoutBindings); | ||||||
| 
 | 
 | ||||||
| 	/* Create sampler descriptor pool */ |  | ||||||
| 	if (!VULKAN_INTERNAL_CreateSamplerDescriptorPool( |  | ||||||
| 		renderer, |  | ||||||
| 		&pipelineCreateInfo->pipelineLayoutCreateInfo, |  | ||||||
| 		&graphicsPipeline->descriptorPool |  | ||||||
| 	)) { |  | ||||||
| 		REFRESH_LogError("Failed to create descriptor pool!"); |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	renderer->descriptorPools = SDL_realloc( |  | ||||||
| 		renderer->descriptorPools, |  | ||||||
| 		renderer->descriptorPoolCount + 1 |  | ||||||
| 	); |  | ||||||
| 	renderer->descriptorPools[renderer->descriptorPoolCount + 1] = |  | ||||||
| 		graphicsPipeline->descriptorPool; |  | ||||||
| 
 |  | ||||||
| 	/* Allocate uniform buffer descriptors */ | 	/* Allocate uniform buffer descriptors */ | ||||||
| 
 | 
 | ||||||
| 	vertexUBODescriptorAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | 	vertexUBODescriptorAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | ||||||
|  | @ -4508,14 +4730,21 @@ static void VULKAN_SetVertexSamplers( | ||||||
| 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | ||||||
| 	VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; | 	VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; | ||||||
| 
 | 
 | ||||||
| 	writeDescriptorSets = SDL_stack_alloc(VkWriteDescriptorSet, graphicsPipeline->vertexSamplerBindingCount); | 	/* FIXME: this needs an abstraction */ | ||||||
| 	descriptorImageInfos = SDL_stack_alloc(VkDescriptorImageInfo, graphicsPipeline->vertexSamplerBindingCount); | 	writeDescriptorSets = SDL_stack_alloc( | ||||||
|  | 		VkWriteDescriptorSet, | ||||||
|  | 		graphicsPipeline->pipelineLayout->vertexSamplerBindingCount | ||||||
|  | 	); | ||||||
|  | 	descriptorImageInfos = SDL_stack_alloc( | ||||||
|  | 		VkDescriptorImageInfo, | ||||||
|  | 		graphicsPipeline->pipelineLayout->vertexSamplerBindingCount | ||||||
|  | 	); | ||||||
| 
 | 
 | ||||||
| 	descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | 	descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | ||||||
| 	descriptorSetAllocateInfo.pNext = NULL; | 	descriptorSetAllocateInfo.pNext = NULL; | ||||||
| 	descriptorSetAllocateInfo.descriptorSetCount = 1; | 	descriptorSetAllocateInfo.descriptorSetCount = 1; | ||||||
| 	descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->descriptorPool; | 	descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->pipelineLayout->descriptorPool; | ||||||
| 	descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->vertexSamplerLayout; | 	descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->pipelineLayout->vertexSamplerLayout; | ||||||
| 
 | 
 | ||||||
| 	renderer->vkAllocateDescriptorSets( | 	renderer->vkAllocateDescriptorSets( | ||||||
| 		renderer->logicalDevice, | 		renderer->logicalDevice, | ||||||
|  | @ -4523,7 +4752,7 @@ static void VULKAN_SetVertexSamplers( | ||||||
| 		&descriptorSet | 		&descriptorSet | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < graphicsPipeline->vertexSamplerBindingCount; i += 1) | 	for (i = 0; i < graphicsPipeline->pipelineLayout->vertexSamplerBindingCount; i += 1) | ||||||
| 	{ | 	{ | ||||||
| 		currentTexture = (VulkanTexture*) pTextures[i]; | 		currentTexture = (VulkanTexture*) pTextures[i]; | ||||||
| 		currentSampler = (VkSampler) pSamplers[i]; | 		currentSampler = (VkSampler) pSamplers[i]; | ||||||
|  | @ -4544,7 +4773,7 @@ static void VULKAN_SetVertexSamplers( | ||||||
| 
 | 
 | ||||||
| 	renderer->vkUpdateDescriptorSets( | 	renderer->vkUpdateDescriptorSets( | ||||||
| 		renderer->logicalDevice, | 		renderer->logicalDevice, | ||||||
| 		graphicsPipeline->vertexSamplerBindingCount, | 		graphicsPipeline->pipelineLayout->vertexSamplerBindingCount, | ||||||
| 		writeDescriptorSets, | 		writeDescriptorSets, | ||||||
| 		0, | 		0, | ||||||
| 		NULL | 		NULL | ||||||
|  | @ -4575,14 +4804,21 @@ static void VULKAN_SetFragmentSamplers( | ||||||
| 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | ||||||
| 	VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; | 	VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; | ||||||
| 
 | 
 | ||||||
| 	writeDescriptorSets = SDL_stack_alloc(VkWriteDescriptorSet, graphicsPipeline->fragmentSamplerBindingCount); | 	/* FIXME: this needs an abstraction */ | ||||||
| 	descriptorImageInfos = SDL_stack_alloc(VkDescriptorImageInfo, graphicsPipeline->fragmentSamplerBindingCount); | 	writeDescriptorSets = SDL_stack_alloc( | ||||||
|  | 		VkWriteDescriptorSet, | ||||||
|  | 		graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount | ||||||
|  | 	); | ||||||
|  | 	descriptorImageInfos = SDL_stack_alloc( | ||||||
|  | 		VkDescriptorImageInfo, | ||||||
|  | 		graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount | ||||||
|  | 	); | ||||||
| 
 | 
 | ||||||
| 	descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | 	descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | ||||||
| 	descriptorSetAllocateInfo.pNext = NULL; | 	descriptorSetAllocateInfo.pNext = NULL; | ||||||
| 	descriptorSetAllocateInfo.descriptorSetCount = 1; | 	descriptorSetAllocateInfo.descriptorSetCount = 1; | ||||||
| 	descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->descriptorPool; | 	descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->pipelineLayout->descriptorPool; | ||||||
| 	descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->fragmentSamplerLayout; | 	descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->pipelineLayout->fragmentSamplerLayout; | ||||||
| 
 | 
 | ||||||
| 	renderer->vkAllocateDescriptorSets( | 	renderer->vkAllocateDescriptorSets( | ||||||
| 		renderer->logicalDevice, | 		renderer->logicalDevice, | ||||||
|  | @ -4590,7 +4826,7 @@ static void VULKAN_SetFragmentSamplers( | ||||||
| 		&descriptorSet | 		&descriptorSet | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < graphicsPipeline->fragmentSamplerBindingCount; i += 1) | 	for (i = 0; i < graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount; i += 1) | ||||||
| 	{ | 	{ | ||||||
| 		currentTexture = (VulkanTexture*) pTextures[i]; | 		currentTexture = (VulkanTexture*) pTextures[i]; | ||||||
| 		currentSampler = (VkSampler) pSamplers[i]; | 		currentSampler = (VkSampler) pSamplers[i]; | ||||||
|  | @ -4611,7 +4847,7 @@ static void VULKAN_SetFragmentSamplers( | ||||||
| 
 | 
 | ||||||
| 	renderer->vkUpdateDescriptorSets( | 	renderer->vkUpdateDescriptorSets( | ||||||
| 		renderer->logicalDevice, | 		renderer->logicalDevice, | ||||||
| 		graphicsPipeline->fragmentSamplerBindingCount, | 		graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount, | ||||||
| 		writeDescriptorSets, | 		writeDescriptorSets, | ||||||
| 		0, | 		0, | ||||||
| 		NULL | 		NULL | ||||||
|  | @ -4842,12 +5078,12 @@ static void VULKAN_BindGraphicsPipeline( | ||||||
| 	VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline; | 	VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline; | ||||||
| 
 | 
 | ||||||
| 	/* bind dummy samplers */ | 	/* bind dummy samplers */ | ||||||
| 	if (pipeline->vertexSamplerBindingCount == 0) | 	if (pipeline->pipelineLayout->vertexSamplerBindingCount == 0) | ||||||
| 	{ | 	{ | ||||||
| 		pipeline->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet; | 		pipeline->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (pipeline->fragmentSamplerBindingCount == 0) | 	if (pipeline->pipelineLayout->fragmentSamplerBindingCount == 0) | ||||||
| 	{ | 	{ | ||||||
| 		pipeline->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet; | 		pipeline->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet; | ||||||
| 	} | 	} | ||||||
|  | @ -6370,6 +6606,22 @@ static REFRESH_Device* VULKAN_CreateDevice( | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/* Initialize caches */ | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		renderer->pipelineLayoutHashTable.buckets[i].elements = NULL; | ||||||
|  | 		renderer->pipelineLayoutHashTable.buckets[i].count = 0; | ||||||
|  | 		renderer->pipelineLayoutHashTable.buckets[i].capacity = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < NUM_DESCRIPTOR_SET_LAYOUT_BUCKETS; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		renderer->samplerDescriptorSetLayoutHashTable.buckets[i].elements = NULL; | ||||||
|  | 		renderer->samplerDescriptorSetLayoutHashTable.buckets[i].count = 0; | ||||||
|  | 		renderer->samplerDescriptorSetLayoutHashTable.buckets[i].capacity = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/* Descriptor Pools */ | 	/* Descriptor Pools */ | ||||||
| 
 | 
 | ||||||
| 	renderer->descriptorPools = NULL; | 	renderer->descriptorPools = NULL; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue