mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-14 04:59:58 +01:00
01de5957d8
Use these flags to pick the right sampler. Fixes issues with blurry and leaking fonts, lines in main menu tiles, etc. fixes #439, fixes #79
223 lines
7.0 KiB
C
223 lines
7.0 KiB
C
#include "vk_descriptor.h"
|
|
|
|
#include "eiface.h" // ARRAYSIZE
|
|
|
|
descriptor_pool_t vk_desc;
|
|
|
|
qboolean VK_DescriptorInit( void )
|
|
{
|
|
int max_desc_sets = 0;
|
|
|
|
VkDescriptorPoolSize dps[] = {
|
|
{
|
|
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
.descriptorCount = MAX_TEXTURES,
|
|
}, {
|
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
|
.descriptorCount = ARRAYSIZE(vk_desc.ubo_sets),
|
|
/*
|
|
}, {
|
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
.descriptorCount = 1,
|
|
*/
|
|
},
|
|
};
|
|
VkDescriptorPoolCreateInfo dpci = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
.pPoolSizes = dps,
|
|
.poolSizeCount = ARRAYSIZE(dps),
|
|
};
|
|
|
|
for (int i = 0; i < ARRAYSIZE(dps); ++i)
|
|
max_desc_sets += dps[i].descriptorCount;
|
|
|
|
dpci.maxSets = max_desc_sets;
|
|
|
|
XVK_CHECK(vkCreateDescriptorPool(vk_core.device, &dpci, NULL, &vk_desc.pool));
|
|
|
|
{
|
|
const int num_sets = MAX_TEXTURES;
|
|
// ... TODO find better place for this; this should be per-pipeline/shader
|
|
const VkDescriptorSetLayoutBinding bindings[] = { {
|
|
.binding = 0,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
.descriptorCount = 1,
|
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
.pImmutableSamplers = NULL,
|
|
}};
|
|
const VkDescriptorSetLayoutCreateInfo dslci = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
.bindingCount = ARRAYSIZE(bindings),
|
|
.pBindings = bindings,
|
|
};
|
|
VkDescriptorSetLayout* tmp_layouts = Mem_Malloc(vk_core.pool, sizeof(VkDescriptorSetLayout) * num_sets);
|
|
const VkDescriptorSetAllocateInfo dsai = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
.descriptorPool = vk_desc.pool,
|
|
.descriptorSetCount = num_sets,
|
|
.pSetLayouts = tmp_layouts,
|
|
};
|
|
XVK_CHECK(vkCreateDescriptorSetLayout(vk_core.device, &dslci, NULL, &vk_desc.one_texture_layout));
|
|
for (int i = 0; i < num_sets; ++i)
|
|
tmp_layouts[i] = vk_desc.one_texture_layout;
|
|
|
|
XVK_CHECK(vkAllocateDescriptorSets(vk_core.device, &dsai, vk_desc.sets));
|
|
|
|
Mem_Free(tmp_layouts);
|
|
}
|
|
|
|
{
|
|
const int num_sets = ARRAYSIZE(vk_desc.ubo_sets);
|
|
// ... TODO find better place for this; this should be per-pipeline/shader
|
|
VkDescriptorSetLayoutBinding bindings[] = { {
|
|
.binding = 0,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
|
.descriptorCount = 1,
|
|
// TODO we use these sets for both vertex-only and fragment-only bindings; improve
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
}};
|
|
VkDescriptorSetLayoutCreateInfo dslci = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
.bindingCount = ARRAYSIZE(bindings),
|
|
.pBindings = bindings,
|
|
};
|
|
VkDescriptorSetLayout* tmp_layouts = Mem_Malloc(vk_core.pool, sizeof(VkDescriptorSetLayout) * num_sets);
|
|
VkDescriptorSetAllocateInfo dsai = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
.descriptorPool = vk_desc.pool,
|
|
.descriptorSetCount = num_sets,
|
|
.pSetLayouts = tmp_layouts,
|
|
};
|
|
XVK_CHECK(vkCreateDescriptorSetLayout(vk_core.device, &dslci, NULL, &vk_desc.one_uniform_buffer_layout));
|
|
for (int i = 0; i < num_sets; ++i)
|
|
tmp_layouts[i] = vk_desc.one_uniform_buffer_layout;
|
|
|
|
XVK_CHECK(vkAllocateDescriptorSets(vk_core.device, &dsai, vk_desc.ubo_sets));
|
|
|
|
Mem_Free(tmp_layouts);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void VK_DescriptorShutdown( void )
|
|
{
|
|
vkDestroyDescriptorPool(vk_core.device, vk_desc.pool, NULL);
|
|
vkDestroyDescriptorSetLayout(vk_core.device, vk_desc.one_texture_layout, NULL);
|
|
vkDestroyDescriptorSetLayout(vk_core.device, vk_desc.one_uniform_buffer_layout, NULL);
|
|
}
|
|
|
|
void VK_DescriptorsCreate(vk_descriptors_t *desc)
|
|
{
|
|
{
|
|
VkDescriptorSetLayoutCreateInfo dslci = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
.bindingCount = desc->num_bindings,
|
|
.pBindings = desc->bindings,
|
|
};
|
|
XVK_CHECK(vkCreateDescriptorSetLayout(vk_core.device, &dslci, NULL, &desc->desc_layout));
|
|
}
|
|
|
|
{
|
|
VkPipelineLayoutCreateInfo plci = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
.setLayoutCount = 1,
|
|
.pSetLayouts = &desc->desc_layout,
|
|
.pushConstantRangeCount = desc->push_constants.size > 0 ? 1 : 0,
|
|
.pPushConstantRanges = &desc->push_constants,
|
|
};
|
|
XVK_CHECK(vkCreatePipelineLayout(vk_core.device, &plci, NULL, &desc->pipeline_layout));
|
|
}
|
|
|
|
{
|
|
VkDescriptorPoolSize pools[8] = {0};
|
|
VkDescriptorPoolCreateInfo dpci = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
.maxSets = desc->num_sets,
|
|
.poolSizeCount = 0,
|
|
.pPoolSizes = pools,
|
|
};
|
|
|
|
for (int i = 0; i < desc->num_bindings; ++i) {
|
|
const VkDescriptorSetLayoutBinding *bind = desc->bindings + i;
|
|
int j;
|
|
for (j = 0; j < dpci.poolSizeCount; ++j) {
|
|
if (pools[j].type == bind->descriptorType) {
|
|
pools[j].descriptorCount += bind->descriptorCount * desc->num_sets;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (j == dpci.poolSizeCount) {
|
|
ASSERT(dpci.poolSizeCount < ARRAYSIZE(pools));
|
|
pools[j].descriptorCount = bind->descriptorCount * desc->num_sets;
|
|
pools[j].type = bind->descriptorType;
|
|
++dpci.poolSizeCount;
|
|
}
|
|
}
|
|
|
|
XVK_CHECK(vkCreateDescriptorPool(vk_core.device, &dpci, NULL, &desc->desc_pool));
|
|
}
|
|
|
|
for (int i = 0; i < desc->num_sets; ++i)
|
|
{
|
|
VkDescriptorSetAllocateInfo dsai = {
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
.descriptorPool = desc->desc_pool,
|
|
.descriptorSetCount = 1,
|
|
.pSetLayouts = &desc->desc_layout,
|
|
};
|
|
XVK_CHECK(vkAllocateDescriptorSets(vk_core.device, &dsai, desc->desc_sets + i));
|
|
}
|
|
}
|
|
|
|
void VK_DescriptorsWrite(const vk_descriptors_t *desc, int set_slot)
|
|
{
|
|
VkWriteDescriptorSet wds[16];
|
|
ASSERT(ARRAYSIZE(wds) >= desc->num_bindings);
|
|
for (int i = 0; i < desc->num_bindings; ++i){
|
|
const VkDescriptorSetLayoutBinding *binding = desc->bindings + i;
|
|
wds[i] = (VkWriteDescriptorSet) {
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.descriptorCount = binding->descriptorCount,
|
|
.descriptorType = binding->descriptorType,
|
|
.dstSet = desc->desc_sets[set_slot],
|
|
.dstBinding = binding->binding,
|
|
.dstArrayElement = 0,
|
|
};
|
|
|
|
switch (binding->descriptorType) {
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
// TODO
|
|
ASSERT(wds[i].descriptorCount == 1);
|
|
wds[i].pBufferInfo = &desc->values[i].buffer;
|
|
break;
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
|
if (wds[i].descriptorCount > 1)
|
|
wds[i].pImageInfo = desc->values[i].image_array;
|
|
else
|
|
wds[i].pImageInfo = &desc->values[i].image;
|
|
break;
|
|
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
|
|
// TODO
|
|
ASSERT(wds[i].descriptorCount == 1);
|
|
wds[i].pNext = &desc->values[i].accel;
|
|
break;
|
|
default:
|
|
gEngine.Con_Printf(S_ERROR "Unexpected descriptor type %d\n", binding->descriptorType);
|
|
ASSERT("Unexpected descriptor type");
|
|
}
|
|
}
|
|
|
|
vkUpdateDescriptorSets(vk_core.device, desc->num_bindings, wds, 0, NULL);
|
|
}
|
|
|
|
void VK_DescriptorsDestroy(const vk_descriptors_t *desc)
|
|
{
|
|
vkDestroyDescriptorPool(vk_core.device, desc->desc_pool, NULL);
|
|
vkDestroyPipelineLayout(vk_core.device, desc->pipeline_layout, NULL);
|
|
vkDestroyDescriptorSetLayout(vk_core.device, desc->desc_layout, NULL);
|
|
}
|