重构完成到framebuffer

ink-soul 2024-04-03 17:00:30 +08:00
parent c125768fdf
commit e9eb47dfda
4 changed files with 347 additions and 43 deletions

View File

@ -62,11 +62,7 @@ public:
}signal;
struct Models
{
glTFModel::Model scene;
glTFModel::Model skybox;
} models;
struct Textures {
vks::TextureCubeMap environmentCube;

View File

@ -9,6 +9,7 @@
#include <toml11/toml.hpp>
#include "VulkanTools.h"
namespace VulkanBackend
{
class Setter

View File

@ -604,41 +604,231 @@ VkExtent2D VulkanBackend::VulkanFondation::chooseSwapExtent(const VkSurfaceCapab
}
// toDo 重写
void VulkanBackend::VulkanFondation::createImageView()
{
VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
VkFormat depthFormat = findDepthFormat();
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)
if (setter.settings.multiSampling)
{
throw std::runtime_error("failed to creat image view");
VkImageCreateInfo imageCI{};
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = colorAttachmentFormat;
imageCI.extent.width = setter.settings.width;
imageCI.extent.height = setter.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 = setter.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.colorAttachment.image));
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, multisampleTarget.colorAttachment.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.colorAttachment.memory));
vkBindImageMemory(device, multisampleTarget.colorAttachment.image, multisampleTarget.colorAttachment.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.colorAttachment.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.colorAttachment.view));
// Depth target
imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = depthFormat;
imageCI.extent.width = setter.settings.width;
imageCI.extent.height = setter.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 = setter.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.depthAttachment.image));
vkGetImageMemoryRequirements(device, multisampleTarget.depthAttachment.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.depthAttachment.memory));
vkBindImageMemory(device, multisampleTarget.depthAttachment.image, multisampleTarget.depthAttachment.memory, 0);
// Create image view for the MSAA target
imageViewCI.image = multisampleTarget.depthAttachment.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.depthAttachment.view));
}
// creat color image
VkImageCreateInfo imageCI{};
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = colorAttachmentFormat;
imageCI.extent.width = setter.settings.width;
imageCI.extent.height = setter.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 = 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, &colorAttachment.image));
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device,colorAttachment.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, &colorAttachment.memory));
vkBindImageMemory(device, multisampleTarget.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 = colorAttachment.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, &colorAttachment.view));
// 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 = setter.settings.width;
image.extent.height = setter.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;
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image));
VkMemoryAllocateInfo memAlloc = {};
memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAlloc.pNext = NULL;
memAlloc.allocationSize = 0;
memAlloc.memoryTypeIndex = 0;
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs);
memAlloc.allocationSize = memReqs.size;
memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &depthAttachment.memory));
VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 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 = depthAttachment.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;
}
depthStencilView.subresourceRange.baseMipLevel = 0;
depthStencilView.subresourceRange.levelCount = 1;
depthStencilView.subresourceRange.baseArrayLayer = 0;
depthStencilView.subresourceRange.layerCount = 1;
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthAttachment.view));
}
else
{
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");
}
}
}
}
@ -764,7 +954,7 @@ void VulkanBackend::VulkanFondation::createRenderPass()
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].finalLayout = colorAttachmentFinallayout;
// Depth attachment
attachments[1].format = colorAttachmentFormat;
attachments[1].format = depthAttachmentFormat;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@ -1060,7 +1250,92 @@ void VulkanBackend::VulkanFondation::createGraphicPipeline()
void VulkanBackend::VulkanFondation::createFramebuffer()
{
if (setter.settings.headless)
{
if (setter.settings.multiSampling)
{
VkImageView attachments[4];
attachments[0] = multisampleTarget.colorAttachment.view;
attachments[1] = multisampleTarget.depthAttachment.view;
attachments[2] = depthAttachment.view;
attachments[3] = colorAttachment.view;
VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo();
framebufferCreateInfo.renderPass = renderPass;
framebufferCreateInfo.attachmentCount = 4;
framebufferCreateInfo.pAttachments = attachments;
framebufferCreateInfo.width = setter.settings.width;
framebufferCreateInfo.height = setter.settings.height;
framebufferCreateInfo.layers = 1;
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffer));
}
else
{
VkImageView attachments[2];
attachments[0] = colorAttachment.view;
attachments[1] = depthAttachment.view;
VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo();
framebufferCreateInfo.renderPass = renderPass;
framebufferCreateInfo.attachmentCount = 2;
framebufferCreateInfo.pAttachments = attachments;
framebufferCreateInfo.width = setter.settings.width;
framebufferCreateInfo.height = setter.settings.height;
framebufferCreateInfo.layers = 1;
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffer));
}
}
else
{
createSwapChainFramebuffer();
}
}
void VulkanBackend::VulkanFondation::createSwapChainFramebuffer()
{
uint32_t attachmentCount;
VkImageView attachments[attachmentCount];
if (setter.settings.multiSampling) {
attachmentCount = 4;
attachments[0] = multisampleTarget.colorAttachment.view;
attachments[1] = multisampleTarget.depthAttachment.view;
attachments[2] = depthAttachment.view;
}
else {
attachmentCount = 2;
attachments[1] = depthAttachment.view;
}
VkFramebufferCreateInfo frameBufferCI{};
frameBufferCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
frameBufferCI.pNext = NULL;
frameBufferCI.renderPass = renderPass;
frameBufferCI.attachmentCount = attachmentCount;
frameBufferCI.pAttachments = attachments;
frameBufferCI.width = setter.settings.width;
frameBufferCI.height = setter.settings.height;
frameBufferCI.layers = 1;
// Create frame buffers for every swap chain image
swapChainFramebuffers.resize(swapChainImageViews.size());
for (uint32_t i = 0; i < swapChainImageViews.size(); i++) {
if (setter.settings.multiSampling) {
attachments[3] = swapChainImageViews[i];
}
else {
attachments[0] = swapChainImageViews[i];
}
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &swapChainFramebuffers[i]));
}
}
@ -1082,7 +1357,24 @@ void VulkanBackend::VulkanFondation::createCommandPool()
void VulkanBackend::VulkanFondation::createVertexBuffer()
{
VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
void* data;
vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
memcpy(data, vertices.data(), (size_t)bufferSize);
vkUnmapMemory(device, stagingBufferMemory);
// host visible buffer as temp buffer
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
// move the vertex data to the device local buffer
copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);
}
void VulkanBackend::VulkanFondation::createIndexBuffer()
@ -1121,14 +1413,14 @@ void VulkanBackend::VulkanFondation::createDescriptorPool()
}
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount }
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * static_cast<uint32_t>(MAX_FRAME_IN_FLIGHT)},
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * static_cast<uint32_t>(MAX_FRAME_IN_FLIGHT) }
};
VkDescriptorPoolCreateInfo descriptorPoolCI{};
descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCI.poolSizeCount = 2;
descriptorPoolCI.pPoolSizes = poolSizes.data();
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * swapChain.imageCount;
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * static_cast<uint32_t>(MAX_FRAME_IN_FLIGHT);
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool));
}

View File

@ -12,6 +12,7 @@
#include "glTFModel.h"
#include "VulkanUtils.hpp"
#include "PBR.h"
#include "VulkanDevice.hpp"
namespace VulkanBackend
{
@ -37,8 +38,10 @@ namespace VulkanBackend
private:
VulkanBackend::Setter setter;
PBR::Material pbrMaterial;
vks::VulkanDevice* vulkanDevice;
VkInstance instance;
@ -83,13 +86,7 @@ namespace VulkanBackend
VkExtent2D swapChainExtent;
std::vector<VkImageView> swapChainImageViews;
VkImage depthImage;
VkDeviceMemory depthImageMemory;
VkImageView depthImageView;
VkImage colorImage;
VkDeviceMemory colorImageMemory;
VkImageView colorImageView;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
@ -97,6 +94,23 @@ namespace VulkanBackend
VkCommandPool commandPool;
VkDescriptorPool descriptorPool;
VkFramebuffer framebuffer;
std::vector<VkFramebuffer> swapChainFramebuffers;
struct FrameBufferAttachment
{
VkImage image;
VkDeviceMemory memory;
VkImageView view;
}colorAttachment,depthAttachment;
struct MultisampleTarget {
FrameBufferAttachment colorAttachment;
FrameBufferAttachment depthAttachment;
} multisampleTarget;
struct Models
{
glTFModel::Model scene;
@ -187,6 +201,7 @@ namespace VulkanBackend
// 创建帧缓冲区
void createFramebuffer();
void createSwapChainFramebuffer();
// 创建命令缓冲池
void createCommandPool();