我正在尝试渲染三角形,我正在遵循https://vulkan-tutorial.org
的教程我正在使用GLFW,GLSL和Visual Studio 2017。
创建渲染通道时,其值始终为0xc
,创建交换链时,其值始终为0x2
。创建函数始终返回VK_SUCCESS
,并且没有验证层输出。
当我尝试使用vkCreateFramebuffer()
创建帧缓冲区时,系统提示我渲染过程对象句柄无效,而ImageView对象句柄无效。它们的值始终为0x6
,0x7
和0x8
。
此外,当我尝试调用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]));
}
}
运行帧缓冲区创建代码后,我得到以下输出:
创建帧缓冲区时出现ImageView错误:
调用vkAcquireNextImageKHR()
时出现此错误:
这对设备或实例来说不是问题,因为我已启用VK_surface_khr和VK_KHR_swapchain,并且已经检查了我的设备和窗口是否支持这些扩展。此外,我还重新启动了PC,仍然出现此错误。我正在使用Vulkan SDK 1.1.85.0。
此外,除了pNext之外,创建信息结构中没有遗漏任何值,我认为现在不应该使用pNext。