#c #vulkan
Вопрос:
прямо сейчас я пытаюсь понять наборы шаблонных дескрипторов в API Vulkan. До этого я использовал обычные наборы дескрипторов, и они работали нормально. Затем я перешел к шаблонам, и они перестали работать. Когда я использую эти наборы дескрипторов с функцией vkCmdPushDescriptorSetWithTemplatesKHR, эта функция приводит к сбою всей программы с сообщением об ошибке в отладчике:
Exception thrown: read access violation. layout_obj._Ptr was nullptr.
У меня нет никаких других ошибок, включая ошибки проверки.
Прежде всего, у меня есть структура информации о дескрипторе для следующего использования
struct descriptor_info { union { VkDescriptorImageInfo Image; VkDescriptorBufferInfo Buffer; }; }; descriptor_info CreateDescriptorInfo(VkBuffer Buffer_, VkDeviceSize Offset, VkDeviceSize Size) { descriptor_info Result = {}; Result.Buffer.buffer = Buffer_; Result.Buffer.offset = Offset; Result.Buffer.range = Size; return Result; }
Вот функция для создания шаблона набора дескрипторов:
VkDescriptorUpdateTemplate CreateUpdateTemplate(VkDevice Device, VkPipelineBindPoint BindPoint, VkPipelineLayout PipelineLayout, const shaderamp; MeshVert, const shaderamp; MeshFrag) { std::vectorlt;VkDescriptorUpdateTemplateEntrygt; Entries; uint32_t StorageBufferMask = MeshVert.StorageBufferMask | MeshFrag.StorageBufferMask; for(int i = 0; i lt; 32; i) { if(StorageBufferMask amp; (1 lt;lt; i)) { VkDescriptorUpdateTemplateEntry Entry = {}; Entry.dstBinding = i; Entry.dstArrayElement = 0; Entry.descriptorCount = 1; Entry.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; Entry.offset = sizeof(descriptor_info)*i; Entry.stride = sizeof(descriptor_info); Entries.push_back(Entry); } } VkDescriptorUpdateTemplateCreateInfo CreateInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO}; CreateInfo.descriptorUpdateEntryCount = (uint32_t)Entries.size(); CreateInfo.pDescriptorUpdateEntries = Entries.data(); CreateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR; CreateInfo.pipelineBindPoint = BindPoint; CreateInfo.pipelineLayout = PipelineLayout; VkDescriptorUpdateTemplate UpdateTemplate = 0; VK_CHECK(vkCreateDescriptorUpdateTemplate(Device, amp;CreateInfo, 0, amp;UpdateTemplate)); return UpdateTemplate; }
И вот я использую эти шаблоны:
vkCmdBindPipeline(CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, MeshPipeline); descriptor_info Descriptors[] = {CreateDescriptorInfo(VertexBuffer.Buffer, 0, VertexBuffer.Size)}; vkCmdPushDescriptorSetWithTemplateKHR(CommandBuffer, MeshUpdateTemplate, PipelineLayout, 0, Descriptors); vkCmdBindIndexBuffer(CommandBuffer, IndexBuffer.Buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdDrawIndexed(CommandBuffer, (uint32_t)Meshes[0].ConvertedVertexIndices.size(), 1, 0, 0, 0);
Что может вызвать эту проблему? Я сам работал над этой проблемой в отладчике, но ничего не смог найти.