// ********************** Swapchain ************************************
const VkExtent2D extents =
context.physicalDevice().surfaceCapabilities().minImageExtent;
const VkFormat swapChainFormat = VK_FORMAT_R8G8B8A8_UNORM;
context.createSwapchain(swapChainFormat, VK_COLORSPACE_SRGB_NONLINEAR_KHR,
VK_PRESENT_MODE_FIFO_KHR, extents);
const VkRect2D renderArea = {.offset = {.x = 0, .y = 0}, .extent = extents};
具体看一下createSwapChain
void Context::createSwapchain(VkFormat format, VkColorSpaceKHR colorSpace,
VkPresentModeKHR presentMode, const VkExtent2D& extent) {
swapchain_ =
std::make_unique<Swapchain>(*this, physicalDevice_, surface_, presentationQueue_,
format, colorSpace, presentMode, extent);
}
可以看到是context的一个成员变量,还是用unique pointer 管理的
Swapchain::Swapchain(const Context& context, const PhysicalDevice& physicalDevice,
VkSurfaceKHR surface, VkQueue presentQueue, VkFormat imageFormat,
VkColorSpaceKHR imageClorSpace, VkPresentModeKHR presentMode,
VkExtent2D extent, const std::string& name)
: device_{context.device()}, presentQueue_{presentQueue}, extent_{extent} {
const uint32_t numImages =
std::clamp(physicalDevice.surfaceCapabilities().minImageCount + 1,
physicalDevice.surfaceCapabilities().minImageCount,
physicalDevice.surfaceCapabilities().maxImageCount);
const auto presentationFamilyIndex = physicalDevice.presentationFamilyIndex();
const bool presentationQueueIsShared =
physicalDevice.graphicsFamilyIndex().value() == presentationFamilyIndex.value();
std::array<uint32_t, 2> familyIndices{physicalDevice.graphicsFamilyIndex().value(),
presentationFamilyIndex.value()};
const VkSwapchainCreateInfoKHR swapchainInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.surface = surface,
.minImageCount = numImages,
.imageFormat = imageFormat,
.imageColorSpace = imageClorSpace,
.imageExtent = extent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.imageSharingMode = presentationQueueIsShared ? VK_SHARING_MODE_EXCLUSIVE
: VK_SHARING_MODE_CONCURRENT,
.queueFamilyIndexCount = presentationQueueIsShared ? 0u : 2u,
.pQueueFamilyIndices = presentationQueueIsShared ? nullptr : familyIndices.data(),
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = presentMode,
.clipped = VK_TRUE,
.oldSwapchain = VK_NULL_HANDLE,
};
VK_CHECK(vkCreateSwapchainKHR(device_, &swapchainInfo, nullptr, &swapchain_));
createTextures(context, imageFormat, extent);
createSemaphores(context);
const VkFenceCreateInfo fenceci = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT, // 创建好fence状态就是signal的
};
VK_CHECK(vkCreateFence(device_, &fenceci, nullptr, &acquireFence_));
}
createTextures
void Swapchain::createTextures(const Context& context, VkFormat imageFormat,
const VkExtent2D& extent) {
uint32_t imageCount{0};
VK_CHECK(vkGetSwapchainImagesKHR(device_, swapchain_, &imageCount, nullptr));
std::vector<VkImage> images(imageCount);
VK_CHECK(vkGetSwapchainImagesKHR(device_, swapchain_, &imageCount, images.data()));
images_.reserve(imageCount);
for (size_t index = 0; index < imageCount; ++index) {
images_.emplace_back(
std::make_shared<Texture>(context, device_, images[index], imageFormat,
VkExtent3D{
.width = extent.width,
.height = extent.height,
.depth = 1,
},
1, // number of layers
false, "Swapchain image " + std::to_string(index)));
}
}
还得再看看Texture,递归学习了(
Texture::Texture(const Context& context, VkDevice device, VkImage image, VkFormat format,
VkExtent3D extents, uint32_t numlayers, bool multiview,
const std::string& name)
: context_{context},
image_{image},
format_{format},
extents_{extents},
layerCount_(numlayers),
multiview_(multiview),
ownsVkImage_{false},
debugName_{name} {
context.setVkObjectname(image_, VK_OBJECT_TYPE_IMAGE, "Image: " + name);
imageView_ = createImageView(
context, !multiview_ ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY, format,
1, layerCount_, name);
}
又得看imageView
VkImageView Texture::createImageView(const Context& context, VkImageViewType viewType,
VkFormat format, uint32_t numMipLevels,
uint32_t layers, const std::string& name) {
// ASSERT(isDepth() ^ isStencil(),
// "It's illegal to create an image view with both the depth and
// stencil bits. You " "can only use one");
const VkImageAspectFlags aspectMask =
isDepth() ? VK_IMAGE_ASPECT_DEPTH_BIT
: (isStencil() ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT);
const VkImageViewCreateInfo imageViewInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.flags = /*usageFlags_ &
VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT ?
VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT
:*/
VkImageViewCreateFlags(0),
.image = image_,
.viewType = viewType,
.format = format,
.components =
{
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
},
.subresourceRange = {
.aspectMask = aspectMask,
.baseMipLevel = 0,
.levelCount = numMipLevels,
.baseArrayLayer = 0,
.layerCount = multiview_ ? VK_REMAINING_ARRAY_LAYERS : layers,
}};
VkImageView imageView{VK_NULL_HANDLE};
VK_CHECK(vkCreateImageView(context_.device(), &imageViewInfo, nullptr, &imageView));
context.setVkObjectname(imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "Image view: " + name);
return imageView;
}