descriptor set cacheing system
parent
d23b2a6a75
commit
3780772bdd
|
@ -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
|
||||||
/* Create sampler descriptor pool */
|
{
|
||||||
if (!VULKAN_INTERNAL_CreateSamplerDescriptorPool(
|
vulkanGraphicsPipelineLayout->vertexSamplerDescriptorSetCache =
|
||||||
|
VULKAN_INTERNAL_CreateSamplerDescriptorSetCache(
|
||||||
renderer,
|
renderer,
|
||||||
&vulkanGraphicsPipelineLayout->descriptorPool
|
pipelineLayoutHash.vertexSamplerLayout,
|
||||||
)) {
|
vertexSamplerBindingCount
|
||||||
REFRESH_LogError("Failed to create descriptor pool!");
|
);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
if (fragmentSamplerBindingCount == 0)
|
||||||
|
{
|
||||||
|
vulkanGraphicsPipelineLayout->fragmentSamplerDescriptorSetCache = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue