重构到renderPass
parent
7063d9a0f9
commit
c970164ccb
|
@ -34,6 +34,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags,
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
VkResult VulkanExampleBase::createInstance(bool enableValidation)
|
VkResult VulkanExampleBase::createInstance(bool enableValidation)
|
||||||
{
|
{
|
||||||
setter.settings.validation = enableValidation;
|
setter.settings.validation = enableValidation;
|
||||||
|
@ -109,11 +110,12 @@ VkResult VulkanExampleBase::createInstance(bool enableValidation)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void VulkanExampleBase::prepare()
|
void VulkanExampleBase::prepare()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Swapchain
|
Swapchain
|
||||||
*/
|
|
||||||
initSwapchain();
|
initSwapchain();
|
||||||
setupSwapChain();
|
setupSwapChain();
|
||||||
|
|
||||||
|
@ -121,7 +123,7 @@ void VulkanExampleBase::prepare()
|
||||||
width = swapChain.extent.width;
|
width = swapChain.extent.width;
|
||||||
height = swapChain.extent.height;
|
height = swapChain.extent.height;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
Command pool
|
Command pool
|
||||||
*/
|
*/
|
||||||
|
@ -623,7 +625,7 @@ void VulkanExampleBase::initVulkan()
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
Device creation
|
Device creation
|
||||||
*/
|
|
||||||
vulkanDevice = new vks::VulkanDevice(physicalDevice);
|
vulkanDevice = new vks::VulkanDevice(physicalDevice);
|
||||||
VkPhysicalDeviceFeatures enabledFeatures{};
|
VkPhysicalDeviceFeatures enabledFeatures{};
|
||||||
if (deviceFeatures.samplerAnisotropy) {
|
if (deviceFeatures.samplerAnisotropy) {
|
||||||
|
@ -636,15 +638,15 @@ void VulkanExampleBase::initVulkan()
|
||||||
exit(res);
|
exit(res);
|
||||||
}
|
}
|
||||||
device = vulkanDevice->logicalDevice;
|
device = vulkanDevice->logicalDevice;
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
Graphics queue
|
Graphics queue
|
||||||
*/
|
|
||||||
vkGetDeviceQueue(device, vulkanDevice->queueFamilyIndices.graphics, 0, &queue);
|
|
||||||
|
|
||||||
|
vkGetDeviceQueue(device, vulkanDevice->queueFamilyIndices.graphics, 0, &queue);
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
Suitable depth format
|
Suitable depth format
|
||||||
*/
|
|
||||||
std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
|
std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
|
||||||
VkBool32 validDepthFormat = false;
|
VkBool32 validDepthFormat = false;
|
||||||
for (auto& format : depthFormats) {
|
for (auto& format : depthFormats) {
|
||||||
|
@ -659,7 +661,7 @@ void VulkanExampleBase::initVulkan()
|
||||||
assert(validDepthFormat);
|
assert(validDepthFormat);
|
||||||
|
|
||||||
swapChain.connect(instance, physicalDevice, device);
|
swapChain.connect(instance, physicalDevice, device);
|
||||||
|
*/
|
||||||
|
|
||||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
// Get Android device name and manufacturer (to display along GPU name)
|
// Get Android device name and manufacturer (to display along GPU name)
|
||||||
|
@ -2019,7 +2021,7 @@ void VulkanExampleBase::handleMouseMove(int32_t x, int32_t y)
|
||||||
}
|
}
|
||||||
mousePos = glm::vec2((float)x, (float)y);
|
mousePos = glm::vec2((float)x, (float)y);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void VulkanExampleBase::initSwapchain()
|
void VulkanExampleBase::initSwapchain()
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
@ -2041,3 +2043,4 @@ void VulkanExampleBase::setupSwapChain()
|
||||||
{
|
{
|
||||||
swapChain.create(&width, &height, settings.vsync);
|
swapChain.create(&width, &height, settings.vsync);
|
||||||
}
|
}
|
||||||
|
*/
|
|
@ -18,10 +18,19 @@ void VulkanBackend::VulkanFondation::initVulkan()
|
||||||
// 完成逻辑设备创建
|
// 完成逻辑设备创建
|
||||||
createLogicalDevice();
|
createLogicalDevice();
|
||||||
|
|
||||||
|
// 创建交换链
|
||||||
|
createSwapChain();
|
||||||
|
|
||||||
|
// 创建交换链中的imageView
|
||||||
|
createImageView();
|
||||||
|
|
||||||
|
// 创建renderpass
|
||||||
|
createRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void VulkanBackend::VulkanFondation::createInstance()
|
void VulkanBackend::VulkanFondation::createInstance()
|
||||||
{
|
{
|
||||||
// check validation layers
|
// check validation layers
|
||||||
|
@ -422,3 +431,396 @@ void VulkanBackend::VulkanFondation::createLogicalDevice()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void VulkanBackend::VulkanFondation::createSwapChain()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (setter.settings.headless)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
|
||||||
|
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
|
||||||
|
VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
|
||||||
|
|
||||||
|
uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
|
||||||
|
|
||||||
|
if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
|
||||||
|
{
|
||||||
|
imageCount = swapChainSupport.capabilities.maxImageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
createInfo.surface = surface;
|
||||||
|
|
||||||
|
createInfo.minImageCount = imageCount;
|
||||||
|
createInfo.imageFormat = surfaceFormat.format;
|
||||||
|
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
||||||
|
createInfo.imageExtent = extent;
|
||||||
|
createInfo.imageArrayLayers = 1;
|
||||||
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
|
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
|
||||||
|
uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(),indices.presentFamily.value() };
|
||||||
|
if (indices.graphicsFamily != indices.presentFamily)
|
||||||
|
{
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
|
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
createInfo.queueFamilyIndexCount = 0;
|
||||||
|
createInfo.pQueueFamilyIndices = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
|
||||||
|
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
createInfo.presentMode = presentMode;
|
||||||
|
createInfo.clipped = VK_TRUE;
|
||||||
|
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
|
||||||
|
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("failed to create swap chain !");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
|
||||||
|
swapChainImages.resize(imageCount);
|
||||||
|
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
|
||||||
|
// store swap format and swap extent to member variable
|
||||||
|
swapChainImageFormat = surfaceFormat.format;
|
||||||
|
swapChainExtent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR VulkanBackend::VulkanFondation::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
||||||
|
{
|
||||||
|
for (const auto& availableFormat : availableFormats) {
|
||||||
|
if (availableFormat.format == VK_FORMAT_B8G8R8_SRGB && availableFormat.colorSpace == VK_COLORSPACE_SRGB_NONLINEAR_KHR)
|
||||||
|
{
|
||||||
|
return availableFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableFormats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPresentModeKHR VulkanBackend::VulkanFondation::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes)
|
||||||
|
{
|
||||||
|
// Get available present modes
|
||||||
|
uint32_t presentModeCount;
|
||||||
|
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL));
|
||||||
|
assert(presentModeCount > 0);
|
||||||
|
|
||||||
|
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
|
||||||
|
VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()));
|
||||||
|
// The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
|
||||||
|
// This mode waits for the vertical blank ("v-sync")
|
||||||
|
// 垂直同步模式
|
||||||
|
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
|
||||||
|
// If v-sync is not requested, try to find a mailbox mode
|
||||||
|
// It's the lowest latency non-tearing present mode available
|
||||||
|
if (!setter.settings.vsync)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < presentModeCount; i++)
|
||||||
|
{
|
||||||
|
if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||||
|
{
|
||||||
|
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR))
|
||||||
|
{
|
||||||
|
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExtent2D VulkanBackend::VulkanFondation::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities)
|
||||||
|
{
|
||||||
|
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
|
||||||
|
{
|
||||||
|
return capabilities.currentExtent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
VkExtent2D actualExtent = {
|
||||||
|
static_cast<uint32_t>(width),
|
||||||
|
static_cast<uint32_t>(height)
|
||||||
|
};
|
||||||
|
|
||||||
|
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||||
|
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
||||||
|
|
||||||
|
return actualExtent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void VulkanBackend::VulkanFondation::createImageView()
|
||||||
|
{
|
||||||
|
if (setter.settings.headless)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapChainImageViews.resize(swapChainImages.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < swapChainImages.size(); i++)
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo creatInfo{};
|
||||||
|
creatInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
creatInfo.image = swapChainImages[i];
|
||||||
|
creatInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
creatInfo.format = swapChainImageFormat;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void VulkanBackend::VulkanFondation::createRenderPass()
|
||||||
|
{
|
||||||
|
VkFormat colorAttachmentFormat;
|
||||||
|
VkFormat depthAttachmentFormat = findDepthFormat();
|
||||||
|
VkImageLayout colorAttachmentFinallayout;
|
||||||
|
if (setter.settings.headless)
|
||||||
|
{
|
||||||
|
colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
colorAttachmentFinallayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorAttachmentFormat = swapChainImageFormat;
|
||||||
|
colorAttachmentFinallayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setter.settings.multiSampling) {
|
||||||
|
std::array<VkAttachmentDescription, 4> attachments = {};
|
||||||
|
|
||||||
|
// Multisampled attachment that we render to
|
||||||
|
attachments[0].format = colorAttachmentFormat;
|
||||||
|
attachments[0].samples = setter.settings.sampleCount;
|
||||||
|
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
// This is the frame buffer attachment to where the multisampled image
|
||||||
|
// will be resolved to and which will be presented to the swapchain
|
||||||
|
attachments[1].format = colorAttachmentFormat;
|
||||||
|
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[1].finalLayout = colorAttachmentFinallayout;
|
||||||
|
|
||||||
|
// Multisampled depth attachment we render to
|
||||||
|
attachments[2].format = depthAttachmentFormat;
|
||||||
|
attachments[2].samples = setter.settings.sampleCount;
|
||||||
|
attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
// Depth resolve attachment
|
||||||
|
attachments[3].format = depthAttachmentFormat;
|
||||||
|
attachments[3].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachments[3].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[3].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[3].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[3].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[3].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[3].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference colorReference = {};
|
||||||
|
colorReference.attachment = 0;
|
||||||
|
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference depthReference = {};
|
||||||
|
depthReference.attachment = 2;
|
||||||
|
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
// Resolve attachment reference for the color attachment
|
||||||
|
VkAttachmentReference resolveReference = {};
|
||||||
|
resolveReference.attachment = 1;
|
||||||
|
resolveReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpass = {};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &colorReference;
|
||||||
|
// Pass our resolve attachments to the sub pass
|
||||||
|
subpass.pResolveAttachments = &resolveReference;
|
||||||
|
subpass.pDepthStencilAttachment = &depthReference;
|
||||||
|
|
||||||
|
std::array<VkSubpassDependency, 2> dependencies;
|
||||||
|
|
||||||
|
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependencies[0].dstSubpass = 0;
|
||||||
|
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
|
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
|
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
|
|
||||||
|
dependencies[1].srcSubpass = 0;
|
||||||
|
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
|
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
|
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo renderPassCI = {};
|
||||||
|
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
|
renderPassCI.pAttachments = attachments.data();
|
||||||
|
renderPassCI.subpassCount = 1;
|
||||||
|
renderPassCI.pSubpasses = &subpass;
|
||||||
|
renderPassCI.dependencyCount = 2;
|
||||||
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
|
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::array<VkAttachmentDescription, 2> attachments = {};
|
||||||
|
// Color attachment
|
||||||
|
attachments[0].format = colorAttachmentFormat;
|
||||||
|
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[0].finalLayout = colorAttachmentFinallayout;
|
||||||
|
// Depth attachment
|
||||||
|
attachments[1].format = colorAttachmentFormat;
|
||||||
|
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference colorReference = {};
|
||||||
|
colorReference.attachment = 0;
|
||||||
|
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference depthReference = {};
|
||||||
|
depthReference.attachment = 1;
|
||||||
|
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpassDescription = {};
|
||||||
|
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpassDescription.colorAttachmentCount = 1;
|
||||||
|
subpassDescription.pColorAttachments = &colorReference;
|
||||||
|
subpassDescription.pDepthStencilAttachment = &depthReference;
|
||||||
|
subpassDescription.inputAttachmentCount = 0;
|
||||||
|
subpassDescription.pInputAttachments = nullptr;
|
||||||
|
subpassDescription.preserveAttachmentCount = 0;
|
||||||
|
subpassDescription.pPreserveAttachments = nullptr;
|
||||||
|
subpassDescription.pResolveAttachments = nullptr;
|
||||||
|
|
||||||
|
// Subpass dependencies for layout transitions
|
||||||
|
std::array<VkSubpassDependency, 2> dependencies;
|
||||||
|
|
||||||
|
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependencies[0].dstSubpass = 0;
|
||||||
|
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
|
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
|
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
|
|
||||||
|
dependencies[1].srcSubpass = 0;
|
||||||
|
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
|
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
|
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo renderPassCI{};
|
||||||
|
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
|
renderPassCI.pAttachments = attachments.data();
|
||||||
|
renderPassCI.subpassCount = 1;
|
||||||
|
renderPassCI.pSubpasses = &subpassDescription;
|
||||||
|
renderPassCI.dependencyCount = static_cast<uint32_t>(dependencies.size());
|
||||||
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
|
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFormat VulkanBackend::VulkanFondation::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 VulkanBackend::VulkanFondation::findSupportedFormat(const std::vector<VkFormat>& 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanBackend::VulkanFondation::hasStencilComponent(VkFormat format)
|
||||||
|
{
|
||||||
|
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "renderSetter.h"
|
#include "renderSetter.h"
|
||||||
|
#include <VulkanSwapChain.hpp>
|
||||||
|
|
||||||
namespace VulkanBackend
|
namespace VulkanBackend
|
||||||
{
|
{
|
||||||
|
@ -72,7 +73,23 @@ namespace VulkanBackend
|
||||||
VkQueue presentQueue;
|
VkQueue presentQueue;
|
||||||
|
|
||||||
|
|
||||||
|
VkSwapchainKHR swapChain;
|
||||||
|
std::vector<VkImage> swapChainImages;
|
||||||
|
VkFormat swapChainImageFormat;
|
||||||
|
VkExtent2D swapChainExtent;
|
||||||
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
|
|
||||||
|
VkImage depthImage;
|
||||||
|
VkDeviceMemory depthImageMemory;
|
||||||
|
VkImageView depthImageView;
|
||||||
|
|
||||||
|
VkImage colorImage;
|
||||||
|
VkDeviceMemory colorImageMemory;
|
||||||
|
VkImageView colorImageView;
|
||||||
|
|
||||||
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
|
||||||
|
|
||||||
|
VkRenderPass renderPass;
|
||||||
|
|
||||||
// 句柄创建,检查校验层支持和获取需要的扩展
|
// 句柄创建,检查校验层支持和获取需要的扩展
|
||||||
void createInstance();
|
void createInstance();
|
||||||
|
@ -99,10 +116,23 @@ namespace VulkanBackend
|
||||||
VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||||
VulkanBackend::VulkanFondation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
|
VulkanBackend::VulkanFondation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
|
||||||
|
|
||||||
// 创建程序使用的逻辑显卡设备
|
// 创建程序使用的逻辑设备
|
||||||
|
|
||||||
void createLogicalDevice();
|
void createLogicalDevice();
|
||||||
|
|
||||||
|
// 创建交换链
|
||||||
|
void createSwapChain();
|
||||||
|
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
|
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
||||||
|
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
|
||||||
|
|
||||||
|
// 创建交换链中的imageView,用于访问交换链中图像
|
||||||
|
void createImageView();
|
||||||
|
|
||||||
|
// 创建renderPass
|
||||||
|
void createRenderPass();
|
||||||
|
VkFormat findDepthFormat();
|
||||||
|
VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||||
|
bool hasStencilComponent(VkFormat format);
|
||||||
};
|
};
|
||||||
|
|
||||||
VulkanFondation::VulkanFondation()
|
VulkanFondation::VulkanFondation()
|
||||||
|
|
Loading…
Reference in New Issue