交换链和渲染通道成功创建,但是验证层在使用它们时出现错误

时间:2018-11-15 18:16:49

标签: c++ vulkan

我正在尝试渲染三角形,我正在遵循https://vulkan-tutorial.org

的教程

我正在使用GLFW,GLSL和Visual Studio 2017。

创建渲染通道时,其值始终为0xc,创建交换链时,其值始终为0x2。创建函数始终返回VK_SUCCESS,并且没有验证层输出。

当我尝试使用vkCreateFramebuffer()创建帧缓冲区时,系统提示我渲染过程对象句柄无效,而ImageView对象句柄无效。它们的值始终为0x60x70x8

此外,当我尝试调用vkAcquireNextImageKHR()时,系统提示我我的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));
}

最后,创建帧缓冲代码:

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 error on FrameBuffer creation

创建帧缓冲区时出现ImageView错误:

ImageView error on framebuffer creation:

调用vkAcquireNextImageKHR()时出现此错误:

Swapchain Error

这对设备或实例来说不是问题,因为我已启用VK_surface_khr和VK_KHR_swapchain,并且已经检查了我的设备和窗口是否支持这些扩展。此外,我还重新启动了PC,仍然出现此错误。我正在使用Vulkan SDK 1.1.85.0。

此外,除了pNext之外,创建信息结构中没有遗漏任何值,我认为现在不应该使用pNext。

0 个答案:

没有答案