Swapchain и Render Pass созданы успешно, но слои проверки дают ошибку при их использовании

Я пытаюсь сделать треугольник, и я следую учебнику из https://vulkan-tutorial.org/

Я использую GLFW, GLSL и Visual Studio 2017.

Когда проход рендера создан, его значение всегда 0xc, и когда swapchain создан, его значение всегда 0x2, Функции создания всегда возвращаются VK_SUCCESSи нет выходного уровня проверки.

Когда я пытаюсь создать буфер кадра, используя vkCreateFramebuffer() Я получаю сообщение о том, что мой дескриптор объекта прохода рендеринга недопустим и что мои дескрипторы объекта ImageView недопустимы. Их ценности всегда 0x6, 0x7, а также 0x8,

Кроме того, когда я пытаюсь вызвать vkAcquireNextImageKHR(), Я получаю сообщение о том, что мой дескриптор объекта swapchain недействителен.

Мой код создания swapchain ниже. Пожалуйста, игнорируйте комментарии, они только для учебных целей.

void Swapchain::initSwapchain() {
    VkPresentModeKHR presentMode = getAvaiablePresentMode();
    QueueFamilyIndices indices = *mainWindow->getRenderer()->getQueueIndices();

    swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainCreateInfo.surface = this->mainWindow->getSurface();
    swapchainCreateInfo.minImageCount = swapchainImageCount;                                    //Bufferovanje slika display buffera, koliko slika odjednom moze biti u redu
    swapchainCreateInfo.imageFormat = this->mainWindow->getSurfaceFormat().format;
    swapchainCreateInfo.imageColorSpace = this->mainWindow->getSurfaceFormat().colorSpace;
    swapchainCreateInfo.imageExtent = this->swapExtent;
    swapchainCreateInfo.imageArrayLayers = 1;                                                   //Koliko slojeva ima slika (1 je obicno renderovanje, 2 je stetoskopsko)
    swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;                       //Za koju vrstu operacija koristimo slike? Renderujemo ih, sto znaci da su oni COLOR ATTACHMENTS                        
    if (indices.getGraphicsFamilyIndex() != indices.getPresentationFamilyIndex()) {
        uint32_t queueIndices[] = { indices.getGraphicsFamilyIndex(), indices.getPresentationFamilyIndex() };
        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;                      //Slika moze da se koristi paralelno, bez transfera vlasnistva nad slikom.
        swapchainCreateInfo.queueFamilyIndexCount = 2;
        swapchainCreateInfo.pQueueFamilyIndices = queueIndices;
    }
    else {
        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;                       //Slika je u vlasnistvu jednog reda u jedno vreme, i vlasnistvo mora biti prebaceno na drugi da bi taj drugi mogao da ga koristi.
        swapchainCreateInfo.queueFamilyIndexCount = 0;                                          //Za exclusive je uvek 0
        swapchainCreateInfo.pQueueFamilyIndices = nullptr;                                      //Ignorisemo za Exclusive
    }

    swapchainCreateInfo.preTransform = mainWindow->getSurfaceCapatibilities().currentTransform; //mainWindow->getCapabilities().currentTransform ako necemo transformaciju. VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;                     //Alfa kanal SURFACE-a, da li je ona transparentna
    swapchainCreateInfo.presentMode = presentMode;                                              //Vertical Sync
    swapchainCreateInfo.clipped = VK_TRUE;                                                      //Ukljucujemo clipping, jako bitno za telefone
    swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;                                          //Ako rekonstruisemo swapchain, pokazivac na stari

    util->ErrorCheck(vkCreateSwapchainKHR(renderer->getDevice(), &swapchainCreateInfo, nullptr, &swapchain));
    util->ErrorCheck(vkGetSwapchainImagesKHR(renderer->getDevice(), swapchain, &swapchainImageCount, nullptr));
}

