Я пытался получить эту работу в течение нескольких дней, и я не понимаю, что я делаю неправильно. Я получаю следующие сообщения об ошибках:
уровень проверки: буфер отправленных команд ожидает, что VkImage 0x3ba5830000000006 [] (подресурс: уровень массива 0x1 aspectMask 0, уровень mip 0) будет в макете VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - вместо этого текущий макет VK_IMAGE_LAYOUT_UNDEFINED. слой проверки: во время отрисовки в VkPipeline не найдено ни одного активного прохода рендеринга. Уровень проверки: vkCmdDrawIndexed (): этот вызов должен быть выполнен в активном проходе рендеринга. В Vulkan spe c говорится: эта команда должна вызываться только внутри экземпляра прохода рендеринга (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID -vkCmdDrawIndexed-renderpass ): во время отрисовки в VkPipeline 0xe164150000000050 не найдено ни одного активного прохода рендеринга. [!] Уровень проверки: vkCmdDrawIndexed (): этот вызов должен быть выполнен в активном проходе рендеринга. Vulkan spe c заявляет: эта команда должна вызываться только внутри экземпляра прохода рендеринга (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID -vkCmdDrawIndexed-renderpass ): во время отрисовки в VkPipeline 0xe164150000000050 не найдено ни одного активного прохода рендеринга []!
void mainLoop() {
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::ShowDemoWindow();
ImGui::Render();
drawFrame();
}
vkDeviceWaitIdle(device);
}
void initVulkan() {
vulkanFrame.resize(3);
vulkanSemaphores.resize(3);
createInstance();
setupDebugMessenger();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
createImageViews();
createRenderPass();
createDepthResources();
createFramebuffers();
createDescriptorSetLayout();
createGraphicsPipeline();
createCommandPool();
createTextureImage();
createTextureImageView();
createTextureSampler();
createVertexBuffer();
createIndexBuffer();
createUniformBuffers();
createDescriptorPool();
createDescriptorSets();
createCommandBuffers();
createSyncObjects();
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
auto err = vkCreateDescriptorPool(device, &pool_info, nullptr, &imGuiDescriptorPool);
check_vk_result(err);
VkAttachmentDescription attachment = {};
attachment.format = swapChainImageFormat;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference color_attachment = {};
color_attachment.attachment = 0;
color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_attachment;
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0; // or VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.attachmentCount = 1;
info.pAttachments = &attachment;
info.subpassCount = 1;
info.pSubpasses = &subpass;
info.dependencyCount = 1;
info.pDependencies = &dependency;
if (vkCreateRenderPass(device, &info, nullptr, &imGuiRenderPass) != VK_SUCCESS) {
throw std::runtime_error("Could not create Dear ImGui's render pass");
}
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
imGuiCommandPools.resize(vulkanFrame.size());
imGuiCommandBuffers.resize(vulkanFrame.size());
for (size_t i = 0; i < vulkanFrame.size(); i++)
{
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
if (vkCreateCommandPool(device, &commandPoolCreateInfo, nullptr, &imGuiCommandPools[i]) != VK_SUCCESS) {
throw std::runtime_error("Could not create graphics command pool");
}
VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocateInfo.commandPool = imGuiCommandPools[i];
commandBufferAllocateInfo.commandBufferCount = 1;
vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &imGuiCommandBuffers[i]);
}
VkImageView attachment2[1];
VkFramebufferCreateInfo Framebuffeinfo = {};
Framebuffeinfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
Framebuffeinfo.renderPass = imGuiRenderPass;
Framebuffeinfo.attachmentCount = 1;
Framebuffeinfo.pAttachments = attachment2;
Framebuffeinfo.width = WIDTH;
Framebuffeinfo.height = HEIGHT;
Framebuffeinfo.layers = 1;
for (uint32_t i = 0; i < vulkanFrame.size(); i++)
{
attachment2[0] = vulkanFrame[i].swapChainImageViews;
err = vkCreateFramebuffer(device, &Framebuffeinfo, nullptr, &imGuiFrameBuffer);
check_vk_result(err);
}
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForVulkan(window, true);
ImGui_ImplVulkan_InitInfo init_info = {};
init_info.Instance = instance;
init_info.PhysicalDevice = physicalDevice;
init_info.Device = device;
init_info.QueueFamily = 0;
init_info.Queue = graphicsQueue;
init_info.PipelineCache = VK_NULL_HANDLE;
init_info.DescriptorPool = imGuiDescriptorPool;
init_info.Allocator = nullptr;
init_info.MinImageCount = 3;
init_info.ImageCount = 3;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, imGuiRenderPass);
VkCommandBuffer command_buffer = beginSingleTimeCommands(currentFrame);
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
endSingleTimeCommands(currentFrame, command_buffer);
}
void drawFrame()
{
std::array<VkClearValue, 2> clearValues = {};
clearValues[0].color = { 0.0f, 0.0f, 0.0f, 1.0f };
clearValues[1].depthStencil = { 1.0f, 0 };
VkBuffer vertexBuffers[] = { vertexBuffer };
VkDeviceSize offsets[] = { 0 };
uint32_t imageIndex;
VkSemaphore ImageAcquiredSemaphore = vulkanSemaphores[currentFrame].ImageAcquiredSemaphore;
VkSemaphore RenderCompleteSemaphore = vulkanSemaphores[currentFrame].RenderCompleteSemaphore;
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, ImageAcquiredSemaphore, VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR)
{
recreateSwapChain();
return;
}
currentFrame = imageIndex;
//vkDeviceWaitIdle(device);
result = vkWaitForFences(device, 1, &vulkanFrame[currentFrame].Fence, VK_TRUE, UINT64_MAX);
result = vkResetFences(device, 1, &vulkanFrame[currentFrame].Fence);
result = vkResetCommandPool(device, vulkanFrame[currentFrame].commandPool, 0);
updateUniformBuffer(imageIndex);
VkCommandBufferBeginInfo CommandBufferInfo = {};
CommandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
CommandBufferInfo.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
result = vkBeginCommandBuffer(vulkanFrame[currentFrame].commandBuffers, &CommandBufferInfo);
VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = renderPass;
renderPassInfo.framebuffer = vulkanFrame[currentFrame].swapChainFramebuffers;
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = swapChainExtent;
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();
vkCmdBeginRenderPass(vulkanFrame[currentFrame].commandBuffers, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(vulkanFrame[currentFrame].commandBuffers, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
vkCmdBindVertexBuffers(vulkanFrame[currentFrame].commandBuffers, 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(vulkanFrame[currentFrame].commandBuffers, indexBuffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdBindDescriptorSets(vulkanFrame[currentFrame].commandBuffers, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[currentFrame], 0, nullptr);
vkCmdDrawIndexed(vulkanFrame[currentFrame].commandBuffers, static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
vkCmdEndRenderPass(vulkanFrame[currentFrame].commandBuffers);
vkResetCommandPool(device, imGuiCommandPools[currentFrame], 0);
VkCommandBufferBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(imGuiCommandBuffers[currentFrame], &info);
{
VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = imGuiRenderPass;
info.framebuffer = imGuiFrameBuffer;
info.renderArea.extent = swapChainExtent;
info.clearValueCount = static_cast<uint32_t>(clearValues.size());
info.pClearValues = clearValues.data();
vkCmdBeginRenderPass(imGuiCommandBuffers[currentFrame], &info, VK_SUBPASS_CONTENTS_INLINE);
}
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), vulkanFrame[currentFrame].commandBuffers);
vkCmdEndRenderPass(imGuiCommandBuffers[currentFrame]);
vkEndCommandBuffer(imGuiCommandBuffers[currentFrame]);
std::array<VkCommandBuffer, 2> submitCommandBuffers =
{ vulkanFrame[currentFrame].commandBuffers, imGuiCommandBuffers[currentFrame] };
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &ImageAcquiredSemaphore;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = static_cast<uint32_t>(submitCommandBuffers.size());
submitInfo.pCommandBuffers = submitCommandBuffers.data();
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &RenderCompleteSemaphore;
if (vkEndCommandBuffer(vulkanFrame[currentFrame].commandBuffers) != VK_SUCCESS) {
throw std::runtime_error("failed to record command buffer!");
}
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, vulkanFrame[currentFrame].Fence) != VK_SUCCESS) {
throw std::runtime_error("failed to submit draw command buffer!");
}
VkSwapchainKHR swapChains[] = { swapChain };
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &RenderCompleteSemaphore;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;
result = vkQueuePresentKHR(presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
}
}