descriptor set cacheing system

submit_rewrite
cosmonaut 2020-12-27 15:20:59 -08:00
parent d23b2a6a75
commit 3780772bdd
1 changed files with 359 additions and 140 deletions

View File

@ -74,7 +74,7 @@ static uint32_t deviceExtensionCount = SDL_arraysize(deviceExtensionNames);
#define TEXTURE_STAGING_SIZE 8000000 /* 8MB */ #define TEXTURE_STAGING_SIZE 8000000 /* 8MB */
#define UBO_BUFFER_SIZE 8000000 /* 8MB */ #define UBO_BUFFER_SIZE 8000000 /* 8MB */
#define UBO_ACTUAL_SIZE (UBO_BUFFER_SIZE * 2) #define UBO_ACTUAL_SIZE (UBO_BUFFER_SIZE * 2)
#define SAMPLER_POOL_SIZE 100 #define SAMPLER_POOL_STARTING_SIZE 128
#define UBO_POOL_SIZE 1000 #define UBO_POOL_SIZE 1000
#define SUB_BUFFER_COUNT 2 #define SUB_BUFFER_COUNT 2
@ -651,14 +651,13 @@ typedef struct SwapChainSupportDetails
uint32_t presentModesLength; uint32_t presentModesLength;
} SwapChainSupportDetails; } SwapChainSupportDetails;
typedef struct SamplerDescriptorSetCache SamplerDescriptorSetCache;
typedef struct VulkanGraphicsPipelineLayout typedef struct VulkanGraphicsPipelineLayout
{ {
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkDescriptorSetLayout vertexSamplerLayout; SamplerDescriptorSetCache *vertexSamplerDescriptorSetCache;
uint32_t vertexSamplerBindingCount; SamplerDescriptorSetCache *fragmentSamplerDescriptorSetCache;
VkDescriptorSetLayout fragmentSamplerLayout;
uint32_t fragmentSamplerBindingCount;
VkDescriptorPool descriptorPool;
} VulkanGraphicsPipelineLayout; } VulkanGraphicsPipelineLayout;
typedef struct VulkanGraphicsPipeline typedef struct VulkanGraphicsPipeline
@ -886,6 +885,64 @@ static inline void PipelineLayoutHashArray_Insert(
arr->count += 1; arr->count += 1;
} }
typedef struct SamplerDescriptorSetData
{
VkDescriptorImageInfo descriptorImageInfo[MAX_TEXTURE_SAMPLERS]; /* used for vertex samplers as well */
} SamplerDescriptorSetData;
typedef struct SamplerDescriptorSetHashMap
{
uint64_t key;
SamplerDescriptorSetData descriptorSetData;
VkDescriptorSet descriptorSet;
uint8_t inactiveFrameCount;
} SamplerDescriptorSetHashMap;
typedef struct SamplerDescriptorSetHashArray
{
uint32_t *elements;
int32_t count;
int32_t capacity;
} SamplerDescriptorSetHashArray;
#define NUM_DESCRIPTOR_SET_HASH_BUCKETS 1031
static inline uint64_t SamplerDescriptorSetHashTable_GetHashCode(
SamplerDescriptorSetData *descriptorSetData,
uint32_t samplerCount
) {
const uint64_t HASH_FACTOR = 97;
uint32_t i;
uint64_t result = 1;
for (i = 0; i < samplerCount; i++)
{
result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorImageInfo[i].imageView;
result = result * HASH_FACTOR + (uint64_t) descriptorSetData->descriptorImageInfo[i].sampler;
}
return result;
}
struct SamplerDescriptorSetCache
{
VkDescriptorSetLayout descriptorSetLayout;
uint32_t samplerBindingCount;
SamplerDescriptorSetHashArray buckets[NUM_DESCRIPTOR_SET_HASH_BUCKETS]; /* these buckets store indices */
SamplerDescriptorSetHashMap *elements; /* where the hash map elements are stored */
uint32_t count;
uint32_t capacity;
VkDescriptorPool *samplerDescriptorPools;
uint32_t samplerDescriptorPoolCount;
uint32_t nextPoolSize;
VkDescriptorSet *inactiveDescriptorSets;
uint32_t inactiveDescriptorSetCount;
uint32_t inactiveDescriptorSetCapacity;
};
/* Context */ /* Context */
typedef struct VulkanRenderer typedef struct VulkanRenderer
@ -2757,25 +2814,25 @@ static REFRESH_RenderPass* VULKAN_CreateRenderPass(
static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool( static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VkDescriptorType descriptorType,
uint32_t descriptorSetCount,
uint32_t descriptorCount,
VkDescriptorPool *pDescriptorPool VkDescriptorPool *pDescriptorPool
) { ) {
VkResult vulkanResult; VkResult vulkanResult;
VkDescriptorPoolSize poolSizes[2]; VkDescriptorPoolSize descriptorPoolSize;
VkDescriptorPoolCreateInfo descriptorPoolInfo; VkDescriptorPoolCreateInfo descriptorPoolInfo;
poolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorPoolSize.type = descriptorType;
poolSizes[0].descriptorCount = SAMPLER_POOL_SIZE; descriptorPoolSize.descriptorCount = descriptorCount;
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[1].descriptorCount = SAMPLER_POOL_SIZE;
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.pNext = NULL; descriptorPoolInfo.pNext = NULL;
descriptorPoolInfo.flags = 0; descriptorPoolInfo.flags = 0;
descriptorPoolInfo.maxSets = 2 * SAMPLER_POOL_SIZE; descriptorPoolInfo.maxSets = descriptorSetCount;
descriptorPoolInfo.poolSizeCount = 2; descriptorPoolInfo.poolSizeCount = 1;
descriptorPoolInfo.pPoolSizes = poolSizes; descriptorPoolInfo.pPoolSizes = &descriptorPoolSize;
vulkanResult = renderer->vkCreateDescriptorPool( vulkanResult = renderer->vkCreateDescriptorPool(
renderer->logicalDevice, renderer->logicalDevice,
@ -2793,6 +2850,84 @@ static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool(
return 1; return 1;
} }
static uint8_t VULKAN_INTERNAL_AllocateSamplerDescriptorSets(
VulkanRenderer *renderer,
VkDescriptorPool descriptorPool,
VkDescriptorSetLayout descriptorSetLayout,
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetArray
) {
VkResult vulkanResult;
uint32_t i;
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo;
VkDescriptorSetLayout *descriptorSetLayouts = SDL_stack_alloc(VkDescriptorSetLayout, descriptorSetCount);
for (i = 0; i < descriptorSetCount; i += 1)
{
descriptorSetLayouts[i] = descriptorSetLayout;
}
descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
descriptorSetAllocateInfo.pNext = NULL;
descriptorSetAllocateInfo.descriptorPool = descriptorPool;
descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount;
descriptorSetAllocateInfo.pSetLayouts = descriptorSetLayouts;
vulkanResult = renderer->vkAllocateDescriptorSets(
renderer->logicalDevice,
&descriptorSetAllocateInfo,
descriptorSetArray
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkAllocateDescriptorSets", vulkanResult);
SDL_stack_free(descriptorSetLayouts);
return 0;
}
SDL_stack_free(descriptorSetLayouts);
return 1;
}
static SamplerDescriptorSetCache* VULKAN_INTERNAL_CreateSamplerDescriptorSetCache(
VulkanRenderer *renderer,
VkDescriptorSetLayout descriptorSetLayout,
uint32_t samplerBindingCount
) {
SamplerDescriptorSetCache *samplerDescriptorSetCache = SDL_malloc(sizeof(samplerDescriptorSetCache));
samplerDescriptorSetCache->descriptorSetLayout = descriptorSetLayout;
samplerDescriptorSetCache->samplerBindingCount = samplerBindingCount;
VULKAN_INTERNAL_CreateSamplerDescriptorPool(
renderer,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
SAMPLER_POOL_STARTING_SIZE,
SAMPLER_POOL_STARTING_SIZE * samplerBindingCount,
&samplerDescriptorSetCache->samplerDescriptorPools[0]
);
samplerDescriptorSetCache->samplerDescriptorPoolCount = 1;
samplerDescriptorSetCache->nextPoolSize = SAMPLER_POOL_STARTING_SIZE * 2;
samplerDescriptorSetCache->inactiveDescriptorSetCapacity = SAMPLER_POOL_STARTING_SIZE;
samplerDescriptorSetCache->inactiveDescriptorSetCount = SAMPLER_POOL_STARTING_SIZE;
samplerDescriptorSetCache->inactiveDescriptorSets = SDL_malloc(
sizeof(VkDescriptorSet) * SAMPLER_POOL_STARTING_SIZE
);
VULKAN_INTERNAL_AllocateSamplerDescriptorSets(
renderer,
samplerDescriptorSetCache->samplerDescriptorPools[0],
samplerDescriptorSetCache->descriptorSetLayout,
SAMPLER_POOL_STARTING_SIZE,
samplerDescriptorSetCache->inactiveDescriptorSets
);
return samplerDescriptorSetCache;
}
static VkDescriptorSetLayout VULKAN_INTERNAL_FetchSamplerDescriptorSetLayout( static VkDescriptorSetLayout VULKAN_INTERNAL_FetchSamplerDescriptorSetLayout(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VkShaderStageFlagBits shaderStageFlagBit, VkShaderStageFlagBits shaderStageFlagBit,
@ -2947,18 +3082,32 @@ static VulkanGraphicsPipelineLayout* VULKAN_INTERNAL_FetchGraphicsPipelineLayout
vulkanGraphicsPipelineLayout vulkanGraphicsPipelineLayout
); );
vulkanGraphicsPipelineLayout->vertexSamplerLayout = pipelineLayoutHash.vertexSamplerLayout; if (vertexSamplerBindingCount == 0)
vulkanGraphicsPipelineLayout->vertexSamplerBindingCount = vertexSamplerBindingCount; {
vulkanGraphicsPipelineLayout->fragmentSamplerLayout = pipelineLayoutHash.fragmentSamplerLayout; vulkanGraphicsPipelineLayout->vertexSamplerDescriptorSetCache = NULL;
vulkanGraphicsPipelineLayout->fragmentSamplerBindingCount = fragmentSamplerBindingCount; }
else
{
vulkanGraphicsPipelineLayout->vertexSamplerDescriptorSetCache =
VULKAN_INTERNAL_CreateSamplerDescriptorSetCache(
renderer,
pipelineLayoutHash.vertexSamplerLayout,
vertexSamplerBindingCount
);
}
/* Create sampler descriptor pool */ if (fragmentSamplerBindingCount == 0)
if (!VULKAN_INTERNAL_CreateSamplerDescriptorPool( {
renderer, vulkanGraphicsPipelineLayout->fragmentSamplerDescriptorSetCache = NULL;
&vulkanGraphicsPipelineLayout->descriptorPool }
)) { else
REFRESH_LogError("Failed to create descriptor pool!"); {
return NULL; vulkanGraphicsPipelineLayout->fragmentSamplerDescriptorSetCache =
VULKAN_INTERNAL_CreateSamplerDescriptorSetCache(
renderer,
pipelineLayoutHash.fragmentSamplerLayout,
fragmentSamplerBindingCount
);
} }
return vulkanGraphicsPipelineLayout; return vulkanGraphicsPipelineLayout;
@ -4711,78 +4860,187 @@ static void VULKAN_PushFragmentShaderParams(
); );
} }
static inline uint8_t SamplerDescriptorSetDataEqual(
SamplerDescriptorSetData *a,
SamplerDescriptorSetData *b,
uint8_t samplerCount
) {
uint32_t i;
for (i = 0; i < samplerCount; i += 1)
{
if ( a->descriptorImageInfo[i].imageLayout != b->descriptorImageInfo[i].imageLayout ||
a->descriptorImageInfo[i].imageView != b->descriptorImageInfo[i].imageView ||
a->descriptorImageInfo[i].sampler != b->descriptorImageInfo[i].sampler )
{
return 0;
}
}
return 1;
}
static VkDescriptorSet VULKAN_INTERNAL_FetchSamplerDescriptorSet(
VulkanRenderer *renderer,
SamplerDescriptorSetCache *samplerDescriptorSetCache,
SamplerDescriptorSetData *samplerDescriptorSetData
) {
uint32_t i;
uint64_t hashcode;
SamplerDescriptorSetHashArray *arr;
VkDescriptorSet newDescriptorSet;
VkWriteDescriptorSet writeDescriptorSets[MAX_TEXTURE_SAMPLERS];
SamplerDescriptorSetHashMap *map;
hashcode = SamplerDescriptorSetHashTable_GetHashCode(
samplerDescriptorSetData,
samplerDescriptorSetCache->samplerBindingCount
);
arr = &samplerDescriptorSetCache->buckets[hashcode % NUM_DESCRIPTOR_SET_HASH_BUCKETS];
for (i = 0; i < arr->count; i += 1)
{
SamplerDescriptorSetHashMap *e = &samplerDescriptorSetCache->elements[arr->elements[i]];
if (SamplerDescriptorSetDataEqual(
samplerDescriptorSetData,
&e->descriptorSetData,
samplerDescriptorSetCache->samplerBindingCount
)) {
e->inactiveFrameCount = 0;
return e->descriptorSet;
}
}
/* If no match exists, assign a new descriptor set and prepare it for update */
/* If no inactive descriptor sets remain, create a new pool and allocate new inactive sets */
if (samplerDescriptorSetCache->inactiveDescriptorSetCount == 0)
{
samplerDescriptorSetCache->samplerDescriptorPoolCount += 1;
samplerDescriptorSetCache->samplerDescriptorPools = SDL_realloc(
samplerDescriptorSetCache->samplerDescriptorPools,
sizeof(VkDescriptorPool) * samplerDescriptorSetCache->samplerDescriptorPoolCount
);
VULKAN_INTERNAL_CreateSamplerDescriptorPool(
renderer,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
samplerDescriptorSetCache->nextPoolSize,
samplerDescriptorSetCache->nextPoolSize * samplerDescriptorSetCache->samplerBindingCount,
&samplerDescriptorSetCache->samplerDescriptorPools[samplerDescriptorSetCache->samplerDescriptorPoolCount - 1]
);
samplerDescriptorSetCache->inactiveDescriptorSetCapacity += samplerDescriptorSetCache->nextPoolSize;
samplerDescriptorSetCache->inactiveDescriptorSets = SDL_realloc(
samplerDescriptorSetCache->inactiveDescriptorSets,
sizeof(VkDescriptorSet) * samplerDescriptorSetCache->inactiveDescriptorSetCapacity
);
VULKAN_INTERNAL_AllocateSamplerDescriptorSets(
renderer,
samplerDescriptorSetCache->samplerDescriptorPools[samplerDescriptorSetCache->samplerDescriptorPoolCount - 1],
samplerDescriptorSetCache->descriptorSetLayout,
samplerDescriptorSetCache->nextPoolSize,
samplerDescriptorSetCache->inactiveDescriptorSets
);
samplerDescriptorSetCache->inactiveDescriptorSetCount = samplerDescriptorSetCache->nextPoolSize;
samplerDescriptorSetCache->nextPoolSize *= 2;
}
newDescriptorSet = samplerDescriptorSetCache->inactiveDescriptorSets[samplerDescriptorSetCache->inactiveDescriptorSetCount - 1];
samplerDescriptorSetCache->inactiveDescriptorSetCount -= 1;
for (i = 0; i < samplerDescriptorSetCache->samplerBindingCount; i += 1)
{
writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[i].pNext = NULL;
writeDescriptorSets[i].descriptorCount = 1;
writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeDescriptorSets[i].dstArrayElement = 0;
writeDescriptorSets[i].dstBinding = i;
writeDescriptorSets[i].dstSet = newDescriptorSet;
writeDescriptorSets[i].pBufferInfo = NULL;
writeDescriptorSets[i].pImageInfo = &samplerDescriptorSetData->descriptorImageInfo[i];
}
renderer->vkUpdateDescriptorSets(
renderer->logicalDevice,
samplerDescriptorSetCache->samplerBindingCount,
writeDescriptorSets,
0,
NULL
);
EXPAND_ARRAY_IF_NEEDED(arr, 2, uint32_t)
arr->elements[arr->count] = samplerDescriptorSetCache->count;
arr->count += 1;
if (samplerDescriptorSetCache->count == samplerDescriptorSetCache->capacity)
{
samplerDescriptorSetCache->capacity *= 2;
samplerDescriptorSetCache->elements = SDL_realloc(
samplerDescriptorSetCache->elements,
sizeof(SamplerDescriptorSetHashMap) * samplerDescriptorSetCache->capacity
);
}
map = &samplerDescriptorSetCache->elements[samplerDescriptorSetCache->count];
map->key = hashcode;
for (i = 0; i < samplerDescriptorSetCache->samplerBindingCount; i += 1)
{
map->descriptorSetData.descriptorImageInfo[i].imageLayout =
samplerDescriptorSetData->descriptorImageInfo[i].imageLayout;
map->descriptorSetData.descriptorImageInfo[i].imageView =
samplerDescriptorSetData->descriptorImageInfo[i].imageView;
map->descriptorSetData.descriptorImageInfo[i].sampler =
samplerDescriptorSetData->descriptorImageInfo[i].sampler;
}
map->descriptorSet = newDescriptorSet;
map->inactiveFrameCount = 0;
samplerDescriptorSetCache->count += 1;
return newDescriptorSet;
}
static void VULKAN_SetVertexSamplers( static void VULKAN_SetVertexSamplers(
REFRESH_Renderer *driverData, REFRESH_Renderer *driverData,
REFRESH_GraphicsPipeline *pipeline, REFRESH_GraphicsPipeline *pipeline,
REFRESH_Texture **pTextures, REFRESH_Texture **pTextures,
REFRESH_Sampler **pSamplers REFRESH_Sampler **pSamplers
) { ) {
/* TODO: we can defer and batch these */
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo;
VkDescriptorSet descriptorSet;
VkWriteDescriptorSet *writeDescriptorSets;
VkDescriptorImageInfo *descriptorImageInfos;
VulkanTexture *currentTexture; VulkanTexture *currentTexture;
VkSampler currentSampler; uint32_t i, samplerCount;
uint32_t i;
VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline;
SamplerDescriptorSetData vertexSamplerDescriptorSetData;
/* FIXME: this needs an abstraction */ samplerCount = graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache->samplerBindingCount;
writeDescriptorSets = SDL_stack_alloc(
VkWriteDescriptorSet,
graphicsPipeline->pipelineLayout->vertexSamplerBindingCount
);
descriptorImageInfos = SDL_stack_alloc(
VkDescriptorImageInfo,
graphicsPipeline->pipelineLayout->vertexSamplerBindingCount
);
descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; if (samplerCount == 0)
descriptorSetAllocateInfo.pNext = NULL;
descriptorSetAllocateInfo.descriptorSetCount = 1;
descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->pipelineLayout->descriptorPool;
descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->pipelineLayout->vertexSamplerLayout;
renderer->vkAllocateDescriptorSets(
renderer->logicalDevice,
&descriptorSetAllocateInfo,
&descriptorSet
);
for (i = 0; i < graphicsPipeline->pipelineLayout->vertexSamplerBindingCount; i += 1)
{ {
currentTexture = (VulkanTexture*) pTextures[i]; return;
currentSampler = (VkSampler) pSamplers[i];
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler;
writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[i].pNext = NULL;
writeDescriptorSets[i].dstSet = descriptorSet;
writeDescriptorSets[i].dstBinding = i;
writeDescriptorSets[i].dstArrayElement = 0;
writeDescriptorSets[i].descriptorCount = 1;
writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeDescriptorSets[i].pImageInfo = &descriptorImageInfos[i];
} }
renderer->vkUpdateDescriptorSets( for (i = 0; i < samplerCount; i += 1)
renderer->logicalDevice, {
graphicsPipeline->pipelineLayout->vertexSamplerBindingCount, currentTexture = (VulkanTexture*) pTextures[i];
writeDescriptorSets, vertexSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view;
0, vertexSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i];
NULL vertexSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
graphicsPipeline->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchSamplerDescriptorSet(
renderer,
graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache,
&vertexSamplerDescriptorSetData
); );
graphicsPipeline->vertexSamplerDescriptorSet = descriptorSet;
SDL_stack_free(writeDescriptorSets);
SDL_stack_free(descriptorImageInfos);
} }
static void VULKAN_SetFragmentSamplers( static void VULKAN_SetFragmentSamplers(
@ -4791,72 +5049,33 @@ static void VULKAN_SetFragmentSamplers(
REFRESH_Texture **pTextures, REFRESH_Texture **pTextures,
REFRESH_Sampler **pSamplers REFRESH_Sampler **pSamplers
) { ) {
/* TODO: we can defer and batch these */
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo;
VkDescriptorSet descriptorSet;
VkWriteDescriptorSet *writeDescriptorSets;
VkDescriptorImageInfo *descriptorImageInfos;
VulkanTexture *currentTexture; VulkanTexture *currentTexture;
VkSampler currentSampler; uint32_t i, samplerCount;
uint32_t i;
VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline; VulkanGraphicsPipeline *graphicsPipeline = (VulkanGraphicsPipeline*) pipeline;
SamplerDescriptorSetData fragmentSamplerDescriptorSetData;
/* FIXME: this needs an abstraction */ samplerCount = graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache->samplerBindingCount;
writeDescriptorSets = SDL_stack_alloc(
VkWriteDescriptorSet,
graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount
);
descriptorImageInfos = SDL_stack_alloc(
VkDescriptorImageInfo,
graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount
);
descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; if (samplerCount == 0)
descriptorSetAllocateInfo.pNext = NULL;
descriptorSetAllocateInfo.descriptorSetCount = 1;
descriptorSetAllocateInfo.descriptorPool = graphicsPipeline->pipelineLayout->descriptorPool;
descriptorSetAllocateInfo.pSetLayouts = &graphicsPipeline->pipelineLayout->fragmentSamplerLayout;
renderer->vkAllocateDescriptorSets(
renderer->logicalDevice,
&descriptorSetAllocateInfo,
&descriptorSet
);
for (i = 0; i < graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount; i += 1)
{ {
currentTexture = (VulkanTexture*) pTextures[i]; return;
currentSampler = (VkSampler) pSamplers[i];
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler;
writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[i].pNext = NULL;
writeDescriptorSets[i].dstSet = descriptorSet;
writeDescriptorSets[i].dstBinding = i;
writeDescriptorSets[i].dstArrayElement = 0;
writeDescriptorSets[i].descriptorCount = 1;
writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeDescriptorSets[i].pImageInfo = &descriptorImageInfos[i];
} }
renderer->vkUpdateDescriptorSets( for (i = 0; i < samplerCount; i += 1)
renderer->logicalDevice, {
graphicsPipeline->pipelineLayout->fragmentSamplerBindingCount, currentTexture = (VulkanTexture*) pTextures[i];
writeDescriptorSets, fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageView = currentTexture->view;
0, fragmentSamplerDescriptorSetData.descriptorImageInfo[i].sampler = (VkSampler) pSamplers[i];
NULL fragmentSamplerDescriptorSetData.descriptorImageInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
graphicsPipeline->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchSamplerDescriptorSet(
renderer,
graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache,
&fragmentSamplerDescriptorSetData
); );
graphicsPipeline->fragmentSamplerDescriptorSet = descriptorSet;
SDL_stack_free(writeDescriptorSets);
SDL_stack_free(descriptorImageInfos);
} }
static void VULKAN_GetTextureData2D( static void VULKAN_GetTextureData2D(
@ -5078,12 +5297,12 @@ static void VULKAN_BindGraphicsPipeline(
VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline; VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline;
/* bind dummy samplers */ /* bind dummy samplers */
if (pipeline->pipelineLayout->vertexSamplerBindingCount == 0) if (pipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
{ {
pipeline->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet; pipeline->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet;
} }
if (pipeline->pipelineLayout->fragmentSamplerBindingCount == 0) if (pipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
{ {
pipeline->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet; pipeline->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet;
} }