Возникли проблемы при получении Im Gui для работы с Vulkan - PullRequest
0 голосов
/ 17 апреля 2020

Я пытался получить эту работу в течение нескольких дней, и я не понимаю, что я делаю неправильно. Я получаю следующие сообщения об ошибках:

уровень проверки: буфер отправленных команд ожидает, что 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();
        }
    }

1 Ответ

0 голосов
/ 17 апреля 2020

Вы создаете отдельный буфер команд im gui:

vkBeginCommandBuffer(imGuiCommandBuffers[currentFrame], &info);

, но затем вы визуализируете im gui в другой буфер команд:

ImGui_ImplVulkan_RenderDrawData(
    ImGui::GetDrawData(),
    vulkanFrame[currentFrame].commandBuffers
);
...