重构到descriptorPool

ink-soul 2024-04-03 12:07:49 +08:00
parent baa5457b4e
commit c125768fdf
8 changed files with 374 additions and 392 deletions

View File

@ -127,185 +127,17 @@ void VulkanExampleBase::prepare()
/*
Command pool
*/
VkCommandPoolCreateInfo cmdPoolInfo = {};
cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex;
cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VK_CHECK_RESULT(vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &cmdPool));
/*
Render pass
*/
if (settings.multiSampling) {
std::array<VkAttachmentDescription, 4> attachments = {};
// Multisampled attachment that we render to
attachments[0].format = swapChain.colorFormat;
attachments[0].samples = 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 = swapChain.colorFormat;
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 = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
// Multisampled depth attachment we render to
attachments[2].format = depthFormat;
attachments[2].samples = 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 = depthFormat;
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 = swapChain.colorFormat;
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 = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
// Depth attachment
attachments[1].format = depthFormat;
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));
}
/*
Pipeline cache
*/
VkPipelineCacheCreateInfo pipelineCacheCreateInfo{};
pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
VK_CHECK_RESULT(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache));
/*
Frame buffer
@ -1921,7 +1753,7 @@ void VulkanExampleBase::setupFrameBuffer()
depthStencilView.image = depthStencil.image;
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view));
//
// create framebuffer
VkImageView attachments[4];

View File

@ -34,7 +34,7 @@ function(buildHomework HOMEWORK_NAME)
"render/glTFModel.h"
"render/glTFModel.cpp"
"render/vulkanFoundation.h" "render/vulkanFoundation.cpp" "render/renderSetter.h" "render/renderSetter.cpp")
"render/vulkanFoundation.h" "render/vulkanFoundation.cpp" "render/renderSetter.h" "render/renderSetter.cpp" "render/PBR.h" "render/PBR.cpp")
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS})
else(WIN32)
add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES})

View File

46
src/render/PBR.h 100644
View File

@ -0,0 +1,46 @@
#pragma once
#include "glm/glm.hpp"
namespace PBR
{
class Material
{
public:
Material();
~Material();
struct PushConstBlockMaterial {
glm::vec4 baseColorFactor;
glm::vec4 emissiveFactor;
glm::vec4 diffuseFactor;
glm::vec4 specularFactor;
float workflow;
int colorTextureSet;
int PhysicalDescriptorTextureSet;
int normalTextureSet;
int occlusionTextureSet;
int emissiveTextureSet;
float metallicFactor;
float roughnessFactor;
float alphaMask;
float alphaMaskCutoff;
} pushConstBlockMaterial;
private:
};
Material::Material()
{
}
Material::~Material()
{
}
}

View File

@ -300,39 +300,7 @@ void PlumageRender::setupNodeDescriptorSet(glTFModel::Node* node)
void PlumageRender::setupDescriptors()
{
/*
Descriptor Pool
*/
uint32_t imageSamplerCount = 0;
uint32_t materialCount = 0;
uint32_t meshCount = 0;
// Environment samplers (radiance, irradiance, brdflut)
imageSamplerCount += 3;
std::vector<glTFModel::Model*> modellist = { &models.skybox, &models.scene };
for (auto& model : modellist) {
for (auto& material : model->materials) {
imageSamplerCount += 5;
materialCount++;
}
for (auto node : model->linearNodes) {
if (node->mesh) {
meshCount++;
}
}
}
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount }
};
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;
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool));
/*
Descriptor sets
@ -492,154 +460,6 @@ void PlumageRender::setupDescriptors()
}
}
void PlumageRender::preparePipelines()
{
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{};
inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssemblyStateCI.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPipelineRasterizationStateCreateInfo rasterizationStateCI{};
rasterizationStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL;
rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizationStateCI.lineWidth = 1.0f;
VkPipelineColorBlendAttachmentState blendAttachmentState{};
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
blendAttachmentState.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlendStateCI{};
colorBlendStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlendStateCI.attachmentCount = 1;
colorBlendStateCI.pAttachments = &blendAttachmentState;
VkPipelineDepthStencilStateCreateInfo depthStencilStateCI{};
depthStencilStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencilStateCI.depthTestEnable = VK_FALSE;
depthStencilStateCI.depthWriteEnable = VK_FALSE;
depthStencilStateCI.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
depthStencilStateCI.front = depthStencilStateCI.back;
depthStencilStateCI.back.compareOp = VK_COMPARE_OP_ALWAYS;
VkPipelineViewportStateCreateInfo viewportStateCI{};
viewportStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportStateCI.viewportCount = 1;
viewportStateCI.scissorCount = 1;
VkPipelineMultisampleStateCreateInfo multisampleStateCI{};
multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples = setter.settings.sampleCount;
}
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicStateCI{};
dynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicStateCI.pDynamicStates = dynamicStateEnables.data();
dynamicStateCI.dynamicStateCount = static_cast<uint32_t>(dynamicStateEnables.size());
// Pipeline layout
const std::vector<VkDescriptorSetLayout> setLayouts = {
descriptorSetLayouts.scene, descriptorSetLayouts.material, descriptorSetLayouts.node
};
VkPipelineLayoutCreateInfo pipelineLayoutCI{};
pipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCI.setLayoutCount = static_cast<uint32_t>(setLayouts.size());
pipelineLayoutCI.pSetLayouts = setLayouts.data();
VkPushConstantRange pushConstantRange{};
pushConstantRange.size = sizeof(PushConstBlockMaterial);
pushConstantRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
pipelineLayoutCI.pushConstantRangeCount = 1;
pipelineLayoutCI.pPushConstantRanges = &pushConstantRange;
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
// Vertex bindings an attributes
VkVertexInputBindingDescription vertexInputBinding = { 0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX };
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 },
{ 1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3 },
{ 2, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6 },
{ 3, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 8 },
{ 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 10 },
{ 5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 14 },
{ 6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 18 }
};
VkPipelineVertexInputStateCreateInfo vertexInputStateCI{};
vertexInputStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCI.vertexBindingDescriptionCount = 1;
vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding;
vertexInputStateCI.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size());
vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data();
// Pipelines
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
VkGraphicsPipelineCreateInfo pipelineCI{};
pipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCI.layout = pipelineLayout;
pipelineCI.renderPass = renderPass;
pipelineCI.pInputAssemblyState = &inputAssemblyStateCI;
pipelineCI.pVertexInputState = &vertexInputStateCI;
pipelineCI.pRasterizationState = &rasterizationStateCI;
pipelineCI.pColorBlendState = &colorBlendStateCI;
pipelineCI.pMultisampleState = &multisampleStateCI;
pipelineCI.pViewportState = &viewportStateCI;
pipelineCI.pDepthStencilState = &depthStencilStateCI;
pipelineCI.pDynamicState = &dynamicStateCI;
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineCI.pStages = shaderStages.data();
if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples = setter.settings.sampleCount;
}
// Skybox pipeline (background cube)
shaderStages = {
loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
};
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox));
for (auto shaderStage : shaderStages) {
vkDestroyShaderModule(device, shaderStage.module, nullptr);
}
// PBR pipeline
shaderStages = {
loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
};
depthStencilStateCI.depthWriteEnable = VK_TRUE;
depthStencilStateCI.depthTestEnable = VK_TRUE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbr));
rasterizationStateCI.cullMode = VK_CULL_MODE_NONE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrDoubleSided));
rasterizationStateCI.cullMode = VK_CULL_MODE_NONE;
blendAttachmentState.blendEnable = VK_TRUE;
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrAlphaBlend));
for (auto shaderStage : shaderStages) {
vkDestroyShaderModule(device, shaderStage.module, nullptr);
}
//Create Tone Mapping render pipeline
//CreateToneMappingPipeline();
}
// generate two cube maps
// irradiance cube map
// prefileter environment cube map

View File

@ -124,22 +124,6 @@ public:
glm::vec3 camPos;
} shaderDataScene, shaderDataSkybox;
struct PushConstBlockMaterial {
glm::vec4 baseColorFactor;
glm::vec4 emissiveFactor;
glm::vec4 diffuseFactor;
glm::vec4 specularFactor;
float workflow;
int colorTextureSet;
int PhysicalDescriptorTextureSet;
int normalTextureSet;
int occlusionTextureSet;
int emissiveTextureSet;
float metallicFactor;
float roughnessFactor;
float alphaMask;
float alphaMaskCutoff;
} pushConstBlockMaterial;
@ -164,27 +148,9 @@ public:
VkDeviceMemory memory;
} vertexStaging, indexStaging;
struct Pipelines {
VkPipeline skybox;
VkPipeline pbr;
VkPipeline pbrDoubleSided;
VkPipeline pbrAlphaBlend;
VkPipeline solid;
VkPipeline wireframe = VK_NULL_HANDLE;
VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines;
VkPipeline boundPipeline = VK_NULL_HANDLE;
struct PipelineLayouts
{
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
VkPipelineLayout tonemappingLayout;
} pipelineLayouts;
VkPipelineLayout pipelineLayout;
struct DescriptorSets {
VkDescriptorSet scene;
@ -192,9 +158,6 @@ public:
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
};
std::vector<DescriptorSets> descriptorSets;

View File

@ -26,6 +26,39 @@ void VulkanBackend::VulkanFondation::initVulkan()
// 创建renderpass
createRenderPass();
// 创建资源描述符层级
createDescriptorSetLayout();
// 创建管线缓存
createPipelineCache();
// 创建图形管线
createGraphicPipeline();
// 创建主要帧缓冲区
createFramebuffer();
// 创建命令缓冲池
createCommandPool();
// 创建顶点缓存
createVertexBuffer();
// 创建索引缓存区
createIndexBuffer();
// 创建统一缓存区
createUniformBuffer();
// 创建资源描述存储池
createDescriptorPool();
// 创建资源描述符集
createDescriptorSets();
// 创建命令缓存区
createCommandBuffer();
}
@ -823,6 +856,8 @@ bool VulkanBackend::VulkanFondation::hasStencilComponent(VkFormat format)
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
}
void VulkanBackend::VulkanFondation::createDescriptorSetLayout()
{
// scene场景的资源描述符
@ -865,3 +900,248 @@ void VulkanBackend::VulkanFondation::createDescriptorSetLayout()
}
void VulkanBackend::VulkanFondation::createPipelineCache()
{
VkPipelineCacheCreateInfo pipelineCacheCreateInfo{};
pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
VK_CHECK_RESULT(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache));
}
void VulkanBackend::VulkanFondation::createGraphicPipeline()
{
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{};
inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssemblyStateCI.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPipelineRasterizationStateCreateInfo rasterizationStateCI{};
rasterizationStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL;
rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizationStateCI.lineWidth = 1.0f;
VkPipelineColorBlendAttachmentState blendAttachmentState{};
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
blendAttachmentState.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlendStateCI{};
colorBlendStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlendStateCI.attachmentCount = 1;
colorBlendStateCI.pAttachments = &blendAttachmentState;
VkPipelineDepthStencilStateCreateInfo depthStencilStateCI{};
depthStencilStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencilStateCI.depthTestEnable = VK_FALSE;
depthStencilStateCI.depthWriteEnable = VK_FALSE;
depthStencilStateCI.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
depthStencilStateCI.front = depthStencilStateCI.back;
depthStencilStateCI.back.compareOp = VK_COMPARE_OP_ALWAYS;
VkPipelineViewportStateCreateInfo viewportStateCI{};
viewportStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportStateCI.viewportCount = 1;
viewportStateCI.scissorCount = 1;
VkPipelineMultisampleStateCreateInfo multisampleStateCI{};
multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples = setter.settings.sampleCount;
}
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicStateCI{};
dynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicStateCI.pDynamicStates = dynamicStateEnables.data();
dynamicStateCI.dynamicStateCount = static_cast<uint32_t>(dynamicStateEnables.size());
// Pipeline layout
const std::vector<VkDescriptorSetLayout> setLayouts = {
descriptorSetLayouts.scene, descriptorSetLayouts.material, descriptorSetLayouts.node
};
VkPipelineLayoutCreateInfo pipelineLayoutCI{};
pipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCI.setLayoutCount = static_cast<uint32_t>(setLayouts.size());
pipelineLayoutCI.pSetLayouts = setLayouts.data();
VkPushConstantRange pushConstantRange{};
pushConstantRange.size = sizeof(pbrMaterial.pushConstBlockMaterial);
pushConstantRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
pipelineLayoutCI.pushConstantRangeCount = 1;
pipelineLayoutCI.pPushConstantRanges = &pushConstantRange;
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
// Vertex bindings an attributes
VkVertexInputBindingDescription vertexInputBinding = { 0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX };
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 },
{ 1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3 },
{ 2, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6 },
{ 3, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 8 },
{ 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 10 },
{ 5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 14 },
{ 6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 18 }
};
VkPipelineVertexInputStateCreateInfo vertexInputStateCI{};
vertexInputStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCI.vertexBindingDescriptionCount = 1;
vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding;
vertexInputStateCI.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size());
vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data();
// Pipelines
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
VkGraphicsPipelineCreateInfo pipelineCI{};
pipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCI.layout = pipelineLayout;
pipelineCI.renderPass = renderPass;
pipelineCI.pInputAssemblyState = &inputAssemblyStateCI;
pipelineCI.pVertexInputState = &vertexInputStateCI;
pipelineCI.pRasterizationState = &rasterizationStateCI;
pipelineCI.pColorBlendState = &colorBlendStateCI;
pipelineCI.pMultisampleState = &multisampleStateCI;
pipelineCI.pViewportState = &viewportStateCI;
pipelineCI.pDepthStencilState = &depthStencilStateCI;
pipelineCI.pDynamicState = &dynamicStateCI;
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineCI.pStages = shaderStages.data();
if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples = setter.settings.sampleCount;
}
// Skybox pipeline (background cube)
shaderStages = {
loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
};
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox));
for (auto shaderStage : shaderStages) {
vkDestroyShaderModule(device, shaderStage.module, nullptr);
}
// PBR pipeline
shaderStages = {
loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
};
depthStencilStateCI.depthWriteEnable = VK_TRUE;
depthStencilStateCI.depthTestEnable = VK_TRUE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbr));
rasterizationStateCI.cullMode = VK_CULL_MODE_NONE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrDoubleSided));
rasterizationStateCI.cullMode = VK_CULL_MODE_NONE;
blendAttachmentState.blendEnable = VK_TRUE;
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrAlphaBlend));
for (auto shaderStage : shaderStages) {
vkDestroyShaderModule(device, shaderStage.module, nullptr);
}
//Create Tone Mapping render pipeline
//CreateToneMappingPipeline();
}
void VulkanBackend::VulkanFondation::createFramebuffer()
{
}
void VulkanBackend::VulkanFondation::createCommandPool()
{
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS)
{
throw std::runtime_error("failed to create command pool in createCommandpool");
}
}
void VulkanBackend::VulkanFondation::createVertexBuffer()
{
}
void VulkanBackend::VulkanFondation::createIndexBuffer()
{
}
void VulkanBackend::VulkanFondation::createUniformBuffer()
{
}
void VulkanBackend::VulkanFondation::createDescriptorPool()
{
/*
Descriptor Pool
*/
uint32_t imageSamplerCount = 0;
uint32_t materialCount = 0;
uint32_t meshCount = 0;
// Environment samplers (radiance, irradiance, brdflut)
imageSamplerCount += 3;
std::vector<glTFModel::Model*> modellist = { &models.skybox, &models.scene };
for (auto& model : modellist) {
for (auto& material : model->materials) {
imageSamplerCount += 5;
materialCount++;
}
for (auto node : model->linearNodes) {
if (node->mesh) {
meshCount++;
}
}
}
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount }
};
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;
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool));
}
void VulkanBackend::VulkanFondation::createDescriptorSets()
{
}
void VulkanBackend::VulkanFondation::createCommandBuffer()
{
}

