on nvidia GPUs allow for dynamic descriptor allocation

This commit is contained in:
Gregory Wells
2025-06-16 10:51:56 -04:00
parent b12cc38386
commit b3bd2209be
4 changed files with 82 additions and 42 deletions

View File

@@ -32,6 +32,10 @@ gnReturnCode gnCreateOutputDeviceFn(gnOutputDeviceHandle outputDevice, gnInstanc
}; };
deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, deviceInfo.physicalDevice.physicalDevice->device); deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, deviceInfo.physicalDevice.physicalDevice->device);
outputDevice->outputDevice->enabledOversizedDescriptorPools = gnFalse;
for (int i = 0; i < deviceCreateInfo.enabledExtensionCount; i++)
if (strcmp(deviceCreateInfo.ppEnabledExtensionNames[i], VK_NV_DESCRIPTOR_POOL_OVERALLOCATION_EXTENSION_NAME) == 0) outputDevice->outputDevice->enabledOversizedDescriptorPools = gnTrue;
if (instance->debugger == NULL) if (instance->debugger == NULL)
deviceCreateInfo.enabledLayerCount = 0; deviceCreateInfo.enabledLayerCount = 0;
else { else {

View File

@@ -9,6 +9,8 @@ typedef struct gnPlatformOutputDevice_t {
VkQueue transferQueue; VkQueue transferQueue;
VkCommandPool transferCommandPool; VkCommandPool transferCommandPool;
gnBool enabledOversizedDescriptorPools;
} gnPlatformOutputDevice; } gnPlatformOutputDevice;
VkCommandBuffer gnBeginVulkanTransferOperation(gnDevice device); VkCommandBuffer gnBeginVulkanTransferOperation(gnDevice device);

View File

@@ -9,58 +9,94 @@
gnReturnCode gnCreateUniformPoolFn(gnUniformPool pool, gnDeviceHandle device) { gnReturnCode gnCreateUniformPoolFn(gnUniformPool pool, gnDeviceHandle device) {
pool->uniformPool = malloc(sizeof(struct gnPlatformUniformPool_t)); pool->uniformPool = malloc(sizeof(struct gnPlatformUniformPool_t));
pool->uniformPool->poolCount = 0; pool->uniformPool->poolCount = 0;
pool->uniformPool->maxPoolCount = 1; pool->uniformPool->maxPoolCount = 2;
pool->uniformPool->pools = malloc(sizeof(vkGryphnUniformPool) * pool->uniformPool->maxPoolCount); pool->uniformPool->pools = malloc(sizeof(vkGryphnUniformPool) * pool->uniformPool->maxPoolCount);
if (device->outputDevice->enabledOversizedDescriptorPools == gnTrue) {
VkDescriptorPoolCreateInfo poolInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_ALLOW_OVERALLOCATION_SETS_BIT_NV,
.poolSizeCount = 0,
.pPoolSizes = NULL,
.maxSets = 0
};
if (vkCreateDescriptorPool(
pool->device->outputDevice->device, &poolInfo, NULL,
&pool->uniformPool->pools[pool->uniformPool->poolCount].pool
) != VK_SUCCESS)
return GN_FAILED_TO_ALLOCATE_MEMORY;
pool->uniformPool->poolCount = 1;
}
pool->uniformPool->currentPool = 0;
return GN_SUCCESS; return GN_SUCCESS;
} }
gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, gnUniformAllocationInfo allocInfo) { gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, gnUniformAllocationInfo allocInfo) {
if (pool->uniformPool->poolCount >= pool->uniformPool->maxPoolCount) { gnBool fixedAllocCount = pool->device->outputDevice->enabledOversizedDescriptorPools;
pool->uniformPool->maxPoolCount *= 2;
pool->uniformPool->pools = realloc(pool->uniformPool->pools, sizeof(vkGryphnUniformPool) * pool->uniformPool->maxPoolCount);
}
pool->uniformPool->pools[pool->uniformPool->poolCount].layouts = malloc(sizeof(VkDescriptorSetLayout) * allocInfo.setCount); if (fixedAllocCount) {
pool->uniformPool->pools[pool->uniformPool->poolCount].layoutCount = allocInfo.setCount; if (pool->uniformPool->poolCount >= pool->uniformPool->maxPoolCount) {
VkDescriptorPoolSize uniformBufferSize = { pool->uniformPool->maxPoolCount *= 2;
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pool->uniformPool->pools = realloc(pool->uniformPool->pools, sizeof(vkGryphnUniformPool) * pool->uniformPool->maxPoolCount);
.descriptorCount = 0
};
VkDescriptorPoolSize imageSize = {
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 0
};
for (int i = 0; i < allocInfo.setCount; i++) {
for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) {
if (allocInfo.sets[i].uniformBindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) uniformBufferSize.descriptorCount++;
if (allocInfo.sets[i].uniformBindings[i].type == GN_IMAGE_DESCRIPTOR) imageSize.descriptorCount++;
} }
pool->uniformPool->pools[pool->uniformPool->poolCount].layouts[i] = vkGryphnCreateSetLayouts(&allocInfo.sets[i], pool->device->outputDevice->device);
VkDescriptorPoolSize uniformBufferSize = {
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 0
};
VkDescriptorPoolSize imageSize = {
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 0
};
for (int i = 0; i < allocInfo.setCount; i++) {
for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) {
if (allocInfo.sets[i].uniformBindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) uniformBufferSize.descriptorCount++;
if (allocInfo.sets[i].uniformBindings[i].type == GN_IMAGE_DESCRIPTOR) imageSize.descriptorCount++;
}
}
VkDescriptorPoolCreateInfo poolInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.poolSizeCount = 1,
.pPoolSizes = (VkDescriptorPoolSize[]){ uniformBufferSize, imageSize },
.maxSets = allocInfo.setCount
};
if (vkCreateDescriptorPool(
pool->device->outputDevice->device, &poolInfo, NULL,
&pool->uniformPool->pools[pool->uniformPool->poolCount].pool
) != VK_SUCCESS)
return NULL;
pool->uniformPool->poolCount++;
uint32_t maxSets = uniformBufferSize.descriptorCount + uniformBufferSize.descriptorCount;
} }
uint32_t maxSets = uniformBufferSize.descriptorCount + uniformBufferSize.descriptorCount; if (fixedAllocCount)
pool->uniformPool->pools[pool->uniformPool->currentPool].layouts = malloc(sizeof(VkDescriptorSetLayout) * allocInfo.setCount);
VkDescriptorPoolCreateInfo poolInfo = { else
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, pool->uniformPool->pools[pool->uniformPool->currentPool].layouts = realloc(
.poolSizeCount = 1, pool->uniformPool->pools[pool->uniformPool->currentPool].layouts,
.pPoolSizes = (VkDescriptorPoolSize[]){ uniformBufferSize, imageSize }, sizeof(VkDescriptorSetLayout) * (allocInfo.setCount + pool->uniformPool->pools[pool->uniformPool->currentPool].layoutCount));
.maxSets = maxSets for (int i = 0; i < allocInfo.setCount; i++) {
}; pool->uniformPool->pools[pool->uniformPool->currentPool].layouts[pool->uniformPool->pools[pool->uniformPool->currentPool].layoutCount + i] = vkGryphnCreateSetLayouts(&allocInfo.sets[i], pool->device->outputDevice->device);
}
if (vkCreateDescriptorPool(
pool->device->outputDevice->device, &poolInfo, NULL,
&pool->uniformPool->pools[pool->uniformPool->poolCount].pool
) != VK_SUCCESS)
return NULL;
VkDescriptorSetAllocateInfo vkAllocInfo = { VkDescriptorSetAllocateInfo vkAllocInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = pool->uniformPool->pools[pool->uniformPool->poolCount].pool, .descriptorPool = pool->uniformPool->pools[pool->uniformPool->currentPool].pool,
.descriptorSetCount = allocInfo.setCount, .descriptorSetCount = allocInfo.setCount,
.pSetLayouts = pool->uniformPool->pools[pool->uniformPool->poolCount].layouts .pSetLayouts = &pool->uniformPool->pools[pool->uniformPool->currentPool].layouts[pool->uniformPool->pools[pool->uniformPool->currentPool].layoutCount]
}; };
pool->uniformPool->pools[pool->uniformPool->currentPool].layoutCount += allocInfo.setCount;
VkDescriptorSet* sets = malloc(sizeof(VkDescriptorSet) * allocInfo.setCount); VkDescriptorSet* sets = malloc(sizeof(VkDescriptorSet) * allocInfo.setCount);
if (vkAllocateDescriptorSets(pool->device->outputDevice->device, &vkAllocInfo, sets) != VK_SUCCESS) if (vkAllocateDescriptorSets(pool->device->outputDevice->device, &vkAllocInfo, sets) != VK_SUCCESS)
@@ -72,8 +108,6 @@ gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, gnUniformAllocati
uniforms[i]->uniform = malloc(sizeof(struct gnPlatformUniform_t)); uniforms[i]->uniform = malloc(sizeof(struct gnPlatformUniform_t));
uniforms[i]->uniform->set = sets[i]; uniforms[i]->uniform->set = sets[i];
} }
pool->uniformPool->poolCount++;
return uniforms; return uniforms;
} }
@@ -84,5 +118,5 @@ void gnDestroyUniformPoolFn(gnUniformPool pool) {
vkDestroyDescriptorSetLayout(pool->device->outputDevice->device, pool->uniformPool->pools[i].layouts[k], NULL); vkDestroyDescriptorSetLayout(pool->device->outputDevice->device, pool->uniformPool->pools[i].layouts[k], NULL);
} }
} }
free(pool->uniformPool); // free(pool->uniformPool);
} }

View File

@@ -9,6 +9,6 @@ typedef struct vkGryphnUniformPool {
} vkGryphnUniformPool; } vkGryphnUniformPool;
struct gnPlatformUniformPool_t { struct gnPlatformUniformPool_t {
uint32_t poolCount, maxPoolCount; uint32_t poolCount, maxPoolCount, currentPool;
vkGryphnUniformPool* pools; vkGryphnUniformPool* pools;
}; };