diff --git a/vulkan/vulkan.d b/vulkan/vulkan.d index f7aae7e..78583a8 100644 --- a/vulkan/vulkan.d +++ b/vulkan/vulkan.d @@ -35,7 +35,12 @@ alias DescSetLayout = VkDescriptorSetLayout; alias PipelineLayout = VkPipelineLayout; alias DescLayoutBinding = VkDescriptorSetLayoutBinding; alias DescWrite = VkWriteDescriptorSet; -alias DescSet = VkDescriptorSet; + +struct DescSet +{ + VkDescriptorSet handle; + u32 dynamic_count; +} bool g_VLAYER_SUPPORT = false; @@ -516,6 +521,8 @@ struct Vulkan PipelineHandles[] pipeline_handles; u32 pipeline_count; VkPipeline[FRAME_OVERLAP] last_pipelines; + DescSetLayout global_set_layout; + DescSet global_set; MappedBuffer!(u8) transfer_buf; @@ -599,7 +606,7 @@ CreateDescSetLayout(DescLayoutBinding[] bindings) } DescSet -AllocDescSet(DescSetLayout layout) +AllocDescSet(DescSetLayout layout, u32 dynamic_count = 0) { VkDescriptorSetAllocateInfo alloc_info = { sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -608,15 +615,15 @@ AllocDescSet(DescSetLayout layout) descriptorPool: g_vk.active_pool, }; - DescSet set; - VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set); + DescSet set = { dynamic_count: dynamic_count }; + VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle); if(result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL) { PushDescriptorPool(); alloc_info.descriptorPool = g_vk.active_pool; - result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set); + result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle); VkCheckA("vkAllocateDescriptorSets failure", result); } @@ -1503,21 +1510,50 @@ Bind(Pipeline pipeline_handle, DescSet[] sets, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); - VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); + VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle; BindPipeline(cmd, pipeline); u32[] offsets; + if(g_vk.global_set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.frame_arena, g_vk.global_set.dynamic_count); + } + + vkCmdBindDescriptorSets( + cmd, + pipeline.type, + pipeline.layout, + 0, + 1, + &g_vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr + ); + + u32 offset_count; + VkDescriptorSet[] handles = Alloc!(VkDescriptorSet)(g_vk.frame_arena, sets.length); + + foreach(i, set; sets) + { + handles[i] = set.handle; + offset_count += set.dynamic_count; + } + + if(offset_count > 0) + { + offsets = Alloc!(u32)(g_vk.frame_arena, offset_count); + } vkCmdBindDescriptorSets( cmd, pipeline.type, pipeline.layout, - 0, - cast(u32)sets.length, - sets.ptr, - 0, - null + 1, + cast(u32)handles.length, + handles.ptr, + cast(u32)offsets.length, + offsets.ptr ); } @@ -1536,19 +1572,41 @@ Bind(Pipeline pipeline_handle, DescSet set, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); - VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); + VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle; BindPipeline(cmd, pipeline); + u32[] offsets; + if(g_vk.global_set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.frame_arena, g_vk.global_set.dynamic_count); + } + vkCmdBindDescriptorSets( cmd, pipeline.type, pipeline.layout, 0, 1, - &set, - 0, - null + &g_vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr + ); + + if(set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.frame_arena, set.dynamic_count); + } + + vkCmdBindDescriptorSets( + cmd, + pipeline.type, + pipeline.layout, + 1, + 1, + &set.handle, + cast(u32)offsets.length, + offsets.ptr ); } @@ -2031,7 +2089,7 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc) write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write.descriptorType = desc.type; - write.dstSet = set; + write.dstSet = set.handle; write.dstBinding = desc.binding; write.descriptorCount = 1; write.dstArrayElement = desc.index; @@ -2105,7 +2163,7 @@ WriteConvDescriptor(Buffer* buf) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: g_vk.conv_desc_set, + dstSet: g_vk.conv_desc_set.handle, dstBinding: 1, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2125,7 +2183,7 @@ WriteConvDescriptor(ImageView* view) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: g_vk.conv_desc_set, + dstSet: g_vk.conv_desc_set.handle, dstBinding: 0, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,