From e9ed42bfeb643aa14fcac8e43702e443d302b99b Mon Sep 17 00:00:00 2001 From: ink-soul Date: Fri, 12 Apr 2024 09:54:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=9B=E5=BB=BA=E5=B8=A7?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=8C=BA=E7=9A=84colorAttachment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base/vulkanexamplebase.cpp | 373 +++++++++++++++++++++++++++---------- base/vulkanexamplebase.h | 16 +- 2 files changed, 289 insertions(+), 100 deletions(-) diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 50d896b..9ae42b0 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -1821,28 +1821,117 @@ void VulkanExampleBase::setupFrameBuffer() /* MSAA */ - if (settings.multiSampling) { - // Check if device supports requested sample count for color and depth frame buffer - //assert((deviceProperties.limits.framebufferColorSampleCounts >= sampleCount) && (deviceProperties.limits.framebufferDepthSampleCounts >= sampleCount)); + VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM; + VkFormat depthFormat = findDepthFormat(); + if (settings.headless) + { + if (settings.multiSampling) + { + VkImageCreateInfo imageCI{}; + imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCI.imageType = VK_IMAGE_TYPE_2D; + imageCI.format = colorAttachmentFormat; + imageCI.extent.width = settings.width; + imageCI.extent.height = settings.height; + imageCI.extent.depth = 1; + imageCI.mipLevels = 1; + imageCI.arrayLayers = 1; + imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCI.samples = settings.sampleCount; + imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image)); + + VkMemoryRequirements memReqs; + vkGetImageMemoryRequirements(device, multisampleTarget.color.image, &memReqs); + VkMemoryAllocateInfo memAllocInfo{}; + memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAllocInfo.allocationSize = memReqs.size; + VkBool32 lazyMemTypePresent; + memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); + if (!lazyMemTypePresent) { + memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + } + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.color.memory)); + vkBindImageMemory(device, multisampleTarget.color.image, multisampleTarget.color.memory, 0); + + // Create image view for the MSAA color image target + VkImageViewCreateInfo imageViewCI{}; + imageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCI.image = multisampleTarget.color.image; + imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewCI.format = colorAttachmentFormat; + imageViewCI.components.r = VK_COMPONENT_SWIZZLE_R; + imageViewCI.components.g = VK_COMPONENT_SWIZZLE_G; + imageViewCI.components.b = VK_COMPONENT_SWIZZLE_B; + imageViewCI.components.a = VK_COMPONENT_SWIZZLE_A; + imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + imageViewCI.subresourceRange.levelCount = 1; + imageViewCI.subresourceRange.layerCount = 1; + VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.color.view)); + + // Depth target + imageCI.imageType = VK_IMAGE_TYPE_2D; + imageCI.format = depthFormat; + imageCI.extent.width = settings.width; + imageCI.extent.height = settings.height; + imageCI.extent.depth = 1; + imageCI.mipLevels = 1; + imageCI.arrayLayers = 1; + imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCI.samples = settings.sampleCount; + imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.depth.image)); + + vkGetImageMemoryRequirements(device, multisampleTarget.depth.image, &memReqs); + memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAllocInfo.allocationSize = memReqs.size; + memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); + if (!lazyMemTypePresent) { + memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + } + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.depth.memory)); + vkBindImageMemory(device, multisampleTarget.depth.image, multisampleTarget.depth.memory, 0); + + // Create image view for the MSAA target + imageViewCI.image = multisampleTarget.depth.image; + imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewCI.format = depthFormat; + imageViewCI.components.r = VK_COMPONENT_SWIZZLE_R; + imageViewCI.components.g = VK_COMPONENT_SWIZZLE_G; + imageViewCI.components.b = VK_COMPONENT_SWIZZLE_B; + imageViewCI.components.a = VK_COMPONENT_SWIZZLE_A; + imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + imageViewCI.subresourceRange.levelCount = 1; + imageViewCI.subresourceRange.layerCount = 1; + VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view)); + } + // creat color image VkImageCreateInfo imageCI{}; imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.imageType = VK_IMAGE_TYPE_2D; - imageCI.format = swapChain.colorFormat; - imageCI.extent.width = width; - imageCI.extent.height = height; + imageCI.format = colorAttachmentFormat; + imageCI.extent.width = settings.width; + imageCI.extent.height = settings.height; imageCI.extent.depth = 1; imageCI.mipLevels = 1; imageCI.arrayLayers = 1; imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCI.samples = settings.sampleCount; + imageCI.samples = VK_SAMPLE_COUNT_1_BIT; imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image)); + + VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &colorAttachment.image)); VkMemoryRequirements memReqs; - vkGetImageMemoryRequirements(device, multisampleTarget.color.image, &memReqs); + vkGetImageMemoryRequirements(device, colorAttachment.image, &memReqs); + VkMemoryAllocateInfo memAllocInfo{}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; @@ -1851,15 +1940,16 @@ void VulkanExampleBase::setupFrameBuffer() if (!lazyMemTypePresent) { memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } - VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.color.memory)); - vkBindImageMemory(device, multisampleTarget.color.image, multisampleTarget.color.memory, 0); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &colorAttachment.memory)); - // Create image view for the MSAA target + vkBindImageMemory(device, colorAttachment.image, colorAttachment.memory, 0); + + // Create image view for the color image VkImageViewCreateInfo imageViewCI{}; imageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - imageViewCI.image = multisampleTarget.color.image; + imageViewCI.image = colorAttachment.image; imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewCI.format = swapChain.colorFormat; + imageViewCI.format = colorAttachmentFormat; imageViewCI.components.r = VK_COMPONENT_SWIZZLE_R; imageViewCI.components.g = VK_COMPONENT_SWIZZLE_G; imageViewCI.components.b = VK_COMPONENT_SWIZZLE_B; @@ -1867,103 +1957,158 @@ void VulkanExampleBase::setupFrameBuffer() imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageViewCI.subresourceRange.levelCount = 1; imageViewCI.subresourceRange.layerCount = 1; - VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.color.view)); + VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &colorAttachment.view)); - // Depth target - imageCI.imageType = VK_IMAGE_TYPE_2D; - imageCI.format = depthFormat; - imageCI.extent.width = width; - imageCI.extent.height = height; - imageCI.extent.depth = 1; - imageCI.mipLevels = 1; - imageCI.arrayLayers = 1; - imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCI.samples = settings.sampleCount; - imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.depth.image)); + // create image for the depth image + VkImageCreateInfo image = {}; + image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image.pNext = NULL; + image.imageType = VK_IMAGE_TYPE_2D; + image.format = depthFormat; + image.extent.width = settings.width; + image.extent.height = settings.height; + image.extent.depth = 1; + image.mipLevels = 1; + image.arrayLayers = 1; + image.samples = VK_SAMPLE_COUNT_1_BIT; + image.tiling = VK_IMAGE_TILING_OPTIMAL; + image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + image.flags = 0; - vkGetImageMemoryRequirements(device, multisampleTarget.depth.image, &memReqs); - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthStencil.image)); + + VkMemoryAllocateInfo memAlloc = {}; + memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAlloc.pNext = NULL; + memAlloc.allocationSize = 0; + memAlloc.memoryTypeIndex = 0; + VkMemoryRequirements depthAttachmentMemReqs; + vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs); + memAlloc.allocationSize = depthAttachmentMemReqs.size; + memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &depthStencil.mem)); + VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0)); + + + // create image view for depth image + VkImageViewCreateInfo depthStencilView = {}; + depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + depthStencilView.pNext = NULL; + depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; + depthStencilView.format = depthFormat; + depthStencilView.image = depthStencil.image; + depthStencilView.flags = 0; + depthStencilView.subresourceRange = {}; + depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT) + { + depthStencilView.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; } - VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.depth.memory)); - vkBindImageMemory(device, multisampleTarget.depth.image, multisampleTarget.depth.memory, 0); + depthStencilView.subresourceRange.baseMipLevel = 0; + depthStencilView.subresourceRange.levelCount = 1; + depthStencilView.subresourceRange.baseArrayLayer = 0; + depthStencilView.subresourceRange.layerCount = 1; + VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view)); - // Create image view for the MSAA target - imageViewCI.image = multisampleTarget.depth.image; - imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewCI.format = depthFormat; - imageViewCI.components.r = VK_COMPONENT_SWIZZLE_R; - imageViewCI.components.g = VK_COMPONENT_SWIZZLE_G; - imageViewCI.components.b = VK_COMPONENT_SWIZZLE_B; - imageViewCI.components.a = VK_COMPONENT_SWIZZLE_A; - imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - imageViewCI.subresourceRange.levelCount = 1; - imageViewCI.subresourceRange.layerCount = 1; - VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view)); + } + else + { + + swapChainImageViews.resize(swapChain.imageCount); + for (size_t i = 0; i < swapChain.imageCount; i++) + { + VkImageViewCreateInfo creatInfo{}; + creatInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + creatInfo.image = swapChain.images[i]; + creatInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + creatInfo.format = swapChain.colorFormat; + + creatInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + creatInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + creatInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + creatInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + + creatInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + creatInfo.subresourceRange.baseMipLevel = 0; + creatInfo.subresourceRange.levelCount = 1; + creatInfo.subresourceRange.baseArrayLayer = 0; + creatInfo.subresourceRange.layerCount = 1; + + if (vkCreateImageView(device, &creatInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) + { + throw std::runtime_error("failed to creat image view"); + } + } } + if (settings.headless) + { + auto frameRange = settings.endFrameIndex - settings.startFrameCount; + if (settings.multiSampling) + { - // Depth/Stencil attachment is the same for all frame buffers + for (int i = 0; i < frameRange; i++) + { + VkImageView attachments[4]; + attachments[0] = multisampleTarget.color.view; + attachments[1] = multisampleTarget.depth.view; + attachments[2] = depthStencil.view; + attachments[3] = colorAttachment.view; - VkImageCreateInfo image = {}; - image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image.pNext = NULL; - image.imageType = VK_IMAGE_TYPE_2D; - image.format = depthFormat; - image.extent = { width, height, 1 }; - image.mipLevels = 1; - image.arrayLayers = 1; - image.samples = VK_SAMPLE_COUNT_1_BIT; - image.tiling = VK_IMAGE_TILING_OPTIMAL; - image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - image.flags = 0; + VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo(); + framebufferCreateInfo.renderPass = renderPass; + framebufferCreateInfo.attachmentCount = 4; + framebufferCreateInfo.pAttachments = attachments; + framebufferCreateInfo.width = settings.width; + framebufferCreateInfo.height = settings.height; + framebufferCreateInfo.layers = 1; - VkMemoryAllocateInfo mem_alloc = {}; - mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - mem_alloc.pNext = NULL; - mem_alloc.allocationSize = 0; - mem_alloc.memoryTypeIndex = 0; + VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &frameBuffers[i])); + } - VkImageViewCreateInfo depthStencilView = {}; - depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - depthStencilView.pNext = NULL; - depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; - depthStencilView.format = depthFormat; - depthStencilView.flags = 0; - depthStencilView.subresourceRange = {}; - depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - depthStencilView.subresourceRange.baseMipLevel = 0; - depthStencilView.subresourceRange.levelCount = 1; - depthStencilView.subresourceRange.baseArrayLayer = 0; - depthStencilView.subresourceRange.layerCount = 1; + } + else + { + for (int i = 0; i < frameRange; i++) + { + VkImageView attachments[2]; + attachments[0] = colorAttachment.view; + attachments[1] = depthStencil.view; - VkMemoryRequirements memReqs; - VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthStencil.image)); - vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs); - mem_alloc.allocationSize = memReqs.size; - mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem)); - VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0)); + VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo(); + framebufferCreateInfo.renderPass = renderPass; + framebufferCreateInfo.attachmentCount = 2; + framebufferCreateInfo.pAttachments = attachments; + framebufferCreateInfo.width = settings.width; + framebufferCreateInfo.height = settings.height; + framebufferCreateInfo.layers = 1; + VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &frameBuffers[i])); - depthStencilView.image = depthStencil.image; - VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view)); + } + } - // - VkImageView attachments[4]; + } + else + { + createSwapChainFramebuffer(); + } +} + +void VulkanExampleBase::createSwapChainFramebuffer() +{ + uint32_t attachmentCount; + VkImageView attachments[attachmentCount]; if (settings.multiSampling) { + attachmentCount = 4; attachments[0] = multisampleTarget.color.view; - attachments[2] = multisampleTarget.depth.view; - attachments[3] = depthStencil.view; + attachments[1] = multisampleTarget.depth.view; + attachments[2] = depthStencil.view; + } else { + attachmentCount = 2; attachments[1] = depthStencil.view; } @@ -1971,20 +2116,22 @@ void VulkanExampleBase::setupFrameBuffer() frameBufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; frameBufferCI.pNext = NULL; frameBufferCI.renderPass = renderPass; - frameBufferCI.attachmentCount = settings.multiSampling ? 4 :2; + frameBufferCI.attachmentCount = attachmentCount; frameBufferCI.pAttachments = attachments; - frameBufferCI.width = width; - frameBufferCI.height = height; + frameBufferCI.width = settings.width; + frameBufferCI.height = settings.height; frameBufferCI.layers = 1; + + // Create frame buffers for every swap chain image - frameBuffers.resize(swapChain.imageCount); - for (uint32_t i = 0; i < frameBuffers.size(); i++) { + frameBuffers.resize(swapChainImageViews.size()); + for (uint32_t i = 0; i < swapChainImageViews.size(); i++) { if (settings.multiSampling) { - attachments[1] = swapChain.buffers[i].view; + attachments[3] = swapChainImageViews[i]; } else { - attachments[0] = swapChain.buffers[i].view; + attachments[0] = swapChainImageViews[i]; } VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i])); } @@ -2075,3 +2222,31 @@ void VulkanExampleBase::setupSwapChain() { swapChain.create(&width, &height, settings.vsync); } + +VkFormat VulkanExampleBase::findDepthFormat() +{ + return findSupportedFormat( + { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT }, + VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT + ); +} + +VkFormat VulkanExampleBase::findSupportedFormat(const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) +{ + for (VkFormat format : candidates) + { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props); + + if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) + { + return format; + } + else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) + { + return format; + } + } + throw std::runtime_error("failed to find supported format"); +} diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index 226146f..b948368 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -113,13 +113,16 @@ public: uint32_t lastFPS = 0; struct Settings { - bool validation = false; // 校验层开关 + uint32_t width = 1280; + uint32_t height = 720; + bool validation = true; // 校验层开关 bool fullscreen = false; // 全屏开关 bool vsync = false; // 垂直同步开关 bool multiSampling = true; // 多重采样 bool rotateModel = true; // 模型自旋转(暂时失效) bool headless = false; // 无头开关 bool outputPNGimage = false; + uint32_t endFrameIndex = 75; bool enableSaveToImageSequeue = true; // 图片序列开关(暂时弃用) uint32_t outputFrameCount = 75; // 图片序列结束帧 bool takeScreenShot = false; // 截屏(暂时弃用) @@ -136,6 +139,14 @@ public: VkImageView view; } depthStencil; + struct ColorAttachment { + VkImage image; + VkDeviceMemory memory; + VkImageView view; + } colorAttachment; + + std::vector swapChainImageViews; + struct GamePadState { glm::vec2 axisLeft = glm::vec2(0.0f); glm::vec2 axisRight = glm::vec2(0.0f); @@ -257,11 +268,14 @@ public: virtual void render() = 0; virtual void windowResized(); virtual void setupFrameBuffer(); + void createSwapChainFramebuffer(); virtual void prepare(); virtual void fileDropped(std::string filename); void initSwapchain(); void setupSwapChain(); + VkFormat findDepthFormat(); + VkFormat findSupportedFormat(const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); void renderLoop(); void renderFrame();