View File

@ -9,6 +9,9 @@
#include "renderSetter.h"
#include <VulkanSwapChain.hpp>
#include "glTFModel.h"
#include "VulkanUtils.hpp"
#include "PBR.h"
namespace VulkanBackend
{
@ -35,6 +38,7 @@ namespace VulkanBackend
private:
VulkanBackend::Setter setter;
PBR::Material pbrMaterial;
VkInstance instance;
@ -91,12 +95,44 @@ namespace VulkanBackend
VkRenderPass renderPass;
VkCommandPool commandPool;
struct Models
{
glTFModel::Model scene;
glTFModel::Model skybox;
} models;
struct DescriptorSetLayouts {
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
} descriptorSetLayouts;
struct Pipelines {
VkPipeline skybox;
VkPipeline pbr;
VkPipeline pbrDoubleSided;
VkPipeline pbrAlphaBlend;
VkPipeline solid;
VkPipeline wireframe = VK_NULL_HANDLE;
VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines;
VkPipeline boundPipeline = VK_NULL_HANDLE;
struct PipelineLayouts
{
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
VkPipelineLayout tonemappingLayout;
} pipelineLayouts;
VkPipelineLayout pipelineLayout;
VkPipelineCache pipelineCache;
// 句柄创建,检查校验层支持和获取需要的扩展
void createInstance();
bool checkValidationLayerSupport();
@ -143,6 +179,9 @@ namespace VulkanBackend
// 创建资源描述符层级,用于访问绑定的资源
void createDescriptorSetLayout();
// 创建管线缓存
void createPipelineCache();
// 创建图形管线
void createGraphicPipeline();
@ -167,6 +206,8 @@ namespace VulkanBackend
// 创建描述符集合
void createDescriptorSets();
// 创建命令缓存区
void createCommandBuffer();
};