I am trying to render a triangle and I'm following a tutorial from https://vulkan-tutorial.org
I am using GLFW, GLSL and Visual Studio 2017.
When render pass is created, it's value is always 0xc, and when swapchain is created, it's value is always 0x2. Creation functions always return VK_SUCCESS, and there is no validation layer output.
When I try to create a frame buffer, using vkCreateFramebuffer() I get prompted that my render pass object handle is invalid, and that my ImageView object handles are invalid. Their values are always 0x6, 0x7, and 0x8.
Also, when I try to invoke vkAcquireNextImageKHR(), I get prompted that my swapchain object handle is invalid.
My swapchain creation code is below. Please, ignore the comments, they are for learning purposes only.
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]));
}
}
Render pass creation code:
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));
}
And finally, Framebuffer creation code:
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]));
}
}
After running framebuffer creation code, I get these outputs:
Render Pass error on framebuffer creation:

ImageView error on framebuffer creation:
This error I get when I invoke vkAcquireNextImageKHR():
This can't be a problem with a device or instance because I have enabled VK_surface_khr and VK_KHR_swapchain, and I have checked if my device and window support these extensions. Also, I have rebooted my PC and this errors still occur. I am using Vulkan SDK 1.1.85.0.
Also, there are no missing values in creation info structures except for pNext, which I think shouldn't even be used for now.

