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 при создании кадрового буфера:
Ошибка ImageView при создании кадрового буфера:
Эту ошибку я получаю при вызове vkAcquireNextImageKHR()
:
Это не может быть проблемой с устройством или экземпляром, потому что я включил VK_surface_khr и VK_KHR_swapchain, и я проверил, поддерживают ли мое устройство и окно эти расширения. Кроме того, я перезагрузил компьютер, и эти ошибки все еще происходят. Я использую Vulkan SDK 1.1.85.0.
Кроме того, в инфо-структурах создания отсутствуют пропущенные значения, кроме pNext, который, я думаю, пока не следует использовать.