From 68f857fa5c2b1794823e2c1230eeefed842e1a8e Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 22 Feb 2022 14:19:25 -0800 Subject: [PATCH] remove descriptor set caching --- src/Refresh_Driver_Vulkan.c | 901 ++++++++---------------------------- 1 file changed, 190 insertions(+), 711 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index b69fb9c..a515d53 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -753,14 +753,13 @@ typedef struct SwapChainSupportDetails uint32_t presentModesLength; } SwapChainSupportDetails; -typedef struct BufferDescriptorSetCache BufferDescriptorSetCache; -typedef struct ImageDescriptorSetCache ImageDescriptorSetCache; +typedef struct DescriptorSetCache DescriptorSetCache; typedef struct VulkanGraphicsPipelineLayout { VkPipelineLayout pipelineLayout; - ImageDescriptorSetCache *vertexSamplerDescriptorSetCache; - ImageDescriptorSetCache *fragmentSamplerDescriptorSetCache; + DescriptorSetCache *vertexSamplerDescriptorSetCache; + DescriptorSetCache *fragmentSamplerDescriptorSetCache; } VulkanGraphicsPipelineLayout; typedef struct VulkanGraphicsPipeline @@ -775,8 +774,8 @@ typedef struct VulkanGraphicsPipeline typedef struct VulkanComputePipelineLayout { VkPipelineLayout pipelineLayout; - BufferDescriptorSetCache *bufferDescriptorSetCache; - ImageDescriptorSetCache *imageDescriptorSetCache; + DescriptorSetCache *bufferDescriptorSetCache; + DescriptorSetCache *imageDescriptorSetCache; } VulkanComputePipelineLayout; typedef struct VulkanComputePipeline @@ -910,118 +909,15 @@ static inline void DescriptorSetLayoutHashTable_Insert( /* Descriptor Set Caches */ -#define NUM_DESCRIPTOR_SET_HASH_BUCKETS 1031 - -typedef struct ImageDescriptorSetData -{ - VkDescriptorImageInfo descriptorImageInfo[MAX_TEXTURE_SAMPLERS]; /* used for vertex samplers as well */ -} ImageDescriptorSetData; - -typedef struct ImageDescriptorSetHashMap -{ - uint64_t key; - ImageDescriptorSetData descriptorSetData; - VkDescriptorSet descriptorSet; - uint8_t inactiveFrameCount; -} ImageDescriptorSetHashMap; - -typedef struct ImageDescriptorSetHashArray -{ - uint32_t *elements; - int32_t count; - int32_t capacity; -} ImageDescriptorSetHashArray; - -static inline uint64_t ImageDescriptorSetHashTable_GetHashCode( - ImageDescriptorSetData *descriptorSetData, - uint32_t samplerCount -) { - const uint64_t HASH_FACTOR = 97; - uint32_t i; - uint64_t result = 1; - - for (i = 0; i < samplerCount; i += 1) - { - result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorImageInfo[i].imageView; - result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorImageInfo[i].sampler; - } - - return result; -} - -struct ImageDescriptorSetCache +struct DescriptorSetCache { SDL_mutex *lock; VkDescriptorSetLayout descriptorSetLayout; uint32_t bindingCount; VkDescriptorType descriptorType; - ImageDescriptorSetHashArray buckets[NUM_DESCRIPTOR_SET_HASH_BUCKETS]; /* these buckets store indices */ - ImageDescriptorSetHashMap *elements; /* where the hash map elements are stored */ - uint32_t count; - uint32_t capacity; - - VkDescriptorPool *imageDescriptorPools; - uint32_t imageDescriptorPoolCount; - uint32_t nextPoolSize; - - VkDescriptorSet *inactiveDescriptorSets; - uint32_t inactiveDescriptorSetCount; - uint32_t inactiveDescriptorSetCapacity; -}; - -typedef struct BufferDescriptorSetData -{ - VkDescriptorBufferInfo descriptorBufferInfo[MAX_BUFFER_BINDINGS]; -} BufferDescriptorSetData; - -typedef struct BufferDescriptorSetHashMap -{ - uint64_t key; - BufferDescriptorSetData descriptorSetData; - VkDescriptorSet descriptorSet; - uint8_t inactiveFrameCount; -} BufferDescriptorSetHashMap; - -typedef struct BufferDescriptorSetHashArray -{ - uint32_t *elements; - int32_t count; - int32_t capacity; -} BufferDescriptorSetHashArray; - -static inline uint64_t BufferDescriptorSetHashTable_GetHashCode( - BufferDescriptorSetData *descriptorSetData, - uint32_t bindingCount -) { - const uint64_t HASH_FACTOR = 97; - uint32_t i; - uint64_t result = 1; - - for (i = 0; i < bindingCount; i += 1) - { - result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorBufferInfo[i].buffer; - result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorBufferInfo[i].offset; - result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorBufferInfo[i].range; - } - - return result; -} - -struct BufferDescriptorSetCache -{ - SDL_mutex *lock; - VkDescriptorSetLayout descriptorSetLayout; - uint32_t bindingCount; - VkDescriptorType descriptorType; - - BufferDescriptorSetHashArray buckets[NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - BufferDescriptorSetHashMap *elements; - uint32_t count; - uint32_t capacity; - - VkDescriptorPool *bufferDescriptorPools; - uint32_t bufferDescriptorPoolCount; + VkDescriptorPool *descriptorPools; + uint32_t descriptorPoolCount; uint32_t nextPoolSize; VkDescriptorSet *inactiveDescriptorSets; @@ -1188,6 +1084,12 @@ static inline void ComputePipelineLayoutHashArray_Insert( /* Command structures */ +typedef struct DescriptorSetData +{ + DescriptorSetCache *descriptorSetCache; + VkDescriptorSet descriptorSet; +} DescriptorSetData; + typedef struct VulkanTransferBuffer { VulkanBuffer* buffer; @@ -1243,6 +1145,10 @@ typedef struct VulkanCommandBuffer uint32_t boundUniformBufferCount; uint32_t boundUniformBufferCapacity; + DescriptorSetData *boundDescriptorSetDatas; + uint32_t boundDescriptorSetDataCount; + uint32_t boundDescriptorSetDataCapacity; + /* Deferred destroy storage */ VulkanRenderTarget **renderTargetsToDestroy; @@ -2479,7 +2385,9 @@ static void VULKAN_INTERNAL_DestroyCommandPool( { commandBuffer = commandPool->inactiveCommandBuffers[i]; + SDL_free(commandBuffer->transferBuffers); SDL_free(commandBuffer->boundUniformBuffers); + SDL_free(commandBuffer->boundDescriptorSetDatas); SDL_free(commandBuffer->renderTargetsToDestroy); SDL_free(commandBuffer->texturesToDestroy); SDL_free(commandBuffer->buffersToDestroy); @@ -2633,9 +2541,9 @@ static void VULKAN_INTERNAL_DestroySwapchain( SDL_free(swapchainData); } -static void VULKAN_INTERNAL_DestroyBufferDescriptorSetCache( +static void VULKAN_INTERNAL_DestroyDescriptorSetCache( VulkanRenderer *renderer, - BufferDescriptorSetCache *cache + DescriptorSetCache *cache ) { uint32_t i; @@ -2644,64 +2552,21 @@ static void VULKAN_INTERNAL_DestroyBufferDescriptorSetCache( return; } - for (i = 0; i < cache->bufferDescriptorPoolCount; i += 1) + for (i = 0; i < cache->descriptorPoolCount; i += 1) { renderer->vkDestroyDescriptorPool( renderer->logicalDevice, - cache->bufferDescriptorPools[i], + cache->descriptorPools[i], NULL ); } - SDL_free(cache->bufferDescriptorPools); + SDL_free(cache->descriptorPools); SDL_free(cache->inactiveDescriptorSets); - SDL_free(cache->elements); - - for (i = 0; i < NUM_DESCRIPTOR_SET_HASH_BUCKETS; i += 1) - { - SDL_free(cache->buckets[i].elements); - } - SDL_DestroyMutex(cache->lock); SDL_free(cache); } -static void VULKAN_INTERNAL_DestroyImageDescriptorSetCache( - VulkanRenderer *renderer, - ImageDescriptorSetCache *cache -) { - uint32_t i; - - if (cache == NULL) - { - return; - } - - for (i = 0; i < cache->imageDescriptorPoolCount; i += 1) - { - renderer->vkDestroyDescriptorPool( - renderer->logicalDevice, - cache->imageDescriptorPools[i], - NULL - ); - } - - SDL_free(cache->imageDescriptorPools); - SDL_free(cache->inactiveDescriptorSets); - SDL_free(cache->elements); - - for (i = 0; i < NUM_DESCRIPTOR_SET_HASH_BUCKETS; i += 1) - { - SDL_free(cache->buckets[i].elements); - } - - SDL_DestroyMutex(cache->lock); - SDL_free(cache); -} - -/* Buffer creation */ - - /* Descriptor cache stuff */ static uint8_t VULKAN_INTERNAL_CreateDescriptorPool( @@ -2782,112 +2647,47 @@ static uint8_t VULKAN_INTERNAL_AllocateDescriptorSets( return 1; } -static ImageDescriptorSetCache* VULKAN_INTERNAL_CreateImageDescriptorSetCache( +static DescriptorSetCache* VULKAN_INTERNAL_CreateDescriptorSetCache( VulkanRenderer *renderer, VkDescriptorType descriptorType, VkDescriptorSetLayout descriptorSetLayout, uint32_t bindingCount ) { - uint32_t i; - ImageDescriptorSetCache *imageDescriptorSetCache = SDL_malloc(sizeof(ImageDescriptorSetCache)); + DescriptorSetCache *descriptorSetCache = SDL_malloc(sizeof(DescriptorSetCache)); - imageDescriptorSetCache->lock = SDL_CreateMutex(); - imageDescriptorSetCache->elements = SDL_malloc(sizeof(ImageDescriptorSetHashMap) * 16); - imageDescriptorSetCache->count = 0; - imageDescriptorSetCache->capacity = 16; + descriptorSetCache->lock = SDL_CreateMutex(); - for (i = 0; i < NUM_DESCRIPTOR_SET_HASH_BUCKETS; i += 1) - { - imageDescriptorSetCache->buckets[i].elements = NULL; - imageDescriptorSetCache->buckets[i].count = 0; - imageDescriptorSetCache->buckets[i].capacity = 0; - } + descriptorSetCache->descriptorSetLayout = descriptorSetLayout; + descriptorSetCache->bindingCount = bindingCount; + descriptorSetCache->descriptorType = descriptorType; - imageDescriptorSetCache->descriptorSetLayout = descriptorSetLayout; - imageDescriptorSetCache->bindingCount = bindingCount; - imageDescriptorSetCache->descriptorType = descriptorType; - - imageDescriptorSetCache->imageDescriptorPools = SDL_malloc(sizeof(VkDescriptorPool)); - imageDescriptorSetCache->imageDescriptorPoolCount = 1; - imageDescriptorSetCache->nextPoolSize = DESCRIPTOR_POOL_STARTING_SIZE * 2; + descriptorSetCache->descriptorPools = SDL_malloc(sizeof(VkDescriptorPool)); + descriptorSetCache->descriptorPoolCount = 1; + descriptorSetCache->nextPoolSize = DESCRIPTOR_POOL_STARTING_SIZE * 2; VULKAN_INTERNAL_CreateDescriptorPool( renderer, descriptorType, DESCRIPTOR_POOL_STARTING_SIZE, DESCRIPTOR_POOL_STARTING_SIZE * bindingCount, - &imageDescriptorSetCache->imageDescriptorPools[0] + &descriptorSetCache->descriptorPools[0] ); - imageDescriptorSetCache->inactiveDescriptorSetCapacity = DESCRIPTOR_POOL_STARTING_SIZE; - imageDescriptorSetCache->inactiveDescriptorSetCount = DESCRIPTOR_POOL_STARTING_SIZE; - imageDescriptorSetCache->inactiveDescriptorSets = SDL_malloc( + descriptorSetCache->inactiveDescriptorSetCapacity = DESCRIPTOR_POOL_STARTING_SIZE; + descriptorSetCache->inactiveDescriptorSetCount = DESCRIPTOR_POOL_STARTING_SIZE; + descriptorSetCache->inactiveDescriptorSets = SDL_malloc( sizeof(VkDescriptorSet) * DESCRIPTOR_POOL_STARTING_SIZE ); VULKAN_INTERNAL_AllocateDescriptorSets( renderer, - imageDescriptorSetCache->imageDescriptorPools[0], - imageDescriptorSetCache->descriptorSetLayout, + descriptorSetCache->descriptorPools[0], + descriptorSetCache->descriptorSetLayout, DESCRIPTOR_POOL_STARTING_SIZE, - imageDescriptorSetCache->inactiveDescriptorSets + descriptorSetCache->inactiveDescriptorSets ); - return imageDescriptorSetCache; -} - -static BufferDescriptorSetCache* VULKAN_INTERNAL_CreateBufferDescriptorSetCache( - VulkanRenderer *renderer, - VkDescriptorType descriptorType, - VkDescriptorSetLayout descriptorSetLayout, - uint32_t bindingCount -) { - uint32_t i; - BufferDescriptorSetCache *bufferDescriptorSetCache = SDL_malloc(sizeof(BufferDescriptorSetCache)); - - bufferDescriptorSetCache->lock = SDL_CreateMutex(); - bufferDescriptorSetCache->elements = SDL_malloc(sizeof(BufferDescriptorSetHashMap) * 16); - bufferDescriptorSetCache->count = 0; - bufferDescriptorSetCache->capacity = 16; - - for (i = 0; i < NUM_DESCRIPTOR_SET_HASH_BUCKETS; i += 1) - { - bufferDescriptorSetCache->buckets[i].elements = NULL; - bufferDescriptorSetCache->buckets[i].count = 0; - bufferDescriptorSetCache->buckets[i].capacity = 0; - } - - bufferDescriptorSetCache->descriptorSetLayout = descriptorSetLayout; - bufferDescriptorSetCache->bindingCount = bindingCount; - bufferDescriptorSetCache->descriptorType = descriptorType; - - bufferDescriptorSetCache->bufferDescriptorPools = SDL_malloc(sizeof(VkDescriptorPool)); - bufferDescriptorSetCache->bufferDescriptorPoolCount = 1; - bufferDescriptorSetCache->nextPoolSize = DESCRIPTOR_POOL_STARTING_SIZE * 2; - - VULKAN_INTERNAL_CreateDescriptorPool( - renderer, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - DESCRIPTOR_POOL_STARTING_SIZE, - DESCRIPTOR_POOL_STARTING_SIZE * bindingCount, - &bufferDescriptorSetCache->bufferDescriptorPools[0] - ); - - bufferDescriptorSetCache->inactiveDescriptorSetCapacity = DESCRIPTOR_POOL_STARTING_SIZE; - bufferDescriptorSetCache->inactiveDescriptorSetCount = DESCRIPTOR_POOL_STARTING_SIZE; - bufferDescriptorSetCache->inactiveDescriptorSets = SDL_malloc( - sizeof(VkDescriptorSet) * DESCRIPTOR_POOL_STARTING_SIZE - ); - - VULKAN_INTERNAL_AllocateDescriptorSets( - renderer, - bufferDescriptorSetCache->bufferDescriptorPools[0], - bufferDescriptorSetCache->descriptorSetLayout, - DESCRIPTOR_POOL_STARTING_SIZE, - bufferDescriptorSetCache->inactiveDescriptorSets - ); - - return bufferDescriptorSetCache; + return descriptorSetCache; } static VkDescriptorSetLayout VULKAN_INTERNAL_FetchDescriptorSetLayout( @@ -3075,7 +2875,7 @@ static VulkanGraphicsPipelineLayout* VULKAN_INTERNAL_FetchGraphicsPipelineLayout else { vulkanGraphicsPipelineLayout->vertexSamplerDescriptorSetCache = - VULKAN_INTERNAL_CreateImageDescriptorSetCache( + VULKAN_INTERNAL_CreateDescriptorSetCache( renderer, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, pipelineLayoutHash.vertexSamplerLayout, @@ -3090,7 +2890,7 @@ static VulkanGraphicsPipelineLayout* VULKAN_INTERNAL_FetchGraphicsPipelineLayout else { vulkanGraphicsPipelineLayout->fragmentSamplerDescriptorSetCache = - VULKAN_INTERNAL_CreateImageDescriptorSetCache( + VULKAN_INTERNAL_CreateDescriptorSetCache( renderer, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, pipelineLayoutHash.fragmentSamplerLayout, @@ -3504,169 +3304,6 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_AcquireUniformBufferFromPool( return uniformBuffer; } -static void VULKAN_INTERNAL_DeactivateUnusedBufferDescriptorSets( - BufferDescriptorSetCache* bufferDescriptorSetCache -) { - int32_t i, j; - BufferDescriptorSetHashArray* arr; - - for (i = bufferDescriptorSetCache->count - 1; i >= 0; i -= 1) - { - bufferDescriptorSetCache->elements[i].inactiveFrameCount += 1; - - if (bufferDescriptorSetCache->elements[i].inactiveFrameCount + 1 > DESCRIPTOR_SET_DEACTIVATE_FRAMES) - { - arr = &bufferDescriptorSetCache->buckets[bufferDescriptorSetCache->elements[i].key % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - /* remove index from bucket */ - for (j = 0; j < arr->count; j += 1) - { - if (arr->elements[j] == i) - { - if (j < arr->count - 1) - { - arr->elements[j] = arr->elements[arr->count - 1]; - } - - arr->count -= 1; - break; - } - } - - /* remove element from table and place in inactive sets */ - - bufferDescriptorSetCache->inactiveDescriptorSets[bufferDescriptorSetCache->inactiveDescriptorSetCount] = bufferDescriptorSetCache->elements[i].descriptorSet; - bufferDescriptorSetCache->inactiveDescriptorSetCount += 1; - - /* move another descriptor set to fill the hole */ - if (i < bufferDescriptorSetCache->count - 1) - { - bufferDescriptorSetCache->elements[i] = bufferDescriptorSetCache->elements[bufferDescriptorSetCache->count - 1]; - - /* update index in bucket */ - arr = &bufferDescriptorSetCache->buckets[bufferDescriptorSetCache->elements[i].key % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - for (j = 0; j < arr->count; j += 1) - { - if (arr->elements[j] == bufferDescriptorSetCache->count - 1) - { - arr->elements[j] = i; - break; - } - } - } - - bufferDescriptorSetCache->count -= 1; - } - } -} - -static void VULKAN_INTERNAL_DeactivateUnusedImageDescriptorSets( - ImageDescriptorSetCache* imageDescriptorSetCache -) { - int32_t i, j; - ImageDescriptorSetHashArray* arr; - - for (i = imageDescriptorSetCache->count - 1; i >= 0; i -= 1) - { - imageDescriptorSetCache->elements[i].inactiveFrameCount += 1; - - if (imageDescriptorSetCache->elements[i].inactiveFrameCount + 1 > DESCRIPTOR_SET_DEACTIVATE_FRAMES) - { - arr = &imageDescriptorSetCache->buckets[imageDescriptorSetCache->elements[i].key % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - /* remove index from bucket */ - for (j = 0; j < arr->count; j += 1) - { - if (arr->elements[j] == i) - { - if (j < arr->count - 1) - { - arr->elements[j] = arr->elements[arr->count - 1]; - } - - arr->count -= 1; - break; - } - } - - /* remove element from table and place in inactive sets */ - - imageDescriptorSetCache->inactiveDescriptorSets[imageDescriptorSetCache->inactiveDescriptorSetCount] = imageDescriptorSetCache->elements[i].descriptorSet; - imageDescriptorSetCache->inactiveDescriptorSetCount += 1; - - /* move another descriptor set to fill the hole */ - if (i < imageDescriptorSetCache->count - 1) - { - imageDescriptorSetCache->elements[i] = imageDescriptorSetCache->elements[imageDescriptorSetCache->count - 1]; - - /* update index in bucket */ - arr = &imageDescriptorSetCache->buckets[imageDescriptorSetCache->elements[i].key % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - for (j = 0; j < arr->count; j += 1) - { - if (arr->elements[j] == imageDescriptorSetCache->count - 1) - { - arr->elements[j] = i; - break; - } - } - } - - imageDescriptorSetCache->count -= 1; - } - } -} - -/* FIXME: get rid of descriptor set caching */ -static void VULKAN_INTERNAL_ResetDescriptorSetData(VulkanRenderer* renderer) -{ - uint32_t i, j; - VulkanGraphicsPipelineLayout* graphicsPipelineLayout; - VulkanComputePipelineLayout* computePipelineLayout; - - for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1) - { - for (j = 0; j < renderer->graphicsPipelineLayoutHashTable.buckets[i].count; j += 1) - { - graphicsPipelineLayout = renderer->graphicsPipelineLayoutHashTable.buckets[i].elements[j].value; - - if (graphicsPipelineLayout->vertexSamplerDescriptorSetCache != NULL) - { - VULKAN_INTERNAL_DeactivateUnusedImageDescriptorSets( - graphicsPipelineLayout->vertexSamplerDescriptorSetCache - ); - } - - if (graphicsPipelineLayout->fragmentSamplerDescriptorSetCache != NULL) - { - VULKAN_INTERNAL_DeactivateUnusedImageDescriptorSets( - graphicsPipelineLayout->fragmentSamplerDescriptorSetCache - ); - } - } - - for (j = 0; j < renderer->computePipelineLayoutHashTable.buckets[i].count; j += 1) - { - computePipelineLayout = renderer->computePipelineLayoutHashTable.buckets[i].elements[j].value; - - if (computePipelineLayout->bufferDescriptorSetCache != NULL) - { - VULKAN_INTERNAL_DeactivateUnusedBufferDescriptorSets( - computePipelineLayout->bufferDescriptorSetCache - ); - } - - if (computePipelineLayout->imageDescriptorSetCache != NULL) - { - VULKAN_INTERNAL_DeactivateUnusedImageDescriptorSets( - computePipelineLayout->imageDescriptorSetCache - ); - } - } - } -} - /* Swapchain */ static uint8_t VULKAN_INTERNAL_QuerySwapChainSupport( @@ -4330,8 +3967,6 @@ static void VULKAN_INTERNAL_EndCommandBuffer( } } -/* Public API */ - static void VULKAN_DestroyDevice( Refresh_Device *device ) { @@ -4379,16 +4014,6 @@ static void VULKAN_DestroyDevice( graphicsPipelineLayoutHashArray = renderer->graphicsPipelineLayoutHashTable.buckets[i]; for (j = 0; j < graphicsPipelineLayoutHashArray.count; j += 1) { - VULKAN_INTERNAL_DestroyImageDescriptorSetCache( - renderer, - graphicsPipelineLayoutHashArray.elements[j].value->vertexSamplerDescriptorSetCache - ); - - VULKAN_INTERNAL_DestroyImageDescriptorSetCache( - renderer, - graphicsPipelineLayoutHashArray.elements[j].value->fragmentSamplerDescriptorSetCache - ); - renderer->vkDestroyPipelineLayout( renderer->logicalDevice, graphicsPipelineLayoutHashArray.elements[j].value->pipelineLayout, @@ -4404,12 +4029,12 @@ static void VULKAN_DestroyDevice( computePipelineLayoutHashArray = renderer->computePipelineLayoutHashTable.buckets[i]; for (j = 0; j < computePipelineLayoutHashArray.count; j += 1) { - VULKAN_INTERNAL_DestroyBufferDescriptorSetCache( + VULKAN_INTERNAL_DestroyDescriptorSetCache( renderer, computePipelineLayoutHashArray.elements[j].value->bufferDescriptorSetCache ); - VULKAN_INTERNAL_DestroyImageDescriptorSetCache( + VULKAN_INTERNAL_DestroyDescriptorSetCache( renderer, computePipelineLayoutHashArray.elements[j].value->imageDescriptorSetCache ); @@ -5470,7 +5095,7 @@ static VulkanComputePipelineLayout* VULKAN_INTERNAL_FetchComputePipelineLayout( else { vulkanComputePipelineLayout->bufferDescriptorSetCache = - VULKAN_INTERNAL_CreateBufferDescriptorSetCache( + VULKAN_INTERNAL_CreateDescriptorSetCache( renderer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, pipelineLayoutHash.bufferLayout, @@ -5485,7 +5110,7 @@ static VulkanComputePipelineLayout* VULKAN_INTERNAL_FetchComputePipelineLayout( else { vulkanComputePipelineLayout->imageDescriptorSetCache = - VULKAN_INTERNAL_CreateImageDescriptorSetCache( + VULKAN_INTERNAL_CreateDescriptorSetCache( renderer, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, pipelineLayoutHash.imageLayout, @@ -6890,325 +6515,133 @@ static uint32_t VULKAN_PushComputeShaderUniforms( return offset; } -static inline uint8_t BufferDescriptorSetDataEqual( - BufferDescriptorSetData *a, - BufferDescriptorSetData *b, - uint8_t bindingCount -) { - uint32_t i; - - for (i = 0; i < bindingCount; i += 1) - { - if ( a->descriptorBufferInfo[i].buffer != b->descriptorBufferInfo[i].buffer || - a->descriptorBufferInfo[i].offset != b->descriptorBufferInfo[i].offset || - a->descriptorBufferInfo[i].range != b->descriptorBufferInfo[i].range ) - { - return 0; - } - } - - return 1; -} - -/* FIXME: this can probably be cleverly folded into the same cache structure as image descriptors */ -static VkDescriptorSet VULKAN_INTERNAL_FetchBufferDescriptorSet( +/* If fetching an image descriptor, descriptorImageInfos must not be NULL. + * If fetching a buffer descriptor, descriptorBufferInfos must not be NULL. + */ +static VkDescriptorSet VULKAN_INTERNAL_FetchDescriptorSet( VulkanRenderer *renderer, - BufferDescriptorSetCache *bufferDescriptorSetCache, - BufferDescriptorSetData *bufferDescriptorSetData + VulkanCommandBuffer *vulkanCommandBuffer, + DescriptorSetCache *descriptorSetCache, + VkDescriptorImageInfo *descriptorImageInfos, /* Can be NULL */ + VkDescriptorBufferInfo *descriptorBufferInfos /* Can be NULL */ ) { uint32_t i; - uint64_t hashcode; - BufferDescriptorSetHashArray *arr; - VkDescriptorSet newDescriptorSet; - VkWriteDescriptorSet writeDescriptorSets[MAX_BUFFER_BINDINGS]; - BufferDescriptorSetHashMap *map; - - SDL_LockMutex(bufferDescriptorSetCache->lock); - hashcode = BufferDescriptorSetHashTable_GetHashCode( - bufferDescriptorSetData, - bufferDescriptorSetCache->bindingCount - ); - arr = &bufferDescriptorSetCache->buckets[hashcode % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - for (i = 0; i < arr->count; i += 1) - { - BufferDescriptorSetHashMap *e = &bufferDescriptorSetCache->elements[arr->elements[i]]; - if (BufferDescriptorSetDataEqual( - bufferDescriptorSetData, - &e->descriptorSetData, - bufferDescriptorSetCache->bindingCount - )) { - e->inactiveFrameCount = 0; - SDL_UnlockMutex(bufferDescriptorSetCache->lock); - return e->descriptorSet; - } - } - - /* If no match exists, assign a new descriptor set and prepare it for update */ - /* If no inactive descriptor sets remain, create a new pool and allocate new inactive sets */ - - if (bufferDescriptorSetCache->inactiveDescriptorSetCount == 0) - { - bufferDescriptorSetCache->bufferDescriptorPoolCount += 1; - bufferDescriptorSetCache->bufferDescriptorPools = SDL_realloc( - bufferDescriptorSetCache->bufferDescriptorPools, - sizeof(VkDescriptorPool) * bufferDescriptorSetCache->bufferDescriptorPoolCount - ); - - if (!VULKAN_INTERNAL_CreateDescriptorPool( - renderer, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - bufferDescriptorSetCache->nextPoolSize, - bufferDescriptorSetCache->nextPoolSize * bufferDescriptorSetCache->bindingCount, - &bufferDescriptorSetCache->bufferDescriptorPools[bufferDescriptorSetCache->bufferDescriptorPoolCount - 1] - )) { - SDL_UnlockMutex(bufferDescriptorSetCache->lock); - Refresh_LogError("Failed to create descriptor pool!"); - return VK_NULL_HANDLE; - } - - bufferDescriptorSetCache->inactiveDescriptorSetCapacity += bufferDescriptorSetCache->nextPoolSize; - - bufferDescriptorSetCache->inactiveDescriptorSets = SDL_realloc( - bufferDescriptorSetCache->inactiveDescriptorSets, - sizeof(VkDescriptorSet) * bufferDescriptorSetCache->inactiveDescriptorSetCapacity - ); - - if (!VULKAN_INTERNAL_AllocateDescriptorSets( - renderer, - bufferDescriptorSetCache->bufferDescriptorPools[bufferDescriptorSetCache->bufferDescriptorPoolCount - 1], - bufferDescriptorSetCache->descriptorSetLayout, - bufferDescriptorSetCache->nextPoolSize, - bufferDescriptorSetCache->inactiveDescriptorSets - )) { - SDL_UnlockMutex(bufferDescriptorSetCache->lock); - Refresh_LogError("Failed to allocate descriptor sets!"); - return VK_NULL_HANDLE; - } - - bufferDescriptorSetCache->inactiveDescriptorSetCount = bufferDescriptorSetCache->nextPoolSize; - - bufferDescriptorSetCache->nextPoolSize *= 2; - } - - newDescriptorSet = bufferDescriptorSetCache->inactiveDescriptorSets[bufferDescriptorSetCache->inactiveDescriptorSetCount - 1]; - bufferDescriptorSetCache->inactiveDescriptorSetCount -= 1; - - for (i = 0; i < bufferDescriptorSetCache->bindingCount; i += 1) - { - writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSets[i].pNext = NULL; - writeDescriptorSets[i].descriptorCount = 1; - writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - writeDescriptorSets[i].dstArrayElement = 0; - writeDescriptorSets[i].dstBinding = i; - writeDescriptorSets[i].dstSet = newDescriptorSet; - writeDescriptorSets[i].pBufferInfo = &bufferDescriptorSetData->descriptorBufferInfo[i]; - writeDescriptorSets[i].pImageInfo = NULL; - writeDescriptorSets[i].pTexelBufferView = NULL; - } - - renderer->vkUpdateDescriptorSets( - renderer->logicalDevice, - bufferDescriptorSetCache->bindingCount, - writeDescriptorSets, - 0, - NULL - ); - - EXPAND_ELEMENTS_IF_NEEDED(arr, 2, uint32_t) - arr->elements[arr->count] = bufferDescriptorSetCache->count; - arr->count += 1; - - if (bufferDescriptorSetCache->count == bufferDescriptorSetCache->capacity) - { - bufferDescriptorSetCache->capacity *= 2; - - bufferDescriptorSetCache->elements = SDL_realloc( - bufferDescriptorSetCache->elements, - sizeof(BufferDescriptorSetHashMap) * bufferDescriptorSetCache->capacity - ); - } - - map = &bufferDescriptorSetCache->elements[bufferDescriptorSetCache->count]; - map->key = hashcode; - - for (i = 0; i < bufferDescriptorSetCache->bindingCount; i += 1) - { - map->descriptorSetData.descriptorBufferInfo[i].buffer = - bufferDescriptorSetData->descriptorBufferInfo[i].buffer; - map->descriptorSetData.descriptorBufferInfo[i].offset = - bufferDescriptorSetData->descriptorBufferInfo[i].offset; - map->descriptorSetData.descriptorBufferInfo[i].range = - bufferDescriptorSetData->descriptorBufferInfo[i].range; - } - - map->descriptorSet = newDescriptorSet; - map->inactiveFrameCount = 0; - bufferDescriptorSetCache->count += 1; - - SDL_UnlockMutex(bufferDescriptorSetCache->lock); - return newDescriptorSet; -} - -static inline uint8_t ImageDescriptorSetDataEqual( - ImageDescriptorSetData *a, - ImageDescriptorSetData *b, - uint8_t bindingCount -) { - uint32_t i; - - for (i = 0; i < bindingCount; i += 1) - { - if ( a->descriptorImageInfo[i].imageLayout != b->descriptorImageInfo[i].imageLayout || - a->descriptorImageInfo[i].imageView != b->descriptorImageInfo[i].imageView || - a->descriptorImageInfo[i].sampler != b->descriptorImageInfo[i].sampler ) - { - return 0; - } - } - - return 1; -} - -static VkDescriptorSet VULKAN_INTERNAL_FetchImageDescriptorSet( - VulkanRenderer *renderer, - ImageDescriptorSetCache *imageDescriptorSetCache, - ImageDescriptorSetData *imageDescriptorSetData -) { - uint32_t i; - uint64_t hashcode; - ImageDescriptorSetHashArray *arr; - VkDescriptorSet newDescriptorSet; + VkDescriptorSet descriptorSet; VkWriteDescriptorSet writeDescriptorSets[MAX_TEXTURE_SAMPLERS]; - ImageDescriptorSetHashMap *map; + uint8_t isImage; - SDL_LockMutex(imageDescriptorSetCache->lock); - hashcode = ImageDescriptorSetHashTable_GetHashCode( - imageDescriptorSetData, - imageDescriptorSetCache->bindingCount - ); - arr = &imageDescriptorSetCache->buckets[hashcode % NUM_DESCRIPTOR_SET_HASH_BUCKETS]; - - for (i = 0; i < arr->count; i += 1) + if (descriptorImageInfos == NULL && descriptorBufferInfos == NULL) { - ImageDescriptorSetHashMap *e = &imageDescriptorSetCache->elements[arr->elements[i]]; - if (ImageDescriptorSetDataEqual( - imageDescriptorSetData, - &e->descriptorSetData, - imageDescriptorSetCache->bindingCount - )) { - e->inactiveFrameCount = 0; - SDL_UnlockMutex(imageDescriptorSetCache->lock); - return e->descriptorSet; - } + Refresh_LogError("descriptorImageInfos and descriptorBufferInfos cannot both be NULL!"); + return VK_NULL_HANDLE; + } + else if (descriptorImageInfos != NULL && descriptorBufferInfos != NULL) + { + Refresh_LogError("descriptorImageInfos and descriptorBufferInfos cannot both be set!"); + return VK_NULL_HANDLE; } - /* If no match exists, assign a new descriptor set and prepare it for update */ + isImage = descriptorImageInfos != NULL; + + SDL_LockMutex(descriptorSetCache->lock); + /* If no inactive descriptor sets remain, create a new pool and allocate new inactive sets */ - if (imageDescriptorSetCache->inactiveDescriptorSetCount == 0) + if (descriptorSetCache->inactiveDescriptorSetCount == 0) { - imageDescriptorSetCache->imageDescriptorPoolCount += 1; - imageDescriptorSetCache->imageDescriptorPools = SDL_realloc( - imageDescriptorSetCache->imageDescriptorPools, - sizeof(VkDescriptorPool) * imageDescriptorSetCache->imageDescriptorPoolCount + descriptorSetCache->descriptorPoolCount += 1; + descriptorSetCache->descriptorPools = SDL_realloc( + descriptorSetCache->descriptorPools, + sizeof(VkDescriptorPool) * descriptorSetCache->descriptorPoolCount ); if (!VULKAN_INTERNAL_CreateDescriptorPool( renderer, - imageDescriptorSetCache->descriptorType, - imageDescriptorSetCache->nextPoolSize, - imageDescriptorSetCache->nextPoolSize * imageDescriptorSetCache->bindingCount, - &imageDescriptorSetCache->imageDescriptorPools[imageDescriptorSetCache->imageDescriptorPoolCount - 1] + descriptorSetCache->descriptorType, + descriptorSetCache->nextPoolSize, + descriptorSetCache->nextPoolSize * descriptorSetCache->bindingCount, + &descriptorSetCache->descriptorPools[descriptorSetCache->descriptorPoolCount - 1] )) { - SDL_UnlockMutex(imageDescriptorSetCache->lock); + SDL_UnlockMutex(descriptorSetCache->lock); Refresh_LogError("Failed to create descriptor pool!"); return VK_NULL_HANDLE; } - imageDescriptorSetCache->inactiveDescriptorSetCapacity += imageDescriptorSetCache->nextPoolSize; + descriptorSetCache->inactiveDescriptorSetCapacity += descriptorSetCache->nextPoolSize; - imageDescriptorSetCache->inactiveDescriptorSets = SDL_realloc( - imageDescriptorSetCache->inactiveDescriptorSets, - sizeof(VkDescriptorSet) * imageDescriptorSetCache->inactiveDescriptorSetCapacity + descriptorSetCache->inactiveDescriptorSets = SDL_realloc( + descriptorSetCache->inactiveDescriptorSets, + sizeof(VkDescriptorSet) * descriptorSetCache->inactiveDescriptorSetCapacity ); if (!VULKAN_INTERNAL_AllocateDescriptorSets( renderer, - imageDescriptorSetCache->imageDescriptorPools[imageDescriptorSetCache->imageDescriptorPoolCount - 1], - imageDescriptorSetCache->descriptorSetLayout, - imageDescriptorSetCache->nextPoolSize, - imageDescriptorSetCache->inactiveDescriptorSets + descriptorSetCache->descriptorPools[descriptorSetCache->descriptorPoolCount - 1], + descriptorSetCache->descriptorSetLayout, + descriptorSetCache->nextPoolSize, + descriptorSetCache->inactiveDescriptorSets )) { - SDL_UnlockMutex(imageDescriptorSetCache->lock); + SDL_UnlockMutex(descriptorSetCache->lock); Refresh_LogError("Failed to allocate descriptor sets!"); return VK_NULL_HANDLE; } - imageDescriptorSetCache->inactiveDescriptorSetCount = imageDescriptorSetCache->nextPoolSize; + descriptorSetCache->inactiveDescriptorSetCount = descriptorSetCache->nextPoolSize; - imageDescriptorSetCache->nextPoolSize *= 2; + descriptorSetCache->nextPoolSize *= 2; } - newDescriptorSet = imageDescriptorSetCache->inactiveDescriptorSets[imageDescriptorSetCache->inactiveDescriptorSetCount - 1]; - imageDescriptorSetCache->inactiveDescriptorSetCount -= 1; + descriptorSet = descriptorSetCache->inactiveDescriptorSets[descriptorSetCache->inactiveDescriptorSetCount - 1]; + descriptorSetCache->inactiveDescriptorSetCount -= 1; - for (i = 0; i < imageDescriptorSetCache->bindingCount; i += 1) + for (i = 0; i < descriptorSetCache->bindingCount; i += 1) { writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSets[i].pNext = NULL; writeDescriptorSets[i].descriptorCount = 1; - writeDescriptorSets[i].descriptorType = imageDescriptorSetCache->descriptorType; + writeDescriptorSets[i].descriptorType = descriptorSetCache->descriptorType; writeDescriptorSets[i].dstArrayElement = 0; writeDescriptorSets[i].dstBinding = i; - writeDescriptorSets[i].dstSet = newDescriptorSet; - writeDescriptorSets[i].pBufferInfo = NULL; - writeDescriptorSets[i].pImageInfo = &imageDescriptorSetData->descriptorImageInfo[i]; + writeDescriptorSets[i].dstSet = descriptorSet; writeDescriptorSets[i].pTexelBufferView = NULL; + + if (isImage) + { + writeDescriptorSets[i].pImageInfo = &descriptorImageInfos[i]; + writeDescriptorSets[i].pBufferInfo = NULL; + + } + else + { + writeDescriptorSets[i].pBufferInfo = &descriptorBufferInfos[i]; + writeDescriptorSets[i].pImageInfo = NULL; + } } renderer->vkUpdateDescriptorSets( renderer->logicalDevice, - imageDescriptorSetCache->bindingCount, + descriptorSetCache->bindingCount, writeDescriptorSets, 0, NULL ); - EXPAND_ELEMENTS_IF_NEEDED(arr, 2, uint32_t) - arr->elements[arr->count] = imageDescriptorSetCache->count; - arr->count += 1; + SDL_UnlockMutex(descriptorSetCache->lock); - if (imageDescriptorSetCache->count == imageDescriptorSetCache->capacity) + if (vulkanCommandBuffer->boundDescriptorSetDataCount == vulkanCommandBuffer->boundDescriptorSetDataCapacity) { - imageDescriptorSetCache->capacity *= 2; - - imageDescriptorSetCache->elements = SDL_realloc( - imageDescriptorSetCache->elements, - sizeof(ImageDescriptorSetHashMap) * imageDescriptorSetCache->capacity + vulkanCommandBuffer->boundDescriptorSetDataCapacity *= 2; + vulkanCommandBuffer->boundDescriptorSetDatas = SDL_realloc( + vulkanCommandBuffer->boundDescriptorSetDatas, + vulkanCommandBuffer->boundDescriptorSetDataCapacity * sizeof(DescriptorSetData) ); } - map = &imageDescriptorSetCache->elements[imageDescriptorSetCache->count]; - map->key = hashcode; + vulkanCommandBuffer->boundDescriptorSetDatas[vulkanCommandBuffer->boundDescriptorSetDataCount].descriptorSet = descriptorSet; + vulkanCommandBuffer->boundDescriptorSetDatas[vulkanCommandBuffer->boundDescriptorSetDataCount].descriptorSetCache = descriptorSetCache; + vulkanCommandBuffer->boundDescriptorSetDataCount += 1; - for (i = 0; i < imageDescriptorSetCache->bindingCount; i += 1) - { - map->descriptorSetData.descriptorImageInfo[i].imageLayout = - imageDescriptorSetData->descriptorImageInfo[i].imageLayout; - map->descriptorSetData.descriptorImageInfo[i].imageView = - imageDescriptorSetData->descriptorImageInfo[i].imageView; - map->descriptorSetData.descriptorImageInfo[i].sampler = - imageDescriptorSetData->descriptorImageInfo[i].sampler; - } - - map->descriptorSet = newDescriptorSet; - map->inactiveFrameCount = 0; - imageDescriptorSetCache->count += 1; - - SDL_UnlockMutex(imageDescriptorSetCache->lock); - return newDescriptorSet; + return descriptorSet; } static void VULKAN_BindVertexSamplers( @@ -7223,7 +6656,7 @@ static void VULKAN_BindVertexSamplers( VulkanTexture *currentTexture; uint32_t i, samplerCount; - ImageDescriptorSetData vertexSamplerDescriptorSetData; + VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS]; if (graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL) { @@ -7235,15 +6668,17 @@ static void VULKAN_BindVertexSamplers( for (i = 0; i < samplerCount; i += 1) { currentTexture = (VulkanTexture*) pTextures[i]; - vertexSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view; - vertexSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i]; - vertexSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptorImageInfos[i].imageView = currentTexture->view; + descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; + descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchImageDescriptorSet( + vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( renderer, + vulkanCommandBuffer, graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache, - &vertexSamplerDescriptorSetData + descriptorImageInfos, + NULL ); } @@ -7256,10 +6691,10 @@ static void VULKAN_BindFragmentSamplers( VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline; - VulkanTexture *currentTexture; + VulkanTexture *currentTexture; uint32_t i, samplerCount; - ImageDescriptorSetData fragmentSamplerDescriptorSetData; + VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS]; if (graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL) { @@ -7271,15 +6706,17 @@ static void VULKAN_BindFragmentSamplers( for (i = 0; i < samplerCount; i += 1) { currentTexture = (VulkanTexture*) pTextures[i]; - fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view; - fragmentSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i]; - fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptorImageInfos[i].imageView = currentTexture->view; + descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; + descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchImageDescriptorSet( + vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( renderer, + vulkanCommandBuffer, graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache, - &fragmentSamplerDescriptorSetData + descriptorImageInfos, + NULL ); } @@ -7942,7 +7379,7 @@ static void VULKAN_BindComputeBuffers( VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; VulkanBuffer *currentVulkanBuffer; - BufferDescriptorSetData bufferDescriptorSetData; + VkDescriptorBufferInfo descriptorBufferInfos[MAX_BUFFER_BINDINGS]; uint32_t i; if (computePipeline->pipelineLayout->bufferDescriptorSetCache == NULL) @@ -7954,9 +7391,9 @@ static void VULKAN_BindComputeBuffers( { currentVulkanBuffer = (VulkanBuffer*) pBuffers[i]; - bufferDescriptorSetData.descriptorBufferInfo[i].buffer = currentVulkanBuffer->buffer; - bufferDescriptorSetData.descriptorBufferInfo[i].offset = 0; - bufferDescriptorSetData.descriptorBufferInfo[i].range = currentVulkanBuffer->size; + descriptorBufferInfos[i].buffer = currentVulkanBuffer->buffer; + descriptorBufferInfos[i].offset = 0; + descriptorBufferInfos[i].range = currentVulkanBuffer->size; vulkanCommandBuffer->boundComputeBuffers[i] = currentVulkanBuffer; } @@ -7964,10 +7401,12 @@ static void VULKAN_BindComputeBuffers( vulkanCommandBuffer->boundComputeBufferCount = computePipeline->pipelineLayout->bufferDescriptorSetCache->bindingCount; vulkanCommandBuffer->bufferDescriptorSet = - VULKAN_INTERNAL_FetchBufferDescriptorSet( + VULKAN_INTERNAL_FetchDescriptorSet( renderer, + vulkanCommandBuffer, computePipeline->pipelineLayout->bufferDescriptorSetCache, - &bufferDescriptorSetData + NULL, + descriptorBufferInfos ); } @@ -7981,7 +7420,7 @@ static void VULKAN_BindComputeTextures( VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; VulkanTexture *currentTexture; - ImageDescriptorSetData imageDescriptorSetData; + VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS]; uint32_t i; if (computePipeline->pipelineLayout->imageDescriptorSetCache == NULL) @@ -7992,16 +7431,18 @@ static void VULKAN_BindComputeTextures( for (i = 0; i < computePipeline->pipelineLayout->imageDescriptorSetCache->bindingCount; i += 1) { currentTexture = (VulkanTexture*) pTextures[i]; - imageDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view; - imageDescriptorSetData.descriptorImageInfo[i].sampler = VK_NULL_HANDLE; - imageDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptorImageInfos[i].imageView = currentTexture->view; + descriptorImageInfos[i].sampler = VK_NULL_HANDLE; + descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } vulkanCommandBuffer->imageDescriptorSet = - VULKAN_INTERNAL_FetchImageDescriptorSet( + VULKAN_INTERNAL_FetchDescriptorSet( renderer, + vulkanCommandBuffer, computePipeline->pipelineLayout->imageDescriptorSetCache, - &imageDescriptorSetData + descriptorImageInfos, + NULL ); } @@ -8183,6 +7624,14 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->boundUniformBufferCapacity * sizeof(VulkanUniformBuffer*) ); + /* Descriptor set tracking */ + + commandBuffer->boundDescriptorSetDataCapacity = 16; + commandBuffer->boundDescriptorSetDataCount = 0; + commandBuffer->boundDescriptorSetDatas = SDL_malloc( + commandBuffer->boundDescriptorSetDataCapacity * sizeof(DescriptorSetData) + ); + /* Deferred destroy storage */ commandBuffer->renderTargetsToDestroyCapacity = 16; @@ -8439,6 +7888,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( uint32_t i; VulkanUniformBuffer *uniformBuffer; VkResult result; + DescriptorSetData *descriptorSetData; result = renderer->vkResetCommandBuffer( commandBuffer->commandBuffer, @@ -8497,6 +7947,31 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( commandBuffer->transferBufferCount = 0; + /* Bound descriptor sets are now available */ + + for (i = 0; i < commandBuffer->boundDescriptorSetDataCount; i += 1) + { + descriptorSetData = &commandBuffer->boundDescriptorSetDatas[i]; + + SDL_LockMutex(descriptorSetData->descriptorSetCache->lock); + + if (descriptorSetData->descriptorSetCache->inactiveDescriptorSetCount == descriptorSetData->descriptorSetCache->inactiveDescriptorSetCapacity) + { + descriptorSetData->descriptorSetCache->inactiveDescriptorSetCapacity *= 2; + descriptorSetData->descriptorSetCache->inactiveDescriptorSets = SDL_realloc( + descriptorSetData->descriptorSetCache->inactiveDescriptorSets, + descriptorSetData->descriptorSetCache->inactiveDescriptorSetCapacity * sizeof(VkDescriptorSet) + ); + } + + descriptorSetData->descriptorSetCache->inactiveDescriptorSets[descriptorSetData->descriptorSetCache->inactiveDescriptorSetCount] = descriptorSetData->descriptorSet; + descriptorSetData->descriptorSetCache->inactiveDescriptorSetCount += 1; + + SDL_UnlockMutex(descriptorSetData->descriptorSetCache->lock); + } + + commandBuffer->boundDescriptorSetDataCount = 0; + /* Perform pending destroys */ for (i = 0; i < commandBuffer->renderTargetsToDestroyCount; i += 1) @@ -9072,6 +8547,10 @@ static uint8_t VULKAN_INTERNAL_CreateInstance( Refresh_LogWarn("Validation layers not found, continuing without validation"); createInfo.enabledLayerCount = 0; } + else + { + Refresh_LogInfo("Validation layers enabled, expect debug level performance!"); + } } else {