|
@@ -69,7 +69,7 @@ typedef struct VulkanExtensions
|
|
|
#define SMALL_ALLOCATION_SIZE 16777216 // 16 MiB
|
|
|
#define LARGE_ALLOCATION_INCREMENT 67108864 // 64 MiB
|
|
|
#define MAX_UBO_SECTION_SIZE 4096 // 4 KiB
|
|
|
-#define DESCRIPTOR_POOL_STARTING_SIZE 128
|
|
|
+#define DESCRIPTOR_POOL_SIZE 128
|
|
|
#define WINDOW_PROPERTY_DATA "SDL_GPUVulkanWindowPropertyData"
|
|
|
|
|
|
#define IDENTITY_SWIZZLE \
|
|
@@ -723,23 +723,69 @@ typedef struct VulkanDescriptorInfo
|
|
|
|
|
|
typedef struct DescriptorSetPool
|
|
|
{
|
|
|
- SDL_SpinLock lock;
|
|
|
+ // It's a pool... of pools!!!
|
|
|
+ Uint32 poolCount;
|
|
|
+ VkDescriptorPool *descriptorPools;
|
|
|
+
|
|
|
+ // We'll just manage the descriptor sets ourselves instead of freeing the sets
|
|
|
+ VkDescriptorSet *descriptorSets;
|
|
|
+ Uint32 descriptorSetCount;
|
|
|
+ Uint32 descriptorSetIndex;
|
|
|
+} DescriptorSetPool;
|
|
|
+
|
|
|
+// A command buffer acquires a cache at command buffer acquisition time
|
|
|
+typedef struct DescriptorSetCache
|
|
|
+{
|
|
|
+ // Pools are indexed by DescriptorSetLayoutID which increases monotonically
|
|
|
+ // There's only a certain number of maximum layouts possible since we de-duplicate them.
|
|
|
+ DescriptorSetPool *pools;
|
|
|
+ Uint32 poolCount;
|
|
|
+} DescriptorSetCache;
|
|
|
+
|
|
|
+typedef struct DescriptorSetLayoutHashTableKey
|
|
|
+{
|
|
|
+ VkShaderStageFlagBits shaderStage;
|
|
|
+ // Category 1: read resources
|
|
|
+ Uint32 samplerCount;
|
|
|
+ Uint32 storageBufferCount;
|
|
|
+ Uint32 storageTextureCount;
|
|
|
+ // Category 2: write resources
|
|
|
+ Uint32 writeStorageBufferCount;
|
|
|
+ Uint32 writeStorageTextureCount;
|
|
|
+ // Category 3: uniform buffers
|
|
|
+ Uint32 uniformBufferCount;
|
|
|
+} DescriptorSetLayoutHashTableKey;
|
|
|
|
|
|
+typedef uint32_t DescriptorSetLayoutID;
|
|
|
+
|
|
|
+typedef struct DescriptorSetLayout
|
|
|
+{
|
|
|
+ DescriptorSetLayoutID ID;
|
|
|
VkDescriptorSetLayout descriptorSetLayout;
|
|
|
|
|
|
- VulkanDescriptorInfo *descriptorInfos;
|
|
|
- Uint32 descriptorInfoCount;
|
|
|
+ // Category 1: read resources
|
|
|
+ Uint32 samplerCount;
|
|
|
+ Uint32 storageBufferCount;
|
|
|
+ Uint32 storageTextureCount;
|
|
|
+ // Category 2: write resources
|
|
|
+ Uint32 writeStorageBufferCount;
|
|
|
+ Uint32 writeStorageTextureCount;
|
|
|
+ // Category 3: uniform buffers
|
|
|
+ Uint32 uniformBufferCount;
|
|
|
+} DescriptorSetLayout;
|
|
|
|
|
|
- // This is actually a descriptor set and descriptor pool simultaneously
|
|
|
- VkDescriptorPool *descriptorPools;
|
|
|
- Uint32 descriptorPoolCount;
|
|
|
- Uint32 nextPoolSize;
|
|
|
+typedef struct GraphicsPipelineResourceLayoutHashTableKey
|
|
|
+{
|
|
|
+ Uint32 vertexSamplerCount;
|
|
|
+ Uint32 vertexStorageBufferCount;
|
|
|
+ Uint32 vertexStorageTextureCount;
|
|
|
+ Uint32 vertexUniformBufferCount;
|
|
|
|
|
|
- // We just manage a pool ourselves instead of freeing the sets
|
|
|
- VkDescriptorSet *inactiveDescriptorSets;
|
|
|
- Uint32 inactiveDescriptorSetCount;
|
|
|
- Uint32 inactiveDescriptorSetCapacity;
|
|
|
-} DescriptorSetPool;
|
|
|
+ Uint32 fragmentSamplerCount;
|
|
|
+ Uint32 fragmentStorageBufferCount;
|
|
|
+ Uint32 fragmentStorageTextureCount;
|
|
|
+ Uint32 fragmentUniformBufferCount;
|
|
|
+} GraphicsPipelineResourceLayoutHashTableKey;
|
|
|
|
|
|
typedef struct VulkanGraphicsPipelineResourceLayout
|
|
|
{
|
|
@@ -752,7 +798,7 @@ typedef struct VulkanGraphicsPipelineResourceLayout
|
|
|
* 2: fragment resources
|
|
|
* 3: fragment uniform buffers
|
|
|
*/
|
|
|
- DescriptorSetPool descriptorSetPools[4];
|
|
|
+ DescriptorSetLayout *descriptorSetLayouts[4];
|
|
|
|
|
|
Uint32 vertexSamplerCount;
|
|
|
Uint32 vertexStorageBufferCount;
|
|
@@ -770,7 +816,7 @@ typedef struct VulkanGraphicsPipeline
|
|
|
VkPipeline pipeline;
|
|
|
SDL_GPUPrimitiveType primitiveType;
|
|
|
|
|
|
- VulkanGraphicsPipelineResourceLayout resourceLayout;
|
|
|
+ VulkanGraphicsPipelineResourceLayout *resourceLayout;
|
|
|
|
|
|
VulkanShader *vertexShader;
|
|
|
VulkanShader *fragmentShader;
|
|
@@ -778,6 +824,16 @@ typedef struct VulkanGraphicsPipeline
|
|
|
SDL_AtomicInt referenceCount;
|
|
|
} VulkanGraphicsPipeline;
|
|
|
|
|
|
+typedef struct ComputePipelineResourceLayoutHashTableKey
|
|
|
+{
|
|
|
+ Uint32 samplerCount;
|
|
|
+ Uint32 readonlyStorageTextureCount;
|
|
|
+ Uint32 readonlyStorageBufferCount;
|
|
|
+ Uint32 writeonlyStorageTextureCount;
|
|
|
+ Uint32 writeonlyStorageBufferCount;
|
|
|
+ Uint32 uniformBufferCount;
|
|
|
+} ComputePipelineResourceLayoutHashTableKey;
|
|
|
+
|
|
|
typedef struct VulkanComputePipelineResourceLayout
|
|
|
{
|
|
|
VkPipelineLayout pipelineLayout;
|
|
@@ -788,7 +844,7 @@ typedef struct VulkanComputePipelineResourceLayout
|
|
|
* 1: write-only textures, then write-only buffers
|
|
|
* 2: uniform buffers
|
|
|
*/
|
|
|
- DescriptorSetPool descriptorSetPools[3];
|
|
|
+ DescriptorSetLayout *descriptorSetLayouts[3];
|
|
|
|
|
|
Uint32 numSamplers;
|
|
|
Uint32 numReadonlyStorageTextures;
|
|
@@ -802,7 +858,7 @@ typedef struct VulkanComputePipeline
|
|
|
{
|
|
|
VkShaderModule shaderModule;
|
|
|
VkPipeline pipeline;
|
|
|
- VulkanComputePipelineResourceLayout resourceLayout;
|
|
|
+ VulkanComputePipelineResourceLayout *resourceLayout;
|
|
|
SDL_AtomicInt referenceCount;
|
|
|
} VulkanComputePipeline;
|
|
|
|
|
@@ -851,12 +907,6 @@ typedef struct FramebufferHashTableKey
|
|
|
|
|
|
// Command structures
|
|
|
|
|
|
-typedef struct DescriptorSetData
|
|
|
-{
|
|
|
- DescriptorSetPool *descriptorSetPool;
|
|
|
- VkDescriptorSet descriptorSet;
|
|
|
-} DescriptorSetData;
|
|
|
-
|
|
|
typedef struct VulkanFencePool
|
|
|
{
|
|
|
SDL_Mutex *lock;
|
|
@@ -911,6 +961,8 @@ typedef struct VulkanCommandBuffer
|
|
|
|
|
|
// Resource bind state
|
|
|
|
|
|
+ DescriptorSetCache *descriptorSetCache; // acquired when command buffer is acquired
|
|
|
+
|
|
|
bool needNewVertexResourceDescriptorSet;
|
|
|
bool needNewVertexUniformDescriptorSet;
|
|
|
bool needNewVertexUniformOffsets;
|
|
@@ -932,10 +984,6 @@ typedef struct VulkanCommandBuffer
|
|
|
VkDescriptorSet computeWriteOnlyDescriptorSet;
|
|
|
VkDescriptorSet computeUniformDescriptorSet;
|
|
|
|
|
|
- DescriptorSetData *boundDescriptorSetDatas;
|
|
|
- Uint32 boundDescriptorSetDataCount;
|
|
|
- Uint32 boundDescriptorSetDataCapacity;
|
|
|
-
|
|
|
VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
|
|
VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
|
|
VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
|
@@ -964,32 +1012,32 @@ typedef struct VulkanCommandBuffer
|
|
|
// Track used resources
|
|
|
|
|
|
VulkanBuffer **usedBuffers;
|
|
|
- Uint32 usedBufferCount;
|
|
|
- Uint32 usedBufferCapacity;
|
|
|
+ Sint32 usedBufferCount;
|
|
|
+ Sint32 usedBufferCapacity;
|
|
|
|
|
|
VulkanTexture **usedTextures;
|
|
|
- Uint32 usedTextureCount;
|
|
|
- Uint32 usedTextureCapacity;
|
|
|
+ Sint32 usedTextureCount;
|
|
|
+ Sint32 usedTextureCapacity;
|
|
|
|
|
|
VulkanSampler **usedSamplers;
|
|
|
- Uint32 usedSamplerCount;
|
|
|
- Uint32 usedSamplerCapacity;
|
|
|
+ Sint32 usedSamplerCount;
|
|
|
+ Sint32 usedSamplerCapacity;
|
|
|
|
|
|
VulkanGraphicsPipeline **usedGraphicsPipelines;
|
|
|
- Uint32 usedGraphicsPipelineCount;
|
|
|
- Uint32 usedGraphicsPipelineCapacity;
|
|
|
+ Sint32 usedGraphicsPipelineCount;
|
|
|
+ Sint32 usedGraphicsPipelineCapacity;
|
|
|
|
|
|
VulkanComputePipeline **usedComputePipelines;
|
|
|
- Uint32 usedComputePipelineCount;
|
|
|
- Uint32 usedComputePipelineCapacity;
|
|
|
+ Sint32 usedComputePipelineCount;
|
|
|
+ Sint32 usedComputePipelineCapacity;
|
|
|
|
|
|
VulkanFramebuffer **usedFramebuffers;
|
|
|
- Uint32 usedFramebufferCount;
|
|
|
- Uint32 usedFramebufferCapacity;
|
|
|
+ Sint32 usedFramebufferCount;
|
|
|
+ Sint32 usedFramebufferCapacity;
|
|
|
|
|
|
VulkanUniformBuffer **usedUniformBuffers;
|
|
|
- Uint32 usedUniformBufferCount;
|
|
|
- Uint32 usedUniformBufferCapacity;
|
|
|
+ Sint32 usedUniformBufferCount;
|
|
|
+ Sint32 usedUniformBufferCapacity;
|
|
|
|
|
|
VulkanFenceHandle *inFlightFence;
|
|
|
Uint8 autoReleaseFence;
|
|
@@ -1048,11 +1096,20 @@ struct VulkanRenderer
|
|
|
SDL_HashTable *commandPoolHashTable;
|
|
|
SDL_HashTable *renderPassHashTable;
|
|
|
SDL_HashTable *framebufferHashTable;
|
|
|
+ SDL_HashTable *graphicsPipelineResourceLayoutHashTable;
|
|
|
+ SDL_HashTable *computePipelineResourceLayoutHashTable;
|
|
|
+ SDL_HashTable *descriptorSetLayoutHashTable;
|
|
|
|
|
|
VulkanUniformBuffer **uniformBufferPool;
|
|
|
Uint32 uniformBufferPoolCount;
|
|
|
Uint32 uniformBufferPoolCapacity;
|
|
|
|
|
|
+ DescriptorSetCache **descriptorSetCachePool;
|
|
|
+ Uint32 descriptorSetCachePoolCount;
|
|
|
+ Uint32 descriptorSetCachePoolCapacity;
|
|
|
+
|
|
|
+ SDL_AtomicInt layoutResourceID;
|
|
|
+
|
|
|
Uint32 minUBOAlignment;
|
|
|
|
|
|
// Deferred resource destruction
|
|
@@ -2257,23 +2314,21 @@ static Uint8 VULKAN_INTERNAL_BindMemoryForBuffer(
|
|
|
commandBuffer->array[commandBuffer->count] = resource; \
|
|
|
commandBuffer->count += 1;
|
|
|
|
|
|
-#define TRACK_RESOURCE(resource, type, array, count, capacity) \
|
|
|
- Uint32 i; \
|
|
|
- \
|
|
|
- for (i = 0; i < commandBuffer->count; i += 1) { \
|
|
|
- if (commandBuffer->array[i] == resource) { \
|
|
|
- return; \
|
|
|
- } \
|
|
|
- } \
|
|
|
- \
|
|
|
- if (commandBuffer->count == commandBuffer->capacity) { \
|
|
|
- commandBuffer->capacity += 1; \
|
|
|
- commandBuffer->array = SDL_realloc( \
|
|
|
- commandBuffer->array, \
|
|
|
- commandBuffer->capacity * sizeof(type)); \
|
|
|
- } \
|
|
|
- commandBuffer->array[commandBuffer->count] = resource; \
|
|
|
- commandBuffer->count += 1; \
|
|
|
+#define TRACK_RESOURCE(resource, type, array, count, capacity) \
|
|
|
+ for (Sint32 i = commandBuffer->count - 1; i >= 0; i -= 1) { \
|
|
|
+ if (commandBuffer->array[i] == resource) { \
|
|
|
+ return; \
|
|
|
+ } \
|
|
|
+ } \
|
|
|
+ \
|
|
|
+ if (commandBuffer->count == commandBuffer->capacity) { \
|
|
|
+ commandBuffer->capacity += 1; \
|
|
|
+ commandBuffer->array = SDL_realloc( \
|
|
|
+ commandBuffer->array, \
|
|
|
+ commandBuffer->capacity * sizeof(type)); \
|
|
|
+ } \
|
|
|
+ commandBuffer->array[commandBuffer->count] = resource; \
|
|
|
+ commandBuffer->count += 1; \
|
|
|
SDL_AtomicIncRef(&resource->referenceCount);
|
|
|
|
|
|
static void VULKAN_INTERNAL_TrackBuffer(
|
|
@@ -2353,8 +2408,7 @@ static void VULKAN_INTERNAL_TrackUniformBuffer(
|
|
|
VulkanCommandBuffer *commandBuffer,
|
|
|
VulkanUniformBuffer *uniformBuffer)
|
|
|
{
|
|
|
- Uint32 i;
|
|
|
- for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
|
|
|
+ for (Sint32 i = commandBuffer->usedUniformBufferCount - 1; i >= 0; i -= 1) {
|
|
|
if (commandBuffer->usedUniformBuffers[i] == uniformBuffer) {
|
|
|
return;
|
|
|
}
|
|
@@ -2935,7 +2989,6 @@ static void VULKAN_INTERNAL_DestroyCommandPool(
|
|
|
SDL_free(commandBuffer->presentDatas);
|
|
|
SDL_free(commandBuffer->waitSemaphores);
|
|
|
SDL_free(commandBuffer->signalSemaphores);
|
|
|
- SDL_free(commandBuffer->boundDescriptorSetDatas);
|
|
|
SDL_free(commandBuffer->usedBuffers);
|
|
|
SDL_free(commandBuffer->usedTextures);
|
|
|
SDL_free(commandBuffer->usedSamplers);
|
|
@@ -2951,55 +3004,33 @@ static void VULKAN_INTERNAL_DestroyCommandPool(
|
|
|
SDL_free(commandPool);
|
|
|
}
|
|
|
|
|
|
-static void VULKAN_INTERNAL_DestroyDescriptorSetPool(
|
|
|
+static void VULKAN_INTERNAL_DestroyDescriptorSetLayout(
|
|
|
VulkanRenderer *renderer,
|
|
|
- DescriptorSetPool *pool)
|
|
|
+ DescriptorSetLayout *layout)
|
|
|
{
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
- if (pool == NULL) {
|
|
|
+ if (layout == NULL) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < pool->descriptorPoolCount; i += 1) {
|
|
|
- renderer->vkDestroyDescriptorPool(
|
|
|
+ if (layout->descriptorSetLayout != VK_NULL_HANDLE) {
|
|
|
+ renderer->vkDestroyDescriptorSetLayout(
|
|
|
renderer->logicalDevice,
|
|
|
- pool->descriptorPools[i],
|
|
|
+ layout->descriptorSetLayout,
|
|
|
NULL);
|
|
|
}
|
|
|
|
|
|
- renderer->vkDestroyDescriptorSetLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- pool->descriptorSetLayout,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_free(pool->descriptorInfos);
|
|
|
- SDL_free(pool->descriptorPools);
|
|
|
- SDL_free(pool->inactiveDescriptorSets);
|
|
|
+ SDL_free(layout);
|
|
|
}
|
|
|
|
|
|
static void VULKAN_INTERNAL_DestroyGraphicsPipeline(
|
|
|
VulkanRenderer *renderer,
|
|
|
VulkanGraphicsPipeline *graphicsPipeline)
|
|
|
{
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
renderer->vkDestroyPipeline(
|
|
|
renderer->logicalDevice,
|
|
|
graphicsPipeline->pipeline,
|
|
|
NULL);
|
|
|
|
|
|
- renderer->vkDestroyPipelineLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- graphicsPipeline->resourceLayout.pipelineLayout,
|
|
|
- NULL);
|
|
|
-
|
|
|
- for (i = 0; i < 4; i += 1) {
|
|
|
- VULKAN_INTERNAL_DestroyDescriptorSetPool(
|
|
|
- renderer,
|
|
|
- &graphicsPipeline->resourceLayout.descriptorSetPools[i]);
|
|
|
- }
|
|
|
-
|
|
|
(void)SDL_AtomicDecRef(&graphicsPipeline->vertexShader->referenceCount);
|
|
|
(void)SDL_AtomicDecRef(&graphicsPipeline->fragmentShader->referenceCount);
|
|
|
|
|
@@ -3010,28 +3041,19 @@ static void VULKAN_INTERNAL_DestroyComputePipeline(
|
|
|
VulkanRenderer *renderer,
|
|
|
VulkanComputePipeline *computePipeline)
|
|
|
{
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
- renderer->vkDestroyPipeline(
|
|
|
- renderer->logicalDevice,
|
|
|
- computePipeline->pipeline,
|
|
|
- NULL);
|
|
|
-
|
|
|
- renderer->vkDestroyPipelineLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- computePipeline->resourceLayout.pipelineLayout,
|
|
|
- NULL);
|
|
|
-
|
|
|
- for (i = 0; i < 3; i += 1) {
|
|
|
- VULKAN_INTERNAL_DestroyDescriptorSetPool(
|
|
|
- renderer,
|
|
|
- &computePipeline->resourceLayout.descriptorSetPools[i]);
|
|
|
+ if (computePipeline->pipeline != VK_NULL_HANDLE) {
|
|
|
+ renderer->vkDestroyPipeline(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ computePipeline->pipeline,
|
|
|
+ NULL);
|
|
|
}
|
|
|
|
|
|
- renderer->vkDestroyShaderModule(
|
|
|
- renderer->logicalDevice,
|
|
|
- computePipeline->shaderModule,
|
|
|
- NULL);
|
|
|
+ if (computePipeline->shaderModule != VK_NULL_HANDLE) {
|
|
|
+ renderer->vkDestroyShaderModule(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ computePipeline->shaderModule,
|
|
|
+ NULL);
|
|
|
+ }
|
|
|
|
|
|
SDL_free(computePipeline);
|
|
|
}
|
|
@@ -3119,8 +3141,148 @@ static void VULKAN_INTERNAL_DestroySwapchain(
|
|
|
SDL_free(swapchainData);
|
|
|
}
|
|
|
|
|
|
+static void VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ VulkanGraphicsPipelineResourceLayout *resourceLayout)
|
|
|
+{
|
|
|
+ if (resourceLayout->pipelineLayout != VK_NULL_HANDLE) {
|
|
|
+ renderer->vkDestroyPipelineLayout(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ resourceLayout->pipelineLayout,
|
|
|
+ NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_free(resourceLayout);
|
|
|
+}
|
|
|
+
|
|
|
+static void VULKAN_INTERNAL_DestroyComputePipelineResourceLayout(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ VulkanComputePipelineResourceLayout *resourceLayout)
|
|
|
+{
|
|
|
+ if (resourceLayout->pipelineLayout != VK_NULL_HANDLE) {
|
|
|
+ renderer->vkDestroyPipelineLayout(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ resourceLayout->pipelineLayout,
|
|
|
+ NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_free(resourceLayout);
|
|
|
+}
|
|
|
+
|
|
|
+static void VULKAN_INTERNAL_DestroyDescriptorSetCache(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ DescriptorSetCache *descriptorSetCache)
|
|
|
+{
|
|
|
+ for (Uint32 i = 0; i < descriptorSetCache->poolCount; i += 1) {
|
|
|
+ for (Uint32 j = 0; j < descriptorSetCache->pools[i].poolCount; j += 1) {
|
|
|
+ renderer->vkDestroyDescriptorPool(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ descriptorSetCache->pools[i].descriptorPools[j],
|
|
|
+ NULL);
|
|
|
+ }
|
|
|
+ SDL_free(descriptorSetCache->pools[i].descriptorSets);
|
|
|
+ SDL_free(descriptorSetCache->pools[i].descriptorPools);
|
|
|
+ }
|
|
|
+ SDL_free(descriptorSetCache);
|
|
|
+}
|
|
|
+
|
|
|
// Hashtable functions
|
|
|
|
|
|
+static Uint32 VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashFunction(const void *key, void *data)
|
|
|
+{
|
|
|
+ GraphicsPipelineResourceLayoutHashTableKey *hashTableKey = (GraphicsPipelineResourceLayoutHashTableKey *)key;
|
|
|
+ /* The algorithm for this hashing function
|
|
|
+ * is taken from Josh Bloch's "Effective Java".
|
|
|
+ * (https://stackoverflow.com/a/113600/12492383)
|
|
|
+ */
|
|
|
+ const Uint32 hashFactor = 31;
|
|
|
+ Uint32 result = 1;
|
|
|
+ result = result * hashFactor + hashTableKey->vertexSamplerCount;
|
|
|
+ result = result * hashFactor + hashTableKey->vertexStorageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->vertexStorageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->vertexUniformBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->fragmentSamplerCount;
|
|
|
+ result = result * hashFactor + hashTableKey->fragmentStorageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->fragmentStorageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->fragmentUniformBufferCount;
|
|
|
+ return result;
|
|
|
+}
|
|
|
+static bool VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashKeyMatch(const void *aKey, const void *bKey, void *data)
|
|
|
+{
|
|
|
+ return SDL_memcmp(aKey, bKey, sizeof(GraphicsPipelineResourceLayoutHashTableKey)) == 0;
|
|
|
+}
|
|
|
+static void VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashNuke(const void *key, const void *value, void *data)
|
|
|
+{
|
|
|
+ VulkanRenderer *renderer = (VulkanRenderer *)data;
|
|
|
+ VulkanGraphicsPipelineResourceLayout *resourceLayout = (VulkanGraphicsPipelineResourceLayout *)value;
|
|
|
+ VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(renderer, resourceLayout);
|
|
|
+ SDL_free((void*)key);
|
|
|
+}
|
|
|
+
|
|
|
+static Uint32 VULKAN_INTERNAL_ComputePipelineResourceLayoutHashFunction(const void *key, void *data)
|
|
|
+{
|
|
|
+ ComputePipelineResourceLayoutHashTableKey *hashTableKey = (ComputePipelineResourceLayoutHashTableKey *)key;
|
|
|
+ /* The algorithm for this hashing function
|
|
|
+ * is taken from Josh Bloch's "Effective Java".
|
|
|
+ * (https://stackoverflow.com/a/113600/12492383)
|
|
|
+ */
|
|
|
+ const Uint32 hashFactor = 31;
|
|
|
+ Uint32 result = 1;
|
|
|
+ result = result * hashFactor + hashTableKey->samplerCount;
|
|
|
+ result = result * hashFactor + hashTableKey->readonlyStorageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->readonlyStorageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->writeonlyStorageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->writeonlyStorageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->uniformBufferCount;
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+static bool VULKAN_INTERNAL_ComputePipelineResourceLayoutHashKeyMatch(const void *aKey, const void *bKey, void *data)
|
|
|
+{
|
|
|
+ return SDL_memcmp(aKey, bKey, sizeof(ComputePipelineResourceLayoutHashTableKey)) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void VULKAN_INTERNAL_ComputePipelineResourceLayoutHashNuke(const void *key, const void *value, void *data)
|
|
|
+{
|
|
|
+ VulkanRenderer *renderer = (VulkanRenderer *)data;
|
|
|
+ VulkanComputePipelineResourceLayout *resourceLayout = (VulkanComputePipelineResourceLayout *)value;
|
|
|
+ VULKAN_INTERNAL_DestroyComputePipelineResourceLayout(renderer, resourceLayout);
|
|
|
+ SDL_free((void*)key);
|
|
|
+}
|
|
|
+
|
|
|
+static Uint32 VULKAN_INTERNAL_DescriptorSetLayoutHashFunction(const void *key, void *data)
|
|
|
+{
|
|
|
+ DescriptorSetLayoutHashTableKey *hashTableKey = (DescriptorSetLayoutHashTableKey *)key;
|
|
|
+
|
|
|
+ /* The algorithm for this hashing function
|
|
|
+ * is taken from Josh Bloch's "Effective Java".
|
|
|
+ * (https://stackoverflow.com/a/113600/12492383)
|
|
|
+ */
|
|
|
+ const Uint32 hashFactor = 31;
|
|
|
+ Uint32 result = 1;
|
|
|
+ result = result * hashFactor + hashTableKey->shaderStage;
|
|
|
+ result = result * hashFactor + hashTableKey->samplerCount;
|
|
|
+ result = result * hashFactor + hashTableKey->storageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->storageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->writeStorageTextureCount;
|
|
|
+ result = result * hashFactor + hashTableKey->writeStorageBufferCount;
|
|
|
+ result = result * hashFactor + hashTableKey->uniformBufferCount;
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+static bool VULKAN_INTERNAL_DescriptorSetLayoutHashKeyMatch(const void *aKey, const void *bKey, void *data)
|
|
|
+{
|
|
|
+ return SDL_memcmp(aKey, bKey, sizeof(DescriptorSetLayoutHashTableKey)) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void VULKAN_INTERNAL_DescriptorSetLayoutHashNuke(const void *key, const void *value, void *data)
|
|
|
+{
|
|
|
+ VulkanRenderer *renderer = (VulkanRenderer *)data;
|
|
|
+ DescriptorSetLayout *layout = (DescriptorSetLayout *)value;
|
|
|
+ VULKAN_INTERNAL_DestroyDescriptorSetLayout(renderer, layout);
|
|
|
+ SDL_free((void*)key);
|
|
|
+}
|
|
|
+
|
|
|
static Uint32 VULKAN_INTERNAL_CommandPoolHashFunction(const void *key, void *data)
|
|
|
{
|
|
|
return (Uint32)((CommandPoolHashTableKey *)key)->threadID;
|
|
@@ -3301,53 +3463,7 @@ static void VULKAN_INTERNAL_FramebufferHashNuke(const void *key, const void *val
|
|
|
SDL_free((void *)key);
|
|
|
}
|
|
|
|
|
|
-// Descriptor pool stuff
|
|
|
-
|
|
|
-static bool VULKAN_INTERNAL_CreateDescriptorPool(
|
|
|
- VulkanRenderer *renderer,
|
|
|
- VulkanDescriptorInfo *descriptorInfos,
|
|
|
- Uint32 descriptorInfoCount,
|
|
|
- Uint32 descriptorSetPoolSize,
|
|
|
- VkDescriptorPool *pDescriptorPool)
|
|
|
-{
|
|
|
- VkDescriptorPoolSize *descriptorPoolSizes;
|
|
|
- VkDescriptorPoolCreateInfo descriptorPoolInfo;
|
|
|
- VkResult vulkanResult;
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
- descriptorPoolSizes = NULL;
|
|
|
-
|
|
|
- if (descriptorInfoCount > 0) {
|
|
|
- descriptorPoolSizes = SDL_stack_alloc(VkDescriptorPoolSize, descriptorInfoCount);
|
|
|
-
|
|
|
- for (i = 0; i < descriptorInfoCount; i += 1) {
|
|
|
- descriptorPoolSizes[i].type = descriptorInfos[i].descriptorType;
|
|
|
- descriptorPoolSizes[i].descriptorCount = descriptorSetPoolSize;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
|
- descriptorPoolInfo.pNext = NULL;
|
|
|
- descriptorPoolInfo.flags = 0;
|
|
|
- descriptorPoolInfo.maxSets = descriptorSetPoolSize;
|
|
|
- descriptorPoolInfo.poolSizeCount = descriptorInfoCount;
|
|
|
- descriptorPoolInfo.pPoolSizes = descriptorPoolSizes;
|
|
|
-
|
|
|
- vulkanResult = renderer->vkCreateDescriptorPool(
|
|
|
- renderer->logicalDevice,
|
|
|
- &descriptorPoolInfo,
|
|
|
- NULL,
|
|
|
- pDescriptorPool);
|
|
|
-
|
|
|
- SDL_stack_free(descriptorPoolSizes);
|
|
|
-
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorPool", vulkanResult);
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
+// Descriptor pools
|
|
|
|
|
|
static bool VULKAN_INTERNAL_AllocateDescriptorSets(
|
|
|
VulkanRenderer *renderer,
|
|
@@ -3376,506 +3492,436 @@ static bool VULKAN_INTERNAL_AllocateDescriptorSets(
|
|
|
&descriptorSetAllocateInfo,
|
|
|
descriptorSetArray);
|
|
|
|
|
|
+ SDL_stack_free(descriptorSetLayouts);
|
|
|
+
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
LogVulkanResultAsError("vkAllocateDescriptorSets", vulkanResult);
|
|
|
- SDL_stack_free(descriptorSetLayouts);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- SDL_stack_free(descriptorSetLayouts);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static void VULKAN_INTERNAL_InitializeDescriptorSetPool(
|
|
|
+static void VULKAN_INTERNAL_AllocateDescriptorsFromPool(
|
|
|
VulkanRenderer *renderer,
|
|
|
+ DescriptorSetLayout *descriptorSetLayout,
|
|
|
DescriptorSetPool *descriptorSetPool)
|
|
|
{
|
|
|
- descriptorSetPool->lock = 0;
|
|
|
-
|
|
|
- // Descriptor set layout and descriptor infos are already set when this function is called
|
|
|
-
|
|
|
- descriptorSetPool->descriptorPoolCount = 1;
|
|
|
- descriptorSetPool->descriptorPools = SDL_malloc(sizeof(VkDescriptorPool));
|
|
|
- descriptorSetPool->nextPoolSize = DESCRIPTOR_POOL_STARTING_SIZE * 2;
|
|
|
-
|
|
|
- VULKAN_INTERNAL_CreateDescriptorPool(
|
|
|
- renderer,
|
|
|
- descriptorSetPool->descriptorInfos,
|
|
|
- descriptorSetPool->descriptorInfoCount,
|
|
|
- DESCRIPTOR_POOL_STARTING_SIZE,
|
|
|
- &descriptorSetPool->descriptorPools[0]);
|
|
|
-
|
|
|
- descriptorSetPool->inactiveDescriptorSetCapacity = DESCRIPTOR_POOL_STARTING_SIZE;
|
|
|
- descriptorSetPool->inactiveDescriptorSetCount = DESCRIPTOR_POOL_STARTING_SIZE;
|
|
|
- descriptorSetPool->inactiveDescriptorSets = SDL_malloc(
|
|
|
- sizeof(VkDescriptorSet) * DESCRIPTOR_POOL_STARTING_SIZE);
|
|
|
-
|
|
|
- VULKAN_INTERNAL_AllocateDescriptorSets(
|
|
|
- renderer,
|
|
|
- descriptorSetPool->descriptorPools[0],
|
|
|
- descriptorSetPool->descriptorSetLayout,
|
|
|
- DESCRIPTOR_POOL_STARTING_SIZE,
|
|
|
- descriptorSetPool->inactiveDescriptorSets);
|
|
|
-}
|
|
|
-
|
|
|
-static bool VULKAN_INTERNAL_InitializeGraphicsPipelineResourceLayout(
|
|
|
- VulkanRenderer *renderer,
|
|
|
- VulkanShader *vertexShader,
|
|
|
- VulkanShader *fragmentShader,
|
|
|
- VulkanGraphicsPipelineResourceLayout *pipelineResourceLayout)
|
|
|
-{
|
|
|
- VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE + MAX_STORAGE_TEXTURES_PER_STAGE + MAX_STORAGE_BUFFERS_PER_STAGE];
|
|
|
- VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo;
|
|
|
- VkDescriptorSetLayout descriptorSetLayouts[4];
|
|
|
- VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo;
|
|
|
- DescriptorSetPool *descriptorSetPool;
|
|
|
+ VkDescriptorPoolSize descriptorPoolSizes[
|
|
|
+ MAX_TEXTURE_SAMPLERS_PER_STAGE +
|
|
|
+ MAX_STORAGE_TEXTURES_PER_STAGE +
|
|
|
+ MAX_STORAGE_BUFFERS_PER_STAGE +
|
|
|
+ MAX_COMPUTE_WRITE_TEXTURES +
|
|
|
+ MAX_COMPUTE_WRITE_BUFFERS +
|
|
|
+ MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
+ VkDescriptorPoolCreateInfo descriptorPoolInfo;
|
|
|
+ VkDescriptorPool pool;
|
|
|
VkResult vulkanResult;
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
- pipelineResourceLayout->vertexSamplerCount = vertexShader->numSamplers;
|
|
|
- pipelineResourceLayout->vertexStorageTextureCount = vertexShader->numStorageTextures;
|
|
|
- pipelineResourceLayout->vertexStorageBufferCount = vertexShader->numStorageBuffers;
|
|
|
- pipelineResourceLayout->vertexUniformBufferCount = vertexShader->numUniformBuffers;
|
|
|
|
|
|
- pipelineResourceLayout->fragmentSamplerCount = fragmentShader->numSamplers;
|
|
|
- pipelineResourceLayout->fragmentStorageTextureCount = fragmentShader->numStorageTextures;
|
|
|
- pipelineResourceLayout->fragmentStorageBufferCount = fragmentShader->numStorageBuffers;
|
|
|
- pipelineResourceLayout->fragmentUniformBufferCount = fragmentShader->numUniformBuffers;
|
|
|
-
|
|
|
- // Vertex Resources
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
- descriptorSetLayoutCreateInfo.pNext = NULL;
|
|
|
- descriptorSetLayoutCreateInfo.flags = 0;
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
- vertexShader->numSamplers +
|
|
|
- vertexShader->numStorageTextures +
|
|
|
- vertexShader->numStorageBuffers;
|
|
|
-
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[0];
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
-
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
-
|
|
|
- for (i = 0; i < vertexShader->numSamplers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = vertexShader->numSamplers; i < vertexShader->numSamplers + vertexShader->numStorageTextures; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = vertexShader->numSamplers + vertexShader->numStorageTextures; i < descriptorSetLayoutCreateInfo.bindingCount; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
+ // Category 1
|
|
|
+ for (Uint32 i = 0; i < descriptorSetLayout->samplerCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
}
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
- NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
-
|
|
|
- descriptorSetLayouts[0] = descriptorSetPool->descriptorSetLayout;
|
|
|
-
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ for (Uint32 i = descriptorSetLayout->samplerCount; i < descriptorSetLayout->samplerCount + descriptorSetLayout->storageTextureCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
}
|
|
|
|
|
|
- // Vertex UBOs
|
|
|
-
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[1];
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount = pipelineResourceLayout->vertexUniformBufferCount;
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
-
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
+ for (Uint32 i = descriptorSetLayout->samplerCount + descriptorSetLayout->storageTextureCount; i < descriptorSetLayout->samplerCount + descriptorSetLayout->storageTextureCount + descriptorSetLayout->storageBufferCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
+ }
|
|
|
|
|
|
- for (i = 0; i < vertexShader->numUniformBuffers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ // Category 2
|
|
|
+ for (Uint32 i = 0; i < descriptorSetLayout->writeStorageTextureCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
+ }
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
- }
|
|
|
+ for (Uint32 i = descriptorSetLayout->writeStorageTextureCount; i < descriptorSetLayout->writeStorageTextureCount + descriptorSetLayout->writeStorageBufferCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
+ }
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
+ // Category 3
|
|
|
+ for (Uint32 i = 0; i < descriptorSetLayout->uniformBufferCount; i += 1) {
|
|
|
+ descriptorPoolSizes[i].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
+ descriptorPoolSizes[i].descriptorCount = DESCRIPTOR_POOL_SIZE;
|
|
|
}
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
+ descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
|
+ descriptorPoolInfo.pNext = NULL;
|
|
|
+ descriptorPoolInfo.flags = 0;
|
|
|
+ descriptorPoolInfo.maxSets = DESCRIPTOR_POOL_SIZE;
|
|
|
+ descriptorPoolInfo.poolSizeCount =
|
|
|
+ descriptorSetLayout->samplerCount +
|
|
|
+ descriptorSetLayout->storageTextureCount +
|
|
|
+ descriptorSetLayout->storageBufferCount +
|
|
|
+ descriptorSetLayout->writeStorageTextureCount +
|
|
|
+ descriptorSetLayout->writeStorageBufferCount +
|
|
|
+ descriptorSetLayout->uniformBufferCount;
|
|
|
+ descriptorPoolInfo.pPoolSizes = descriptorPoolSizes;
|
|
|
+
|
|
|
+ vulkanResult = renderer->vkCreateDescriptorPool(
|
|
|
renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
+ &descriptorPoolInfo,
|
|
|
NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
-
|
|
|
- descriptorSetLayouts[1] = descriptorSetPool->descriptorSetLayout;
|
|
|
+ &pool);
|
|
|
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ LogVulkanResultAsError("vkCreateDescriptorPool", vulkanResult);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- // Fragment resources
|
|
|
-
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[2];
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
- fragmentShader->numSamplers +
|
|
|
- fragmentShader->numStorageTextures +
|
|
|
- fragmentShader->numStorageBuffers;
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
-
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
+ descriptorSetPool->poolCount += 1;
|
|
|
+ descriptorSetPool->descriptorPools = SDL_realloc(
|
|
|
+ descriptorSetPool->descriptorPools,
|
|
|
+ sizeof(VkDescriptorPool) * descriptorSetPool->poolCount);
|
|
|
|
|
|
- for (i = 0; i < fragmentShader->numSamplers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ descriptorSetPool->descriptorPools[descriptorSetPool->poolCount - 1] = pool;
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = fragmentShader->numSamplers; i < fragmentShader->numSamplers + fragmentShader->numStorageTextures; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- }
|
|
|
+ descriptorSetPool->descriptorSets = SDL_realloc(
|
|
|
+ descriptorSetPool->descriptorSets,
|
|
|
+ sizeof(VkDescriptorSet) * descriptorSetPool->poolCount * DESCRIPTOR_POOL_SIZE);
|
|
|
|
|
|
- for (i = fragmentShader->numSamplers + fragmentShader->numStorageTextures; i < descriptorSetLayoutCreateInfo.bindingCount; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ VULKAN_INTERNAL_AllocateDescriptorSets(
|
|
|
+ renderer,
|
|
|
+ pool,
|
|
|
+ descriptorSetLayout->descriptorSetLayout,
|
|
|
+ DESCRIPTOR_POOL_SIZE,
|
|
|
+ &descriptorSetPool->descriptorSets[descriptorSetPool->descriptorSetCount]);
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- }
|
|
|
+ descriptorSetPool->descriptorSetCount += DESCRIPTOR_POOL_SIZE;
|
|
|
+}
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
+// NOTE: these categories should be mutually exclusive
|
|
|
+static DescriptorSetLayout *VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ VkShaderStageFlagBits shaderStage,
|
|
|
+ // Category 1: read resources
|
|
|
+ Uint32 samplerCount,
|
|
|
+ Uint32 storageTextureCount,
|
|
|
+ Uint32 storageBufferCount,
|
|
|
+ // Category 2: write resources
|
|
|
+ Uint32 writeStorageTextureCount,
|
|
|
+ Uint32 writeStorageBufferCount,
|
|
|
+ // Category 3: uniform buffers
|
|
|
+ Uint32 uniformBufferCount)
|
|
|
+{
|
|
|
+ DescriptorSetLayoutHashTableKey key;
|
|
|
+ SDL_zero(key);
|
|
|
+ DescriptorSetLayout *layout = NULL;
|
|
|
+
|
|
|
+ key.shaderStage = shaderStage;
|
|
|
+ key.samplerCount = samplerCount;
|
|
|
+ key.storageTextureCount = storageTextureCount;
|
|
|
+ key.storageBufferCount = storageBufferCount;
|
|
|
+ key.writeStorageTextureCount = writeStorageTextureCount;
|
|
|
+ key.writeStorageBufferCount = writeStorageBufferCount;
|
|
|
+ key.uniformBufferCount = uniformBufferCount;
|
|
|
+
|
|
|
+ if (SDL_FindInHashTable(
|
|
|
+ renderer->descriptorSetLayoutHashTable,
|
|
|
+ (const void *)&key,
|
|
|
+ (const void **)&layout)) {
|
|
|
+ return layout;
|
|
|
}
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
- NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
+ VkDescriptorSetLayout descriptorSetLayout;
|
|
|
+ VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[
|
|
|
+ MAX_TEXTURE_SAMPLERS_PER_STAGE +
|
|
|
+ MAX_STORAGE_TEXTURES_PER_STAGE +
|
|
|
+ MAX_STORAGE_BUFFERS_PER_STAGE +
|
|
|
+ MAX_COMPUTE_WRITE_TEXTURES +
|
|
|
+ MAX_COMPUTE_WRITE_BUFFERS];
|
|
|
|
|
|
- descriptorSetLayouts[2] = descriptorSetPool->descriptorSetLayout;
|
|
|
+ VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo;
|
|
|
+ descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
+ descriptorSetLayoutCreateInfo.pNext = NULL;
|
|
|
+ descriptorSetLayoutCreateInfo.flags = 0;
|
|
|
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ // Category 1
|
|
|
+ for (Uint32 i = 0; i < samplerCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
}
|
|
|
|
|
|
- // Fragment UBOs
|
|
|
-
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[3];
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
- pipelineResourceLayout->fragmentUniformBufferCount;
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
+ for (Uint32 i = samplerCount; i < samplerCount + storageTextureCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ }
|
|
|
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
+ for (Uint32 i = samplerCount + storageTextureCount; i < samplerCount + storageTextureCount + storageBufferCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ }
|
|
|
|
|
|
- for (i = 0; i < fragmentShader->numUniformBuffers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ // Category 2
|
|
|
+ for (Uint32 i = 0; i < writeStorageTextureCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ }
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
- }
|
|
|
+ for (Uint32 i = writeStorageTextureCount; i < writeStorageTextureCount + writeStorageBufferCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ }
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
+ // Category 3
|
|
|
+ for (Uint32 i = 0; i < uniformBufferCount; i += 1) {
|
|
|
+ descriptorSetLayoutBindings[i].binding = i;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
+ descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
+ descriptorSetLayoutBindings[i].stageFlags = shaderStage;
|
|
|
+ descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
}
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
+ descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
+ descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
+ samplerCount +
|
|
|
+ storageTextureCount +
|
|
|
+ storageBufferCount +
|
|
|
+ writeStorageTextureCount +
|
|
|
+ writeStorageBufferCount +
|
|
|
+ uniformBufferCount;
|
|
|
+
|
|
|
+ VkResult vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
renderer->logicalDevice,
|
|
|
&descriptorSetLayoutCreateInfo,
|
|
|
NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
-
|
|
|
- descriptorSetLayouts[3] = descriptorSetPool->descriptorSetLayout;
|
|
|
+ &descriptorSetLayout);
|
|
|
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- // Create the pipeline layout
|
|
|
+ layout = SDL_malloc(sizeof(DescriptorSetLayout));
|
|
|
+ layout->descriptorSetLayout = descriptorSetLayout;
|
|
|
|
|
|
- pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
|
- pipelineLayoutCreateInfo.pNext = NULL;
|
|
|
- pipelineLayoutCreateInfo.flags = 0;
|
|
|
- pipelineLayoutCreateInfo.setLayoutCount = 4;
|
|
|
- pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts;
|
|
|
- pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
|
|
|
- pipelineLayoutCreateInfo.pPushConstantRanges = NULL;
|
|
|
+ layout->samplerCount = samplerCount;
|
|
|
+ layout->storageBufferCount = storageBufferCount;
|
|
|
+ layout->storageTextureCount = storageTextureCount;
|
|
|
+ layout->writeStorageBufferCount = writeStorageBufferCount;
|
|
|
+ layout->writeStorageTextureCount = writeStorageTextureCount;
|
|
|
+ layout->uniformBufferCount = uniformBufferCount;
|
|
|
|
|
|
- vulkanResult = renderer->vkCreatePipelineLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- &pipelineLayoutCreateInfo,
|
|
|
- NULL,
|
|
|
- &pipelineResourceLayout->pipelineLayout);
|
|
|
+ layout->ID = SDL_AtomicIncRef(&renderer->layoutResourceID);
|
|
|
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreatePipelineLayout", vulkanResult);
|
|
|
- return false;
|
|
|
- }
|
|
|
+ DescriptorSetLayoutHashTableKey *allocedKey = SDL_malloc(sizeof(DescriptorSetLayoutHashTableKey));
|
|
|
+ SDL_memcpy(allocedKey, &key, sizeof(DescriptorSetLayoutHashTableKey));
|
|
|
|
|
|
- for (i = 0; i < 4; i += 1) {
|
|
|
- VULKAN_INTERNAL_InitializeDescriptorSetPool(
|
|
|
- renderer,
|
|
|
- &pipelineResourceLayout->descriptorSetPools[i]);
|
|
|
- }
|
|
|
+ SDL_InsertIntoHashTable(
|
|
|
+ renderer->descriptorSetLayoutHashTable,
|
|
|
+ (const void *)allocedKey,
|
|
|
+ (const void *)layout);
|
|
|
|
|
|
- return true;
|
|
|
+ return layout;
|
|
|
}
|
|
|
|
|
|
-static bool VULKAN_INTERNAL_InitializeComputePipelineResourceLayout(
|
|
|
+static VulkanGraphicsPipelineResourceLayout *VULKAN_INTERNAL_FetchGraphicsPipelineResourceLayout(
|
|
|
VulkanRenderer *renderer,
|
|
|
- const SDL_GPUComputePipelineCreateInfo *createinfo,
|
|
|
- VulkanComputePipelineResourceLayout *pipelineResourceLayout)
|
|
|
-{
|
|
|
- VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
- VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo;
|
|
|
- VkDescriptorSetLayout descriptorSetLayouts[3];
|
|
|
- VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo;
|
|
|
- DescriptorSetPool *descriptorSetPool;
|
|
|
- VkResult vulkanResult;
|
|
|
- Uint32 i;
|
|
|
-
|
|
|
- pipelineResourceLayout->numSamplers = createinfo->num_samplers;
|
|
|
- pipelineResourceLayout->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
|
|
|
- pipelineResourceLayout->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
|
|
- pipelineResourceLayout->numWriteonlyStorageTextures = createinfo->num_writeonly_storage_textures;
|
|
|
- pipelineResourceLayout->numWriteonlyStorageBuffers = createinfo->num_writeonly_storage_buffers;
|
|
|
- pipelineResourceLayout->numUniformBuffers = createinfo->num_uniform_buffers;
|
|
|
-
|
|
|
- // Read-only resources
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
- descriptorSetLayoutCreateInfo.pNext = NULL;
|
|
|
- descriptorSetLayoutCreateInfo.flags = 0;
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
- createinfo->num_samplers +
|
|
|
- createinfo->num_readonly_storage_textures +
|
|
|
- createinfo->num_readonly_storage_buffers;
|
|
|
-
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[0];
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
-
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
-
|
|
|
- for (i = 0; i < createinfo->num_samplers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = createinfo->num_samplers; i < createinfo->num_samplers + createinfo->num_readonly_storage_textures; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = createinfo->num_samplers + createinfo->num_readonly_storage_textures; i < descriptorSetLayoutCreateInfo.bindingCount; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
-
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
-
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
- }
|
|
|
-
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
- NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
-
|
|
|
- descriptorSetLayouts[0] = descriptorSetPool->descriptorSetLayout;
|
|
|
-
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ VulkanShader *vertexShader,
|
|
|
+ VulkanShader *fragmentShader)
|
|
|
+{
|
|
|
+ GraphicsPipelineResourceLayoutHashTableKey key;
|
|
|
+ SDL_zero(key);
|
|
|
+ VulkanGraphicsPipelineResourceLayout *pipelineResourceLayout = NULL;
|
|
|
+
|
|
|
+ key.vertexSamplerCount = vertexShader->numSamplers;
|
|
|
+ key.vertexStorageTextureCount = vertexShader->numStorageTextures;
|
|
|
+ key.vertexStorageBufferCount = vertexShader->numStorageBuffers;
|
|
|
+ key.vertexUniformBufferCount = vertexShader->numUniformBuffers;
|
|
|
+ key.fragmentSamplerCount = fragmentShader->numSamplers;
|
|
|
+ key.fragmentStorageTextureCount = fragmentShader->numStorageTextures;
|
|
|
+ key.fragmentStorageBufferCount = fragmentShader->numStorageBuffers;
|
|
|
+ key.fragmentUniformBufferCount = fragmentShader->numUniformBuffers;
|
|
|
+ if (SDL_FindInHashTable(
|
|
|
+ renderer->graphicsPipelineResourceLayoutHashTable,
|
|
|
+ (const void *)&key,
|
|
|
+ (const void **)&pipelineResourceLayout)) {
|
|
|
+ return pipelineResourceLayout;
|
|
|
}
|
|
|
|
|
|
- // Write-only resources
|
|
|
+ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo;
|
|
|
+ VkDescriptorSetLayout descriptorSetLayouts[4];
|
|
|
+ VkResult vulkanResult;
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount =
|
|
|
- createinfo->num_writeonly_storage_textures +
|
|
|
- createinfo->num_writeonly_storage_buffers;
|
|
|
+ pipelineResourceLayout = SDL_calloc(1, sizeof(VulkanGraphicsPipelineResourceLayout));
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[0] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
+ vertexShader->numSamplers,
|
|
|
+ vertexShader->numStorageTextures,
|
|
|
+ vertexShader->numStorageBuffers,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0);
|
|
|
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[1];
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[1] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ vertexShader->numUniformBuffers);
|
|
|
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[2] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
+ fragmentShader->numSamplers,
|
|
|
+ fragmentShader->numStorageTextures,
|
|
|
+ fragmentShader->numStorageBuffers,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0);
|
|
|
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[3] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ fragmentShader->numUniformBuffers);
|
|
|
|
|
|
- for (i = 0; i < createinfo->num_writeonly_storage_textures; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ descriptorSetLayouts[0] = pipelineResourceLayout->descriptorSetLayouts[0]->descriptorSetLayout;
|
|
|
+ descriptorSetLayouts[1] = pipelineResourceLayout->descriptorSetLayouts[1]->descriptorSetLayout;
|
|
|
+ descriptorSetLayouts[2] = pipelineResourceLayout->descriptorSetLayouts[2]->descriptorSetLayout;
|
|
|
+ descriptorSetLayouts[3] = pipelineResourceLayout->descriptorSetLayouts[3]->descriptorSetLayout;
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
+ pipelineResourceLayout->vertexSamplerCount = vertexShader->numSamplers;
|
|
|
+ pipelineResourceLayout->vertexStorageTextureCount = vertexShader->numStorageTextures;
|
|
|
+ pipelineResourceLayout->vertexStorageBufferCount = vertexShader->numStorageBuffers;
|
|
|
+ pipelineResourceLayout->vertexUniformBufferCount = vertexShader->numUniformBuffers;
|
|
|
|
|
|
- for (i = createinfo->num_writeonly_storage_textures; i < descriptorSetLayoutCreateInfo.bindingCount; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ pipelineResourceLayout->fragmentSamplerCount = fragmentShader->numSamplers;
|
|
|
+ pipelineResourceLayout->fragmentStorageTextureCount = fragmentShader->numStorageTextures;
|
|
|
+ pipelineResourceLayout->fragmentStorageBufferCount = fragmentShader->numStorageBuffers;
|
|
|
+ pipelineResourceLayout->fragmentUniformBufferCount = fragmentShader->numUniformBuffers;
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
+ // Create the pipeline layout
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
- }
|
|
|
+ pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
|
+ pipelineLayoutCreateInfo.pNext = NULL;
|
|
|
+ pipelineLayoutCreateInfo.flags = 0;
|
|
|
+ pipelineLayoutCreateInfo.setLayoutCount = 4;
|
|
|
+ pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts;
|
|
|
+ pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
|
|
|
+ pipelineLayoutCreateInfo.pPushConstantRanges = NULL;
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
+ vulkanResult = renderer->vkCreatePipelineLayout(
|
|
|
renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
+ &pipelineLayoutCreateInfo,
|
|
|
NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
-
|
|
|
- descriptorSetLayouts[1] = descriptorSetPool->descriptorSetLayout;
|
|
|
+ &pipelineResourceLayout->pipelineLayout);
|
|
|
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ LogVulkanResultAsError("vkCreatePipelineLayout", vulkanResult);
|
|
|
+ VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(renderer, pipelineResourceLayout);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- // Uniform buffers
|
|
|
+ GraphicsPipelineResourceLayoutHashTableKey *allocedKey = SDL_malloc(sizeof(GraphicsPipelineResourceLayoutHashTableKey));
|
|
|
+ SDL_memcpy(allocedKey, &key, sizeof(GraphicsPipelineResourceLayoutHashTableKey));
|
|
|
|
|
|
- descriptorSetPool = &pipelineResourceLayout->descriptorSetPools[2];
|
|
|
+ SDL_InsertIntoHashTable(
|
|
|
+ renderer->graphicsPipelineResourceLayoutHashTable,
|
|
|
+ (const void *)allocedKey,
|
|
|
+ (const void *)pipelineResourceLayout);
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.bindingCount = createinfo->num_uniform_buffers;
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = NULL;
|
|
|
+ return pipelineResourceLayout;
|
|
|
+}
|
|
|
|
|
|
- descriptorSetPool->descriptorInfoCount = descriptorSetLayoutCreateInfo.bindingCount;
|
|
|
- descriptorSetPool->descriptorInfos = NULL;
|
|
|
+static VulkanComputePipelineResourceLayout *VULKAN_INTERNAL_FetchComputePipelineResourceLayout(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ const SDL_GPUComputePipelineCreateInfo *createinfo)
|
|
|
+{
|
|
|
+ ComputePipelineResourceLayoutHashTableKey key;
|
|
|
+ SDL_zero(key);
|
|
|
+ VulkanComputePipelineResourceLayout *pipelineResourceLayout = NULL;
|
|
|
|
|
|
- if (descriptorSetLayoutCreateInfo.bindingCount > 0) {
|
|
|
- descriptorSetPool->descriptorInfos = SDL_malloc(
|
|
|
- descriptorSetPool->descriptorInfoCount * sizeof(VulkanDescriptorInfo));
|
|
|
+ key.samplerCount = createinfo->num_samplers;
|
|
|
+ key.readonlyStorageTextureCount = createinfo->num_readonly_storage_textures;
|
|
|
+ key.readonlyStorageBufferCount = createinfo->num_readonly_storage_buffers;
|
|
|
+ key.writeonlyStorageTextureCount = createinfo->num_writeonly_storage_textures;
|
|
|
+ key.writeonlyStorageBufferCount = createinfo->num_writeonly_storage_buffers;
|
|
|
+ key.uniformBufferCount = createinfo->num_uniform_buffers;
|
|
|
|
|
|
- for (i = 0; i < createinfo->num_uniform_buffers; i += 1) {
|
|
|
- descriptorSetLayoutBindings[i].binding = i;
|
|
|
- descriptorSetLayoutBindings[i].descriptorCount = 1;
|
|
|
- descriptorSetLayoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetLayoutBindings[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- descriptorSetLayoutBindings[i].pImmutableSamplers = NULL;
|
|
|
+ if (SDL_FindInHashTable(
|
|
|
+ renderer->computePipelineResourceLayoutHashTable,
|
|
|
+ (const void *)&key,
|
|
|
+ (const void **)&pipelineResourceLayout)) {
|
|
|
+ return pipelineResourceLayout;
|
|
|
+ }
|
|
|
|
|
|
- descriptorSetPool->descriptorInfos[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- descriptorSetPool->descriptorInfos[i].stageFlag = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
- }
|
|
|
+ VkDescriptorSetLayout descriptorSetLayouts[3];
|
|
|
+ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo;
|
|
|
+ VkResult vulkanResult;
|
|
|
|
|
|
- descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
|
|
|
- }
|
|
|
+ pipelineResourceLayout = SDL_calloc(1, sizeof(VulkanComputePipelineResourceLayout));
|
|
|
|
|
|
- vulkanResult = renderer->vkCreateDescriptorSetLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- &descriptorSetLayoutCreateInfo,
|
|
|
- NULL,
|
|
|
- &descriptorSetPool->descriptorSetLayout);
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[0] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
+ createinfo->num_samplers,
|
|
|
+ createinfo->num_readonly_storage_textures,
|
|
|
+ createinfo->num_readonly_storage_buffers,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0);
|
|
|
|
|
|
- descriptorSetLayouts[2] = descriptorSetPool->descriptorSetLayout;
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[1] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ createinfo->num_writeonly_storage_textures,
|
|
|
+ createinfo->num_writeonly_storage_buffers,
|
|
|
+ 0);
|
|
|
|
|
|
- if (vulkanResult != VK_SUCCESS) {
|
|
|
- LogVulkanResultAsError("vkCreateDescriptorSetLayout", vulkanResult);
|
|
|
- return false;
|
|
|
- }
|
|
|
+ pipelineResourceLayout->descriptorSetLayouts[2] = VULKAN_INTERNAL_FetchDescriptorSetLayout(
|
|
|
+ renderer,
|
|
|
+ VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ createinfo->num_uniform_buffers);
|
|
|
+
|
|
|
+ descriptorSetLayouts[0] = pipelineResourceLayout->descriptorSetLayouts[0]->descriptorSetLayout;
|
|
|
+ descriptorSetLayouts[1] = pipelineResourceLayout->descriptorSetLayouts[1]->descriptorSetLayout;
|
|
|
+ descriptorSetLayouts[2] = pipelineResourceLayout->descriptorSetLayouts[2]->descriptorSetLayout;
|
|
|
+
|
|
|
+ pipelineResourceLayout->numSamplers = createinfo->num_samplers;
|
|
|
+ pipelineResourceLayout->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
|
|
|
+ pipelineResourceLayout->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
|
|
+ pipelineResourceLayout->numWriteonlyStorageTextures = createinfo->num_writeonly_storage_textures;
|
|
|
+ pipelineResourceLayout->numWriteonlyStorageBuffers = createinfo->num_writeonly_storage_buffers;
|
|
|
+ pipelineResourceLayout->numUniformBuffers = createinfo->num_uniform_buffers;
|
|
|
|
|
|
// Create the pipeline layout
|
|
|
|
|
@@ -3895,16 +3941,19 @@ static bool VULKAN_INTERNAL_InitializeComputePipelineResourceLayout(
|
|
|
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
LogVulkanResultAsError("vkCreatePipelineLayout", vulkanResult);
|
|
|
- return false;
|
|
|
+ VULKAN_INTERNAL_DestroyComputePipelineResourceLayout(renderer, pipelineResourceLayout);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < 3; i += 1) {
|
|
|
- VULKAN_INTERNAL_InitializeDescriptorSetPool(
|
|
|
- renderer,
|
|
|
- &pipelineResourceLayout->descriptorSetPools[i]);
|
|
|
- }
|
|
|
+ ComputePipelineResourceLayoutHashTableKey *allocedKey = SDL_malloc(sizeof(ComputePipelineResourceLayoutHashTableKey));
|
|
|
+ SDL_memcpy(allocedKey, &key, sizeof(ComputePipelineResourceLayoutHashTableKey));
|
|
|
|
|
|
- return true;
|
|
|
+ SDL_InsertIntoHashTable(
|
|
|
+ renderer->computePipelineResourceLayoutHashTable,
|
|
|
+ (const void *)allocedKey,
|
|
|
+ (const void *)pipelineResourceLayout);
|
|
|
+
|
|
|
+ return pipelineResourceLayout;
|
|
|
}
|
|
|
|
|
|
// Data Buffer
|
|
@@ -4674,6 +4723,13 @@ static void VULKAN_DestroyDevice(
|
|
|
}
|
|
|
SDL_free(renderer->uniformBufferPool);
|
|
|
|
|
|
+ for (Uint32 i = 0; i < renderer->descriptorSetCachePoolCount; i += 1) {
|
|
|
+ VULKAN_INTERNAL_DestroyDescriptorSetCache(
|
|
|
+ renderer,
|
|
|
+ renderer->descriptorSetCachePool[i]);
|
|
|
+ }
|
|
|
+ SDL_free(renderer->descriptorSetCachePool);
|
|
|
+
|
|
|
for (Uint32 i = 0; i < renderer->fencePool.availableFenceCount; i += 1) {
|
|
|
renderer->vkDestroyFence(
|
|
|
renderer->logicalDevice,
|
|
@@ -4689,6 +4745,9 @@ static void VULKAN_DestroyDevice(
|
|
|
SDL_DestroyHashTable(renderer->commandPoolHashTable);
|
|
|
SDL_DestroyHashTable(renderer->renderPassHashTable);
|
|
|
SDL_DestroyHashTable(renderer->framebufferHashTable);
|
|
|
+ SDL_DestroyHashTable(renderer->graphicsPipelineResourceLayoutHashTable);
|
|
|
+ SDL_DestroyHashTable(renderer->computePipelineResourceLayoutHashTable);
|
|
|
+ SDL_DestroyHashTable(renderer->descriptorSetLayoutHashTable);
|
|
|
|
|
|
for (Uint32 i = 0; i < VK_MAX_MEMORY_TYPES; i += 1) {
|
|
|
allocator = &renderer->memoryAllocator->subAllocators[i];
|
|
@@ -4740,71 +4799,72 @@ static void VULKAN_DestroyDevice(
|
|
|
SDL_Vulkan_UnloadLibrary();
|
|
|
}
|
|
|
|
|
|
-static VkDescriptorSet VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
- VulkanRenderer *renderer,
|
|
|
- VulkanCommandBuffer *vulkanCommandBuffer,
|
|
|
- DescriptorSetPool *descriptorSetPool)
|
|
|
+static DescriptorSetCache *VULKAN_INTERNAL_AcquireDescriptorSetCache(
|
|
|
+ VulkanRenderer *renderer)
|
|
|
{
|
|
|
- VkDescriptorSet descriptorSet;
|
|
|
+ DescriptorSetCache *cache;
|
|
|
|
|
|
- SDL_LockSpinlock(&descriptorSetPool->lock);
|
|
|
+ if (renderer->descriptorSetCachePoolCount == 0) {
|
|
|
+ cache = SDL_malloc(sizeof(DescriptorSetCache));
|
|
|
+ cache->poolCount = 0;
|
|
|
+ cache->pools = NULL;
|
|
|
+ } else {
|
|
|
+ cache = renderer->descriptorSetCachePool[renderer->descriptorSetCachePoolCount - 1];
|
|
|
+ renderer->descriptorSetCachePoolCount -= 1;
|
|
|
+ }
|
|
|
|
|
|
- // If no inactive descriptor sets remain, create a new pool and allocate new inactive sets
|
|
|
+ return cache;
|
|
|
+}
|
|
|
|
|
|
- if (descriptorSetPool->inactiveDescriptorSetCount == 0) {
|
|
|
- descriptorSetPool->descriptorPoolCount += 1;
|
|
|
- descriptorSetPool->descriptorPools = SDL_realloc(
|
|
|
- descriptorSetPool->descriptorPools,
|
|
|
- sizeof(VkDescriptorPool) * descriptorSetPool->descriptorPoolCount);
|
|
|
+static void VULKAN_INTERNAL_ReturnDescriptorSetCacheToPool(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ DescriptorSetCache *descriptorSetCache)
|
|
|
+{
|
|
|
+ EXPAND_ARRAY_IF_NEEDED(
|
|
|
+ renderer->descriptorSetCachePool,
|
|
|
+ DescriptorSetCache *,
|
|
|
+ renderer->descriptorSetCachePoolCount + 1,
|
|
|
+ renderer->descriptorSetCachePoolCapacity,
|
|
|
+ renderer->descriptorSetCachePoolCapacity * 2)
|
|
|
|
|
|
- if (!VULKAN_INTERNAL_CreateDescriptorPool(
|
|
|
- renderer,
|
|
|
- descriptorSetPool->descriptorInfos,
|
|
|
- descriptorSetPool->descriptorInfoCount,
|
|
|
- descriptorSetPool->nextPoolSize,
|
|
|
- &descriptorSetPool->descriptorPools[descriptorSetPool->descriptorPoolCount - 1])) {
|
|
|
- SDL_UnlockSpinlock(&descriptorSetPool->lock);
|
|
|
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create descriptor pool!");
|
|
|
- return VK_NULL_HANDLE;
|
|
|
- }
|
|
|
+ renderer->descriptorSetCachePool[renderer->descriptorSetCachePoolCount] = descriptorSetCache;
|
|
|
+ renderer->descriptorSetCachePoolCount += 1;
|
|
|
|
|
|
- descriptorSetPool->inactiveDescriptorSetCapacity += descriptorSetPool->nextPoolSize;
|
|
|
+ for (Uint32 i = 0; i < descriptorSetCache->poolCount; i += 1) {
|
|
|
+ descriptorSetCache->pools[i].descriptorSetIndex = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- descriptorSetPool->inactiveDescriptorSets = SDL_realloc(
|
|
|
- descriptorSetPool->inactiveDescriptorSets,
|
|
|
- sizeof(VkDescriptorSet) * descriptorSetPool->inactiveDescriptorSetCapacity);
|
|
|
+static VkDescriptorSet VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
+ VulkanRenderer *renderer,
|
|
|
+ VulkanCommandBuffer *vulkanCommandBuffer,
|
|
|
+ DescriptorSetLayout *descriptorSetLayout)
|
|
|
+{
|
|
|
+ // Grow the pool to meet the descriptor set layout ID
|
|
|
+ if (descriptorSetLayout->ID >= vulkanCommandBuffer->descriptorSetCache->poolCount) {
|
|
|
+ vulkanCommandBuffer->descriptorSetCache->pools = SDL_realloc(
|
|
|
+ vulkanCommandBuffer->descriptorSetCache->pools,
|
|
|
+ sizeof(DescriptorSetPool) * (descriptorSetLayout->ID + 1));
|
|
|
|
|
|
- if (!VULKAN_INTERNAL_AllocateDescriptorSets(
|
|
|
- renderer,
|
|
|
- descriptorSetPool->descriptorPools[descriptorSetPool->descriptorPoolCount - 1],
|
|
|
- descriptorSetPool->descriptorSetLayout,
|
|
|
- descriptorSetPool->nextPoolSize,
|
|
|
- descriptorSetPool->inactiveDescriptorSets)) {
|
|
|
- SDL_UnlockSpinlock(&descriptorSetPool->lock);
|
|
|
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to allocate descriptor sets!");
|
|
|
- return VK_NULL_HANDLE;
|
|
|
+ for (Uint32 i = vulkanCommandBuffer->descriptorSetCache->poolCount; i < descriptorSetLayout->ID + 1; i += 1) {
|
|
|
+ SDL_zero(vulkanCommandBuffer->descriptorSetCache->pools[i]);
|
|
|
}
|
|
|
|
|
|
- descriptorSetPool->inactiveDescriptorSetCount = descriptorSetPool->nextPoolSize;
|
|
|
-
|
|
|
- descriptorSetPool->nextPoolSize *= 2;
|
|
|
+ vulkanCommandBuffer->descriptorSetCache->poolCount = descriptorSetLayout->ID + 1;
|
|
|
}
|
|
|
|
|
|
- descriptorSet = descriptorSetPool->inactiveDescriptorSets[descriptorSetPool->inactiveDescriptorSetCount - 1];
|
|
|
- descriptorSetPool->inactiveDescriptorSetCount -= 1;
|
|
|
+ DescriptorSetPool *pool =
|
|
|
+ &vulkanCommandBuffer->descriptorSetCache->pools[descriptorSetLayout->ID];
|
|
|
|
|
|
- SDL_UnlockSpinlock(&descriptorSetPool->lock);
|
|
|
-
|
|
|
- if (vulkanCommandBuffer->boundDescriptorSetDataCount == vulkanCommandBuffer->boundDescriptorSetDataCapacity) {
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDataCapacity *= 2;
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDatas = SDL_realloc(
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDatas,
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDataCapacity * sizeof(DescriptorSetData));
|
|
|
+ if (pool->descriptorSetIndex == pool->descriptorSetCount) {
|
|
|
+ VULKAN_INTERNAL_AllocateDescriptorsFromPool(
|
|
|
+ renderer,
|
|
|
+ descriptorSetLayout,
|
|
|
+ pool);
|
|
|
}
|
|
|
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDatas[vulkanCommandBuffer->boundDescriptorSetDataCount].descriptorSet = descriptorSet;
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDatas[vulkanCommandBuffer->boundDescriptorSetDataCount].descriptorSetPool = descriptorSetPool;
|
|
|
- vulkanCommandBuffer->boundDescriptorSetDataCount += 1;
|
|
|
+ VkDescriptorSet descriptorSet = pool->descriptorSets[pool->descriptorSetIndex];
|
|
|
+ pool->descriptorSetIndex += 1;
|
|
|
|
|
|
return descriptorSet;
|
|
|
}
|
|
@@ -4814,34 +4874,44 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
VulkanCommandBuffer *commandBuffer)
|
|
|
{
|
|
|
VulkanGraphicsPipelineResourceLayout *resourceLayout;
|
|
|
- VkWriteDescriptorSet *writeDescriptorSets;
|
|
|
- VkWriteDescriptorSet *currentWriteDescriptorSet;
|
|
|
- DescriptorSetPool *descriptorSetPool;
|
|
|
- VkDescriptorBufferInfo bufferInfos[MAX_STORAGE_BUFFERS_PER_STAGE];
|
|
|
- VkDescriptorImageInfo imageInfos[MAX_TEXTURE_SAMPLERS_PER_STAGE + MAX_STORAGE_TEXTURES_PER_STAGE];
|
|
|
- Uint32 dynamicOffsets[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
+ DescriptorSetLayout *descriptorSetLayout;
|
|
|
+ VkWriteDescriptorSet writeDescriptorSets[
|
|
|
+ (MAX_TEXTURE_SAMPLERS_PER_STAGE +
|
|
|
+ MAX_STORAGE_TEXTURES_PER_STAGE +
|
|
|
+ MAX_STORAGE_BUFFERS_PER_STAGE +
|
|
|
+ MAX_UNIFORM_BUFFERS_PER_STAGE) * 2];
|
|
|
+ VkDescriptorBufferInfo bufferInfos[MAX_STORAGE_BUFFERS_PER_STAGE * 2];
|
|
|
+ VkDescriptorImageInfo imageInfos[(MAX_TEXTURE_SAMPLERS_PER_STAGE + MAX_STORAGE_TEXTURES_PER_STAGE) * 2];
|
|
|
+ Uint32 dynamicOffsets[MAX_UNIFORM_BUFFERS_PER_STAGE * 2];
|
|
|
+ Uint32 writeCount = 0;
|
|
|
Uint32 bufferInfoCount = 0;
|
|
|
Uint32 imageInfoCount = 0;
|
|
|
- Uint32 i;
|
|
|
+ Uint32 dynamicOffsetCount = 0;
|
|
|
+
|
|
|
+ if (
|
|
|
+ !commandBuffer->needNewVertexResourceDescriptorSet &&
|
|
|
+ !commandBuffer->needNewVertexUniformDescriptorSet &&
|
|
|
+ !commandBuffer->needNewVertexUniformOffsets &&
|
|
|
+ !commandBuffer->needNewFragmentResourceDescriptorSet &&
|
|
|
+ !commandBuffer->needNewFragmentUniformDescriptorSet &&
|
|
|
+ !commandBuffer->needNewFragmentUniformOffsets
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- resourceLayout = &commandBuffer->currentGraphicsPipeline->resourceLayout;
|
|
|
+ resourceLayout = commandBuffer->currentGraphicsPipeline->resourceLayout;
|
|
|
|
|
|
if (commandBuffer->needNewVertexResourceDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[0];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[0];
|
|
|
|
|
|
commandBuffer->vertexResourceDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->vertexSamplerCount +
|
|
|
- resourceLayout->vertexStorageTextureCount +
|
|
|
- resourceLayout->vertexStorageBufferCount);
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->vertexSamplerCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->vertexSamplerCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
|
currentWriteDescriptorSet->descriptorCount = 1;
|
|
@@ -4858,11 +4928,12 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->vertexStorageTextureCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->vertexSamplerCount + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->vertexStorageTextureCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -4880,11 +4951,12 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->vertexStorageBufferCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->vertexSamplerCount + resourceLayout->vertexStorageTextureCount + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->vertexStorageBufferCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -4902,47 +4974,23 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->vertexSamplerCount + resourceLayout->vertexStorageTextureCount + resourceLayout->vertexStorageBufferCount,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- &commandBuffer->vertexResourceDescriptorSet,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewVertexResourceDescriptorSet = false;
|
|
|
}
|
|
|
|
|
|
if (commandBuffer->needNewVertexUniformDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[1];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[1];
|
|
|
|
|
|
commandBuffer->vertexUniformDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
-
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->vertexUniformBufferCount);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->vertexUniformBufferCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->vertexUniformBufferCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -4960,58 +5008,29 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->vertexUniformBufferCount,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewVertexUniformDescriptorSet = false;
|
|
|
- commandBuffer->needNewVertexUniformOffsets = true;
|
|
|
}
|
|
|
|
|
|
- if (commandBuffer->needNewVertexUniformOffsets) {
|
|
|
- for (i = 0; i < resourceLayout->vertexUniformBufferCount; i += 1) {
|
|
|
- dynamicOffsets[i] = commandBuffer->vertexUniformBuffers[i]->drawOffset;
|
|
|
- }
|
|
|
-
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 1,
|
|
|
- 1,
|
|
|
- &commandBuffer->vertexUniformDescriptorSet,
|
|
|
- resourceLayout->vertexUniformBufferCount,
|
|
|
- dynamicOffsets);
|
|
|
-
|
|
|
- commandBuffer->needNewVertexUniformOffsets = false;
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->vertexUniformBufferCount; i += 1) {
|
|
|
+ dynamicOffsets[dynamicOffsetCount] = commandBuffer->vertexUniformBuffers[i]->drawOffset;
|
|
|
+ dynamicOffsetCount += 1;
|
|
|
}
|
|
|
|
|
|
if (commandBuffer->needNewFragmentResourceDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[2];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[2];
|
|
|
|
|
|
commandBuffer->fragmentResourceDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->fragmentSamplerCount +
|
|
|
- resourceLayout->fragmentStorageTextureCount +
|
|
|
- resourceLayout->fragmentStorageBufferCount);
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->fragmentSamplerCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->fragmentSamplerCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
|
currentWriteDescriptorSet->descriptorCount = 1;
|
|
@@ -5028,11 +5047,12 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->fragmentStorageTextureCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->fragmentSamplerCount + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->fragmentStorageTextureCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -5050,11 +5070,12 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->fragmentStorageBufferCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->fragmentSamplerCount + resourceLayout->fragmentStorageTextureCount + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->fragmentStorageBufferCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -5072,47 +5093,23 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->fragmentSamplerCount + resourceLayout->fragmentStorageTextureCount + resourceLayout->fragmentStorageBufferCount,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 2,
|
|
|
- 1,
|
|
|
- &commandBuffer->fragmentResourceDescriptorSet,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewFragmentResourceDescriptorSet = false;
|
|
|
}
|
|
|
|
|
|
if (commandBuffer->needNewFragmentUniformDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[3];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[3];
|
|
|
|
|
|
commandBuffer->fragmentUniformDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->fragmentUniformBufferCount);
|
|
|
-
|
|
|
- for (i = 0; i < resourceLayout->fragmentUniformBufferCount; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->fragmentUniformBufferCount; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -5130,41 +5127,43 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->fragmentUniformBufferCount,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewFragmentUniformDescriptorSet = false;
|
|
|
- commandBuffer->needNewFragmentUniformOffsets = true;
|
|
|
}
|
|
|
|
|
|
- if (commandBuffer->needNewFragmentUniformOffsets) {
|
|
|
- for (i = 0; i < resourceLayout->fragmentUniformBufferCount; i += 1) {
|
|
|
- dynamicOffsets[i] = commandBuffer->fragmentUniformBuffers[i]->drawOffset;
|
|
|
- }
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->fragmentUniformBufferCount; i += 1) {
|
|
|
+ dynamicOffsets[dynamicOffsetCount] = commandBuffer->fragmentUniformBuffers[i]->drawOffset;
|
|
|
+ dynamicOffsetCount += 1;
|
|
|
+ }
|
|
|
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 3,
|
|
|
- 1,
|
|
|
- &commandBuffer->fragmentUniformDescriptorSet,
|
|
|
- resourceLayout->fragmentUniformBufferCount,
|
|
|
- dynamicOffsets);
|
|
|
+ renderer->vkUpdateDescriptorSets(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ writeCount,
|
|
|
+ writeDescriptorSets,
|
|
|
+ 0,
|
|
|
+ NULL);
|
|
|
|
|
|
- commandBuffer->needNewFragmentUniformOffsets = false;
|
|
|
- }
|
|
|
+ VkDescriptorSet sets[4];
|
|
|
+ sets[0] = commandBuffer->vertexResourceDescriptorSet;
|
|
|
+ sets[1] = commandBuffer->vertexUniformDescriptorSet;
|
|
|
+ sets[2] = commandBuffer->fragmentResourceDescriptorSet;
|
|
|
+ sets[3] = commandBuffer->fragmentUniformDescriptorSet;
|
|
|
+
|
|
|
+ renderer->vkCmdBindDescriptorSets(
|
|
|
+ commandBuffer->commandBuffer,
|
|
|
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
+ resourceLayout->pipelineLayout,
|
|
|
+ 0,
|
|
|
+ 4,
|
|
|
+ sets,
|
|
|
+ dynamicOffsetCount,
|
|
|
+ dynamicOffsets);
|
|
|
+
|
|
|
+ commandBuffer->needNewVertexUniformOffsets = false;
|
|
|
+ commandBuffer->needNewFragmentUniformOffsets = false;
|
|
|
}
|
|
|
|
|
|
static void VULKAN_DrawIndexedPrimitives(
|
|
@@ -6283,11 +6282,13 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline(
|
|
|
|
|
|
// Pipeline Layout
|
|
|
|
|
|
- if (!VULKAN_INTERNAL_InitializeGraphicsPipelineResourceLayout(
|
|
|
+ graphicsPipeline->resourceLayout =
|
|
|
+ VULKAN_INTERNAL_FetchGraphicsPipelineResourceLayout(
|
|
|
renderer,
|
|
|
graphicsPipeline->vertexShader,
|
|
|
- graphicsPipeline->fragmentShader,
|
|
|
- &graphicsPipeline->resourceLayout)) {
|
|
|
+ graphicsPipeline->fragmentShader);
|
|
|
+
|
|
|
+ if (graphicsPipeline->resourceLayout == NULL) {
|
|
|
SDL_stack_free(vertexInputBindingDescriptions);
|
|
|
SDL_stack_free(vertexInputAttributeDescriptions);
|
|
|
SDL_stack_free(colorBlendAttachmentStates);
|
|
@@ -6313,7 +6314,7 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline(
|
|
|
vkPipelineCreateInfo.pDepthStencilState = &depthStencilStateCreateInfo;
|
|
|
vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo;
|
|
|
vkPipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
|
|
|
- vkPipelineCreateInfo.layout = graphicsPipeline->resourceLayout.pipelineLayout;
|
|
|
+ vkPipelineCreateInfo.layout = graphicsPipeline->resourceLayout->pipelineLayout;
|
|
|
vkPipelineCreateInfo.renderPass = transientRenderPass;
|
|
|
vkPipelineCreateInfo.subpass = 0;
|
|
|
vkPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
|
|
@@ -6358,7 +6359,6 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
|
|
|
VkComputePipelineCreateInfo vkShaderCreateInfo;
|
|
|
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo;
|
|
|
VkResult vulkanResult;
|
|
|
- Uint32 i;
|
|
|
VulkanRenderer *renderer = (VulkanRenderer *)driverData;
|
|
|
VulkanComputePipeline *vulkanComputePipeline;
|
|
|
|
|
@@ -6395,10 +6395,11 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
|
|
|
pipelineShaderStageCreateInfo.pName = createinfo->entrypoint;
|
|
|
pipelineShaderStageCreateInfo.pSpecializationInfo = NULL;
|
|
|
|
|
|
- if (!VULKAN_INTERNAL_InitializeComputePipelineResourceLayout(
|
|
|
- renderer,
|
|
|
- createinfo,
|
|
|
- &vulkanComputePipeline->resourceLayout)) {
|
|
|
+ vulkanComputePipeline->resourceLayout = VULKAN_INTERNAL_FetchComputePipelineResourceLayout(
|
|
|
+ renderer,
|
|
|
+ createinfo);
|
|
|
+
|
|
|
+ if (vulkanComputePipeline->resourceLayout == NULL) {
|
|
|
renderer->vkDestroyShaderModule(
|
|
|
renderer->logicalDevice,
|
|
|
vulkanComputePipeline->shaderModule,
|
|
@@ -6411,8 +6412,7 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
|
|
|
vkShaderCreateInfo.pNext = NULL;
|
|
|
vkShaderCreateInfo.flags = 0;
|
|
|
vkShaderCreateInfo.stage = pipelineShaderStageCreateInfo;
|
|
|
- vkShaderCreateInfo.layout =
|
|
|
- vulkanComputePipeline->resourceLayout.pipelineLayout;
|
|
|
+ vkShaderCreateInfo.layout = vulkanComputePipeline->resourceLayout->pipelineLayout;
|
|
|
vkShaderCreateInfo.basePipelineHandle = (VkPipeline)VK_NULL_HANDLE;
|
|
|
vkShaderCreateInfo.basePipelineIndex = 0;
|
|
|
|
|
@@ -6425,24 +6425,9 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
|
|
|
&vulkanComputePipeline->pipeline);
|
|
|
|
|
|
if (vulkanResult != VK_SUCCESS) {
|
|
|
- renderer->vkDestroyPipelineLayout(
|
|
|
- renderer->logicalDevice,
|
|
|
- vulkanComputePipeline->resourceLayout.pipelineLayout,
|
|
|
- NULL);
|
|
|
-
|
|
|
- for (i = 0; i < 3; i += 1) {
|
|
|
- VULKAN_INTERNAL_DestroyDescriptorSetPool(
|
|
|
- renderer,
|
|
|
- &vulkanComputePipeline->resourceLayout.descriptorSetPools[i]);
|
|
|
- }
|
|
|
-
|
|
|
- renderer->vkDestroyShaderModule(
|
|
|
- renderer->logicalDevice,
|
|
|
- vulkanComputePipeline->shaderModule,
|
|
|
- NULL);
|
|
|
-
|
|
|
LogVulkanResultAsError("vkCreateComputePipeline", vulkanResult);
|
|
|
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create compute pipeline!");
|
|
|
+ VULKAN_INTERNAL_DestroyComputePipeline(renderer, vulkanComputePipeline);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
@@ -7667,14 +7652,14 @@ static void VULKAN_BindGraphicsPipeline(
|
|
|
VULKAN_INTERNAL_TrackGraphicsPipeline(vulkanCommandBuffer, pipeline);
|
|
|
|
|
|
// Acquire uniform buffers if necessary
|
|
|
- for (Uint32 i = 0; i < pipeline->resourceLayout.vertexUniformBufferCount; i += 1) {
|
|
|
+ for (Uint32 i = 0; i < pipeline->resourceLayout->vertexUniformBufferCount; i += 1) {
|
|
|
if (vulkanCommandBuffer->vertexUniformBuffers[i] == NULL) {
|
|
|
vulkanCommandBuffer->vertexUniformBuffers[i] = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
|
|
|
vulkanCommandBuffer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for (Uint32 i = 0; i < pipeline->resourceLayout.fragmentUniformBufferCount; i += 1) {
|
|
|
+ for (Uint32 i = 0; i < pipeline->resourceLayout->fragmentUniformBufferCount; i += 1) {
|
|
|
if (vulkanCommandBuffer->fragmentUniformBuffers[i] == NULL) {
|
|
|
vulkanCommandBuffer->fragmentUniformBuffers[i] = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
|
|
|
vulkanCommandBuffer);
|
|
@@ -7899,7 +7884,7 @@ static void VULKAN_BindComputePipeline(
|
|
|
VULKAN_INTERNAL_TrackComputePipeline(vulkanCommandBuffer, vulkanComputePipeline);
|
|
|
|
|
|
// Acquire uniform buffers if necessary
|
|
|
- for (Uint32 i = 0; i < vulkanComputePipeline->resourceLayout.numUniformBuffers; i += 1) {
|
|
|
+ for (Uint32 i = 0; i < vulkanComputePipeline->resourceLayout->numUniformBuffers; i += 1) {
|
|
|
if (vulkanCommandBuffer->computeUniformBuffers[i] == NULL) {
|
|
|
vulkanCommandBuffer->computeUniformBuffers[i] = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
|
|
|
vulkanCommandBuffer);
|
|
@@ -8034,34 +8019,44 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
VulkanCommandBuffer *commandBuffer)
|
|
|
{
|
|
|
VulkanComputePipelineResourceLayout *resourceLayout;
|
|
|
- VkWriteDescriptorSet *writeDescriptorSets;
|
|
|
- VkWriteDescriptorSet *currentWriteDescriptorSet;
|
|
|
- DescriptorSetPool *descriptorSetPool;
|
|
|
- VkDescriptorBufferInfo bufferInfos[MAX_STORAGE_BUFFERS_PER_STAGE]; // 8 is max for both read and write
|
|
|
- VkDescriptorImageInfo imageInfos[MAX_TEXTURE_SAMPLERS_PER_STAGE + MAX_STORAGE_TEXTURES_PER_STAGE];
|
|
|
+ DescriptorSetLayout *descriptorSetLayout;
|
|
|
+ VkWriteDescriptorSet writeDescriptorSets[
|
|
|
+ MAX_TEXTURE_SAMPLERS_PER_STAGE +
|
|
|
+ MAX_STORAGE_TEXTURES_PER_STAGE +
|
|
|
+ MAX_STORAGE_BUFFERS_PER_STAGE +
|
|
|
+ MAX_COMPUTE_WRITE_TEXTURES +
|
|
|
+ MAX_COMPUTE_WRITE_BUFFERS +
|
|
|
+ MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
+ VkDescriptorBufferInfo bufferInfos[MAX_STORAGE_BUFFERS_PER_STAGE + MAX_COMPUTE_WRITE_BUFFERS + MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
+ VkDescriptorImageInfo imageInfos[MAX_TEXTURE_SAMPLERS_PER_STAGE + MAX_STORAGE_TEXTURES_PER_STAGE + MAX_COMPUTE_WRITE_TEXTURES];
|
|
|
Uint32 dynamicOffsets[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
|
|
+ Uint32 writeCount = 0;
|
|
|
Uint32 bufferInfoCount = 0;
|
|
|
Uint32 imageInfoCount = 0;
|
|
|
- Uint32 i;
|
|
|
+ Uint32 dynamicOffsetCount = 0;
|
|
|
+
|
|
|
+ if (
|
|
|
+ !commandBuffer->needNewComputeReadOnlyDescriptorSet &&
|
|
|
+ !commandBuffer->needNewComputeWriteOnlyDescriptorSet &&
|
|
|
+ !commandBuffer->needNewComputeUniformDescriptorSet &&
|
|
|
+ !commandBuffer->needNewComputeUniformOffsets
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- resourceLayout = &commandBuffer->currentComputePipeline->resourceLayout;
|
|
|
+ resourceLayout = commandBuffer->currentComputePipeline->resourceLayout;
|
|
|
|
|
|
if (commandBuffer->needNewComputeReadOnlyDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[0];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[0];
|
|
|
|
|
|
commandBuffer->computeReadOnlyDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->numSamplers +
|
|
|
- resourceLayout->numReadonlyStorageTextures +
|
|
|
- resourceLayout->numReadonlyStorageBuffers);
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numSamplers; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numSamplers; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
|
currentWriteDescriptorSet->descriptorCount = 1;
|
|
@@ -8078,11 +8073,13 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numReadonlyStorageTextures; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numReadonlyStorageTextures; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
+
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
|
currentWriteDescriptorSet->descriptorCount = 1;
|
|
@@ -8099,11 +8096,12 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numReadonlyStorageBuffers; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->numReadonlyStorageTextures + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numReadonlyStorageBuffers; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -8121,48 +8119,23 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->numSamplers + resourceLayout->numReadonlyStorageTextures + resourceLayout->numReadonlyStorageBuffers,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- &commandBuffer->computeReadOnlyDescriptorSet,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewComputeReadOnlyDescriptorSet = false;
|
|
|
}
|
|
|
|
|
|
if (commandBuffer->needNewComputeWriteOnlyDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[1];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[1];
|
|
|
|
|
|
commandBuffer->computeWriteOnlyDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
-
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->numWriteonlyStorageTextures +
|
|
|
- resourceLayout->numWriteonlyStorageBuffers);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numWriteonlyStorageTextures; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numWriteonlyStorageTextures; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -8180,11 +8153,12 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
imageInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numWriteonlyStorageBuffers; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[resourceLayout->numWriteonlyStorageTextures + i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numWriteonlyStorageBuffers; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -8202,47 +8176,24 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->numWriteonlyStorageTextures + resourceLayout->numWriteonlyStorageBuffers,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 1,
|
|
|
- 1,
|
|
|
- &commandBuffer->computeWriteOnlyDescriptorSet,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewComputeWriteOnlyDescriptorSet = false;
|
|
|
}
|
|
|
|
|
|
if (commandBuffer->needNewComputeUniformDescriptorSet) {
|
|
|
- descriptorSetPool = &resourceLayout->descriptorSetPools[2];
|
|
|
+ descriptorSetLayout = resourceLayout->descriptorSetLayouts[2];
|
|
|
|
|
|
commandBuffer->computeUniformDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
|
|
|
renderer,
|
|
|
commandBuffer,
|
|
|
- descriptorSetPool);
|
|
|
+ descriptorSetLayout);
|
|
|
|
|
|
- writeDescriptorSets = SDL_stack_alloc(
|
|
|
- VkWriteDescriptorSet,
|
|
|
- resourceLayout->numUniformBuffers);
|
|
|
|
|
|
- for (i = 0; i < resourceLayout->numUniformBuffers; i += 1) {
|
|
|
- currentWriteDescriptorSet = &writeDescriptorSets[i];
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numUniformBuffers; i += 1) {
|
|
|
+ VkWriteDescriptorSet *currentWriteDescriptorSet = &writeDescriptorSets[writeCount];
|
|
|
|
|
|
currentWriteDescriptorSet->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
currentWriteDescriptorSet->pNext = NULL;
|
|
@@ -8260,41 +8211,41 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
|
|
|
|
|
currentWriteDescriptorSet->pBufferInfo = &bufferInfos[bufferInfoCount];
|
|
|
|
|
|
+ writeCount += 1;
|
|
|
bufferInfoCount += 1;
|
|
|
}
|
|
|
|
|
|
- renderer->vkUpdateDescriptorSets(
|
|
|
- renderer->logicalDevice,
|
|
|
- resourceLayout->numUniformBuffers,
|
|
|
- writeDescriptorSets,
|
|
|
- 0,
|
|
|
- NULL);
|
|
|
-
|
|
|
- SDL_stack_free(writeDescriptorSets);
|
|
|
- bufferInfoCount = 0;
|
|
|
- imageInfoCount = 0;
|
|
|
-
|
|
|
commandBuffer->needNewComputeUniformDescriptorSet = false;
|
|
|
- commandBuffer->needNewComputeUniformOffsets = true;
|
|
|
}
|
|
|
|
|
|
- if (commandBuffer->needNewComputeUniformOffsets) {
|
|
|
- for (i = 0; i < resourceLayout->numUniformBuffers; i += 1) {
|
|
|
- dynamicOffsets[i] = commandBuffer->computeUniformBuffers[i]->drawOffset;
|
|
|
- }
|
|
|
+ for (Uint32 i = 0; i < resourceLayout->numUniformBuffers; i += 1) {
|
|
|
+ dynamicOffsets[i] = commandBuffer->computeUniformBuffers[i]->drawOffset;
|
|
|
+ dynamicOffsetCount += 1;
|
|
|
+ }
|
|
|
|
|
|
- renderer->vkCmdBindDescriptorSets(
|
|
|
- commandBuffer->commandBuffer,
|
|
|
- VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
|
- resourceLayout->pipelineLayout,
|
|
|
- 2,
|
|
|
- 1,
|
|
|
- &commandBuffer->computeUniformDescriptorSet,
|
|
|
- resourceLayout->numUniformBuffers,
|
|
|
- dynamicOffsets);
|
|
|
+ renderer->vkUpdateDescriptorSets(
|
|
|
+ renderer->logicalDevice,
|
|
|
+ writeCount,
|
|
|
+ writeDescriptorSets,
|
|
|
+ 0,
|
|
|
+ NULL);
|
|
|
|
|
|
- commandBuffer->needNewComputeUniformOffsets = false;
|
|
|
- }
|
|
|
+ VkDescriptorSet sets[3];
|
|
|
+ sets[0] = commandBuffer->computeReadOnlyDescriptorSet;
|
|
|
+ sets[1] = commandBuffer->computeWriteOnlyDescriptorSet;
|
|
|
+ sets[2] = commandBuffer->computeUniformDescriptorSet;
|
|
|
+
|
|
|
+ renderer->vkCmdBindDescriptorSets(
|
|
|
+ commandBuffer->commandBuffer,
|
|
|
+ VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
|
+ resourceLayout->pipelineLayout,
|
|
|
+ 0,
|
|
|
+ 3,
|
|
|
+ sets,
|
|
|
+ dynamicOffsetCount,
|
|
|
+ dynamicOffsets);
|
|
|
+
|
|
|
+ commandBuffer->needNewVertexUniformOffsets = false;
|
|
|
}
|
|
|
|
|
|
static void VULKAN_DispatchCompute(
|
|
@@ -9039,13 +8990,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers(
|
|
|
commandBuffer->signalSemaphores = SDL_malloc(
|
|
|
commandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore));
|
|
|
|
|
|
- // Descriptor set tracking
|
|
|
-
|
|
|
- commandBuffer->boundDescriptorSetDataCapacity = 16;
|
|
|
- commandBuffer->boundDescriptorSetDataCount = 0;
|
|
|
- commandBuffer->boundDescriptorSetDatas = SDL_malloc(
|
|
|
- commandBuffer->boundDescriptorSetDataCapacity * sizeof(DescriptorSetData));
|
|
|
-
|
|
|
// Resource bind tracking
|
|
|
|
|
|
commandBuffer->needNewVertexResourceDescriptorSet = true;
|
|
@@ -9215,6 +9159,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
|
|
VulkanCommandBuffer *commandBuffer =
|
|
|
VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(renderer, threadID);
|
|
|
|
|
|
+ commandBuffer->descriptorSetCache = VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
|
|
|
+
|
|
|
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
|
|
|
|
|
if (commandBuffer == NULL) {
|
|
@@ -9933,9 +9879,6 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
|
|
VulkanRenderer *renderer,
|
|
|
VulkanCommandBuffer *commandBuffer)
|
|
|
{
|
|
|
- Uint32 i;
|
|
|
- DescriptorSetData *descriptorSetData;
|
|
|
-
|
|
|
if (commandBuffer->autoReleaseFence) {
|
|
|
VULKAN_ReleaseFence(
|
|
|
(SDL_GPURenderer *)renderer,
|
|
@@ -9944,33 +9887,11 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
|
|
commandBuffer->inFlightFence = NULL;
|
|
|
}
|
|
|
|
|
|
- // Bound descriptor sets are now available
|
|
|
-
|
|
|
- for (i = 0; i < commandBuffer->boundDescriptorSetDataCount; i += 1) {
|
|
|
- descriptorSetData = &commandBuffer->boundDescriptorSetDatas[i];
|
|
|
-
|
|
|
- SDL_TryLockSpinlock(&descriptorSetData->descriptorSetPool->lock);
|
|
|
-
|
|
|
- if (descriptorSetData->descriptorSetPool->inactiveDescriptorSetCount == descriptorSetData->descriptorSetPool->inactiveDescriptorSetCapacity) {
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSetCapacity *= 2;
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSets = SDL_realloc(
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSets,
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSetCapacity * sizeof(VkDescriptorSet));
|
|
|
- }
|
|
|
-
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSets[descriptorSetData->descriptorSetPool->inactiveDescriptorSetCount] = descriptorSetData->descriptorSet;
|
|
|
- descriptorSetData->descriptorSetPool->inactiveDescriptorSetCount += 1;
|
|
|
-
|
|
|
- SDL_UnlockSpinlock(&descriptorSetData->descriptorSetPool->lock);
|
|
|
- }
|
|
|
-
|
|
|
- commandBuffer->boundDescriptorSetDataCount = 0;
|
|
|
-
|
|
|
// Uniform buffers are now available
|
|
|
|
|
|
SDL_LockMutex(renderer->acquireUniformBufferLock);
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
|
|
|
VULKAN_INTERNAL_ReturnUniformBufferToPool(
|
|
|
renderer,
|
|
|
commandBuffer->usedUniformBuffers[i]);
|
|
@@ -9981,32 +9902,32 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
|
|
|
|
|
// Decrement reference counts
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedBufferCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedBufferCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedBuffers[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedBufferCount = 0;
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedTextureCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedTextureCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedTextures[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedTextureCount = 0;
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedSamplerCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedSamplerCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedSamplers[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedSamplerCount = 0;
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedGraphicsPipelineCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedGraphicsPipelineCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedGraphicsPipelines[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedGraphicsPipelineCount = 0;
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedComputePipelineCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedComputePipelineCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedComputePipelines[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedComputePipelineCount = 0;
|
|
|
|
|
|
- for (i = 0; i < commandBuffer->usedFramebufferCount; i += 1) {
|
|
|
+ for (Sint32 i = 0; i < commandBuffer->usedFramebufferCount; i += 1) {
|
|
|
(void)SDL_AtomicDecRef(&commandBuffer->usedFramebuffers[i]->referenceCount);
|
|
|
}
|
|
|
commandBuffer->usedFramebufferCount = 0;
|
|
@@ -10037,10 +9958,18 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
|
|
commandBuffer->commandPool->inactiveCommandBuffers[commandBuffer->commandPool->inactiveCommandBufferCount] = commandBuffer;
|
|
|
commandBuffer->commandPool->inactiveCommandBufferCount += 1;
|
|
|
|
|
|
+ // Release descriptor set cache
|
|
|
+
|
|
|
+ VULKAN_INTERNAL_ReturnDescriptorSetCacheToPool(
|
|
|
+ renderer,
|
|
|
+ commandBuffer->descriptorSetCache);
|
|
|
+
|
|
|
+ commandBuffer->descriptorSetCache = NULL;
|
|
|
+
|
|
|
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
|
|
|
|
|
// Remove this command buffer from the submitted list
|
|
|
- for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) {
|
|
|
+ for (Uint32 i = 0; i < renderer->submittedCommandBufferCount; i += 1) {
|
|
|
if (renderer->submittedCommandBuffers[i] == commandBuffer) {
|
|
|
renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1];
|
|
|
renderer->submittedCommandBufferCount -= 1;
|
|
@@ -11397,6 +11326,12 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
|
|
UNIFORM_BUFFER_SIZE);
|
|
|
}
|
|
|
|
|
|
+ renderer->descriptorSetCachePoolCapacity = 8;
|
|
|
+ renderer->descriptorSetCachePoolCount = 0;
|
|
|
+ renderer->descriptorSetCachePool = SDL_calloc(renderer->descriptorSetCachePoolCapacity, sizeof(DescriptorSetCache *));
|
|
|
+
|
|
|
+ SDL_SetAtomicInt(&renderer->layoutResourceID, 0);
|
|
|
+
|
|
|
// Device limits
|
|
|
|
|
|
renderer->minUBOAlignment = (Uint32)renderer->physicalDeviceProperties.properties.limits.minUniformBufferOffsetAlignment;
|
|
@@ -11427,6 +11362,30 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
|
|
VULKAN_INTERNAL_FramebufferHashNuke,
|
|
|
false);
|
|
|
|
|
|
+ renderer->graphicsPipelineResourceLayoutHashTable = SDL_CreateHashTable(
|
|
|
+ (void *)renderer,
|
|
|
+ 64,
|
|
|
+ VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashFunction,
|
|
|
+ VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashKeyMatch,
|
|
|
+ VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashNuke,
|
|
|
+ false);
|
|
|
+
|
|
|
+ renderer->computePipelineResourceLayoutHashTable = SDL_CreateHashTable(
|
|
|
+ (void *)renderer,
|
|
|
+ 64,
|
|
|
+ VULKAN_INTERNAL_ComputePipelineResourceLayoutHashFunction,
|
|
|
+ VULKAN_INTERNAL_ComputePipelineResourceLayoutHashKeyMatch,
|
|
|
+ VULKAN_INTERNAL_ComputePipelineResourceLayoutHashNuke,
|
|
|
+ false);
|
|
|
+
|
|
|
+ renderer->descriptorSetLayoutHashTable = SDL_CreateHashTable(
|
|
|
+ (void *)renderer,
|
|
|
+ 64,
|
|
|
+ VULKAN_INTERNAL_DescriptorSetLayoutHashFunction,
|
|
|
+ VULKAN_INTERNAL_DescriptorSetLayoutHashKeyMatch,
|
|
|
+ VULKAN_INTERNAL_DescriptorSetLayoutHashNuke,
|
|
|
+ false);
|
|
|
+
|
|
|
// Initialize fence pool
|
|
|
|
|
|
renderer->fencePool.lock = SDL_CreateMutex();
|