void Swapchain::initSwapchainImgs()
{
    images.resize(swapchainImageCount);
    imageViews.resize(swapchainImageCount);

    util->ErrorCheck(vkGetSwapchainImagesKHR(renderer->getDevice(), swapchain, &swapchainImageCount, images.data()));

    for (uint32_t i = 0; i < swapchainImageCount; i++) {
        VkImageViewCreateInfo imgCreateInfo = {};
        imgCreateInfo.components.r = VK_COMPONENT_SWIZZLE_R;
        imgCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;
        imgCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B;
        imgCreateInfo.components.a = VK_COMPONENT_SWIZZLE_A;
        imgCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        imgCreateInfo.subresourceRange.baseMipLevel = 0;
        imgCreateInfo.subresourceRange.levelCount = 1;
        imgCreateInfo.subresourceRange.baseArrayLayer = 0;
        imgCreateInfo.subresourceRange.layerCount = 1;
        imgCreateInfo.format = this->imagesFormat;
        imgCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
        imgCreateInfo.image = images[i];
        imgCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;


        util->ErrorCheck(vkCreateImageView(renderer->getDevice(), &imgCreateInfo, nullptr, &imageViews[i]));
    }
}

Визуализируйте код создания пропуска:

void RenderPass::createColor() {
    VkAttachmentDescription attachment = {};
    VkAttachmentReference reference = {};
    VkSubpassDescription subpass = {};
    VkRenderPassCreateInfo info = {};

    attachment.format = surfaceFormat.format;                   //Mora da se poklapa sa formatom slika iz swapchaina
    attachment.samples = VK_SAMPLE_COUNT_1_BIT;                 //Odnosi se na multisampling
    attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;            //Operacija koju render pass attachment treba da obavi pri ucitavanju
    attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;          //Operacija koju treba odraditi posle rendera
    attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
    attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;       //Nije nam bitno kog je formata bila prosla slika, to ovo znaci.
    attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;   //Slike koje treba da budu predstavljene u swapchainu

    reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;//Layout slike u ovom subpassu
    reference.attachment = 0;                                   //Index attachmenta koji referenciramo ovim subpassom

    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpass.colorAttachmentCount = 1;
    subpass.pColorAttachments = &reference;                     //REFERENCIRAN JE IZ FRAGMENT SHADERA

    info.attachmentCount = 1;
    info.dependencyCount = 0;
    info.pAttachments = &attachment;
    info.pDependencies = nullptr;
    info.subpassCount = 1;
    info.pSubpasses = &subpass;
    info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;

    util->ErrorCheck(vkCreateRenderPass(this->renderer->getDevice(), &info, nullptr, &this->renderPass));
}

И, наконец, код создания Framebuffer:

void FrameBuffer::initFrameBuffer(
    uint32_t swapchainImageCount,
    std::vector<VkImageView> imageViews,
    VkRenderPass renderPass,
    VkExtent2D surfaceSize,
    std::vector<VkImageView> attachments
)
{
    frameBuffers.resize(swapchainImageCount);

    for (uint32_t i = 0; i < swapchainImageCount; ++i) {

        VkFramebufferCreateInfo frameBufferCreateInfo{};
        std::vector<VkImageView> allAttachments = { imageViews[i] };

        allAttachments.insert(allAttachments.begin(), attachments.begin(), attachments.end());

        frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
        frameBufferCreateInfo.renderPass = renderPass;
        frameBufferCreateInfo.width = surfaceSize.width;
        frameBufferCreateInfo.height = surfaceSize.height;
        frameBufferCreateInfo.layers = 1;
        frameBufferCreateInfo.pAttachments = allAttachments.data();
        frameBufferCreateInfo.attachmentCount = allAttachments.size();

        util->ErrorCheck(vkCreateFramebuffer(renderer->getDevice(), &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
    }
}

После запуска кода создания фреймбуфера я получаю следующие выводы:

Ошибка Render Pass при создании кадрового буфера: Ошибка Render Pass при создании FrameBuffer

Ошибка ImageView при создании кадрового буфера:

Ошибка ImageView при создании кадрового буфера

Эту ошибку я получаю при вызове vkAcquireNextImageKHR():

Ошибка свопчейна

Это не может быть проблемой с устройством или экземпляром, потому что я включил VK_surface_khr и VK_KHR_swapchain, и я проверил, поддерживают ли мое устройство и окно эти расширения. Кроме того, я перезагрузил компьютер, и эти ошибки все еще происходят. Я использую Vulkan SDK 1.1.85.0.

Кроме того, в инфо-структурах создания отсутствуют пропущенные значения, кроме pNext, который, я думаю, пока не следует использовать.

0 ответов

Другие вопросы по тегам