2019-04-30 16:42:59 +08:00
|
|
|
|
#include<hgl/graph/vulkan/VKPipeline.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKDevice.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKMaterial.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKRenderPass.h>
|
2019-04-18 16:38:58 +08:00
|
|
|
|
|
|
|
|
|
VK_NAMESPACE_BEGIN
|
2019-04-18 16:53:14 +08:00
|
|
|
|
Pipeline::~Pipeline()
|
|
|
|
|
{
|
|
|
|
|
vkDestroyPipeline(device,pipeline,nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
void PipelineCreater::InitVertexInputState(const Material *material)
|
2019-04-18 16:53:14 +08:00
|
|
|
|
{
|
2019-04-28 21:25:52 +08:00
|
|
|
|
pipelineInfo.stageCount = material->GetStageCount();
|
|
|
|
|
pipelineInfo.pStages = material->GetStages();
|
2019-04-18 16:53:14 +08:00
|
|
|
|
|
2019-04-20 16:12:22 +08:00
|
|
|
|
{
|
|
|
|
|
vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
|
|
|
vis_create_info.pNext = nullptr;
|
|
|
|
|
vis_create_info.flags = 0;
|
|
|
|
|
|
2019-04-28 17:47:58 +08:00
|
|
|
|
material->Write(vis_create_info);
|
2019-04-20 16:12:22 +08:00
|
|
|
|
|
|
|
|
|
pipelineInfo.pVertexInputState=&vis_create_info;
|
|
|
|
|
}
|
2019-05-17 19:22:13 +08:00
|
|
|
|
}
|
2019-04-20 16:12:22 +08:00
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
void PipelineCreater::InitViewportState()
|
|
|
|
|
{
|
2019-04-18 16:53:14 +08:00
|
|
|
|
viewport.x = 0.0f;
|
|
|
|
|
viewport.y = 0.0f;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
viewport.width = extent.width;
|
|
|
|
|
viewport.height = extent.height;
|
2019-04-18 16:53:14 +08:00
|
|
|
|
viewport.minDepth = 0.0f;
|
|
|
|
|
viewport.maxDepth = 1.0f;
|
|
|
|
|
|
|
|
|
|
scissor.offset = {0, 0};
|
2019-04-18 21:02:42 +08:00
|
|
|
|
scissor.extent = extent;
|
2019-04-18 16:53:14 +08:00
|
|
|
|
|
|
|
|
|
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
2019-04-20 01:01:44 +08:00
|
|
|
|
viewportState.pNext = nullptr;
|
|
|
|
|
viewportState.flags = 0;
|
2019-04-18 16:53:14 +08:00
|
|
|
|
viewportState.viewportCount = 1;
|
|
|
|
|
viewportState.pViewports = &viewport;
|
|
|
|
|
viewportState.scissorCount = 1;
|
|
|
|
|
viewportState.pScissors = &scissor;
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pViewportState = &viewportState;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
}
|
2019-04-18 21:02:42 +08:00
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
void PipelineCreater::InitDynamicState()
|
|
|
|
|
{
|
|
|
|
|
memset(dynamicStateEnables, 0, sizeof dynamicStateEnables);
|
2019-04-19 22:27:52 +08:00
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
|
|
|
|
dynamicState.pNext = nullptr;
|
|
|
|
|
dynamicState.flags = 0;
|
|
|
|
|
dynamicState.pDynamicStates = dynamicStateEnables;
|
|
|
|
|
dynamicState.dynamicStateCount = 0;
|
|
|
|
|
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
|
|
|
|
|
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pDynamicState=&dynamicState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//为什么一定要把ext放在这里,因为如果不放在这里,总是会让人遗忘它的重要性
|
|
|
|
|
|
|
|
|
|
PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass *rp,const VkExtent2D &ext)
|
|
|
|
|
{
|
|
|
|
|
device=dev->GetDevice();
|
|
|
|
|
extent=ext;
|
|
|
|
|
cache=dev->GetPipelineCache();
|
|
|
|
|
|
|
|
|
|
//未来这里需要增加是否有vs/fs的检测
|
|
|
|
|
|
|
|
|
|
hgl_zero(pipelineInfo);
|
|
|
|
|
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
|
|
|
InitVertexInputState(material);
|
|
|
|
|
|
2019-05-18 00:08:41 +08:00
|
|
|
|
tessellation.sType=VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
|
|
|
|
|
tessellation.pNext=nullptr;
|
|
|
|
|
tessellation.flags=0;
|
|
|
|
|
tessellation.patchControlPoints=0;
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pTessellationState=&tessellation;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
|
|
|
|
|
InitViewportState();
|
2019-04-19 22:27:52 +08:00
|
|
|
|
|
2019-04-18 21:02:42 +08:00
|
|
|
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
2019-04-19 22:27:52 +08:00
|
|
|
|
rasterizer.pNext = nullptr;
|
|
|
|
|
rasterizer.flags = 0;
|
2019-05-05 14:22:58 +08:00
|
|
|
|
rasterizer.depthClampEnable = VK_FALSE;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
|
|
|
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
2019-04-20 17:41:44 +08:00
|
|
|
|
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
|
|
|
|
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; //顺时针
|
2019-04-18 21:02:42 +08:00
|
|
|
|
rasterizer.depthBiasEnable = VK_FALSE;
|
2019-04-20 01:01:44 +08:00
|
|
|
|
rasterizer.depthBiasConstantFactor = 0;
|
|
|
|
|
rasterizer.depthBiasClamp = 0;
|
|
|
|
|
rasterizer.depthBiasSlopeFactor = 0;
|
2019-04-19 22:27:52 +08:00
|
|
|
|
rasterizer.lineWidth = 1.0f;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
|
|
|
|
|
pipelineInfo.pRasterizationState = &rasterizer;
|
|
|
|
|
|
|
|
|
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
2019-04-19 22:27:52 +08:00
|
|
|
|
multisampling.pNext = nullptr;
|
|
|
|
|
multisampling.flags = 0;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
2019-04-19 22:27:52 +08:00
|
|
|
|
multisampling.sampleShadingEnable = VK_FALSE;
|
|
|
|
|
multisampling.minSampleShading = 0.0;
|
|
|
|
|
multisampling.pSampleMask = nullptr;
|
|
|
|
|
multisampling.alphaToCoverageEnable = VK_FALSE;
|
|
|
|
|
multisampling.alphaToOneEnable = VK_FALSE;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
|
|
|
|
|
pipelineInfo.pMultisampleState = &multisampling;
|
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
|
|
|
depthStencilState.pNext = nullptr;
|
|
|
|
|
depthStencilState.flags = 0;
|
|
|
|
|
depthStencilState.depthTestEnable = VK_TRUE;
|
|
|
|
|
depthStencilState.depthWriteEnable = VK_TRUE;
|
|
|
|
|
depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
|
|
|
|
depthStencilState.depthBoundsTestEnable = VK_FALSE;
|
|
|
|
|
depthStencilState.minDepthBounds = 0;
|
|
|
|
|
depthStencilState.maxDepthBounds = 0;
|
|
|
|
|
depthStencilState.stencilTestEnable = VK_FALSE;
|
|
|
|
|
depthStencilState.back.failOp = VK_STENCIL_OP_KEEP;
|
|
|
|
|
depthStencilState.back.passOp = VK_STENCIL_OP_KEEP;
|
|
|
|
|
depthStencilState.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
|
|
|
depthStencilState.back.compareMask = 0;
|
|
|
|
|
depthStencilState.back.reference = 0;
|
|
|
|
|
depthStencilState.back.depthFailOp = VK_STENCIL_OP_KEEP;
|
|
|
|
|
depthStencilState.back.writeMask = 0;
|
|
|
|
|
depthStencilState.front = depthStencilState.back;
|
2019-07-10 21:00:36 +08:00
|
|
|
|
depthStencilState.front.compareOp=VK_COMPARE_OP_NEVER;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
|
|
|
|
|
pipelineInfo.pDepthStencilState=&depthStencilState;
|
|
|
|
|
|
|
|
|
|
VkPipelineColorBlendAttachmentState cba;
|
|
|
|
|
cba.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
|
|
|
|
cba.blendEnable = VK_FALSE;
|
|
|
|
|
cba.alphaBlendOp = VK_BLEND_OP_ADD;
|
|
|
|
|
cba.colorBlendOp = VK_BLEND_OP_ADD;
|
|
|
|
|
cba.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
|
cba.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
|
cba.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
|
cba.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
|
|
2019-07-10 14:55:34 +08:00
|
|
|
|
colorBlendAttachments.Add(cba,rp->GetColorCount()); //这个需要和subpass中的color attachment数量相等,所以添加多份
|
2019-04-18 21:02:42 +08:00
|
|
|
|
|
2019-05-23 13:29:23 +08:00
|
|
|
|
alpha_blend=false;
|
|
|
|
|
|
2019-04-18 21:02:42 +08:00
|
|
|
|
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
2019-04-20 01:01:44 +08:00
|
|
|
|
colorBlending.pNext = nullptr;
|
|
|
|
|
colorBlending.flags = 0;
|
2019-04-18 21:02:42 +08:00
|
|
|
|
colorBlending.logicOpEnable = VK_FALSE;
|
2019-07-08 20:53:07 +08:00
|
|
|
|
colorBlending.logicOp = VK_LOGIC_OP_CLEAR;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
colorBlending.attachmentCount = colorBlendAttachments.GetCount();
|
|
|
|
|
colorBlending.pAttachments = colorBlendAttachments.GetData();
|
2019-04-18 21:02:42 +08:00
|
|
|
|
colorBlending.blendConstants[0] = 0.0f;
|
|
|
|
|
colorBlending.blendConstants[1] = 0.0f;
|
|
|
|
|
colorBlending.blendConstants[2] = 0.0f;
|
|
|
|
|
colorBlending.blendConstants[3] = 0.0f;
|
2019-04-19 22:27:52 +08:00
|
|
|
|
|
2019-04-18 21:02:42 +08:00
|
|
|
|
pipelineInfo.pColorBlendState = &colorBlending;
|
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
InitDynamicState();
|
2019-04-19 22:27:52 +08:00
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
pipelineInfo.layout = material->GetPipelineLayout();
|
|
|
|
|
{
|
|
|
|
|
pipelineInfo.renderPass = *rp;
|
|
|
|
|
pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进
|
|
|
|
|
}
|
2019-04-20 01:01:44 +08:00
|
|
|
|
|
2019-05-17 19:22:13 +08:00
|
|
|
|
{
|
|
|
|
|
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
2019-07-10 21:00:36 +08:00
|
|
|
|
pipelineInfo.basePipelineIndex = -1;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass *rp,const VkExtent2D &ext,uchar *data,uint size)
|
|
|
|
|
{
|
|
|
|
|
LoadFromMemory(data,size);
|
|
|
|
|
|
|
|
|
|
device=dev->GetDevice();
|
|
|
|
|
extent=ext;
|
|
|
|
|
cache=dev->GetPipelineCache();
|
|
|
|
|
|
|
|
|
|
InitVertexInputState(material);
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pInputAssemblyState=&inputAssembly;
|
|
|
|
|
pipelineInfo.pTessellationState =&tessellation;
|
|
|
|
|
|
|
|
|
|
InitViewportState();
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pRasterizationState=&rasterizer;
|
|
|
|
|
pipelineInfo.pMultisampleState =&multisampling;
|
|
|
|
|
pipelineInfo.pDepthStencilState =&depthStencilState;
|
|
|
|
|
pipelineInfo.pColorBlendState =&colorBlending;
|
|
|
|
|
|
|
|
|
|
InitDynamicState();
|
|
|
|
|
|
|
|
|
|
pipelineInfo.layout = material->GetPipelineLayout();
|
|
|
|
|
{
|
|
|
|
|
pipelineInfo.renderPass = *rp;
|
|
|
|
|
pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
2019-07-10 21:00:36 +08:00
|
|
|
|
pipelineInfo.basePipelineIndex = -1;
|
2019-05-17 19:22:13 +08:00
|
|
|
|
}
|
2019-04-18 16:53:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PipelineCreater::Set(const VkPrimitiveTopology topology,bool restart)
|
|
|
|
|
{
|
2019-04-19 12:11:16 +08:00
|
|
|
|
if(topology<VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE||topology>VK_PRIMITIVE_TOPOLOGY_END_RANGE)
|
|
|
|
|
if(topology!=PRIM_RECTANGLE)return(false);
|
2019-04-18 16:53:14 +08:00
|
|
|
|
|
|
|
|
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
2019-04-20 16:12:22 +08:00
|
|
|
|
inputAssembly.pNext = nullptr;
|
|
|
|
|
inputAssembly.flags = 0;
|
2019-04-19 12:11:16 +08:00
|
|
|
|
inputAssembly.topology = (topology==PRIM_RECTANGLE?VK_PRIMITIVE_TOPOLOGY_POINT_LIST:topology);
|
2019-04-18 16:53:14 +08:00
|
|
|
|
inputAssembly.primitiveRestartEnable = restart;
|
|
|
|
|
|
|
|
|
|
pipelineInfo.pInputAssemblyState = &inputAssembly;
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-18 21:02:42 +08:00
|
|
|
|
Pipeline *PipelineCreater::Create()
|
|
|
|
|
{
|
2019-04-18 16:53:14 +08:00
|
|
|
|
VkPipeline graphicsPipeline;
|
2019-04-18 16:38:58 +08:00
|
|
|
|
|
2019-04-20 01:01:44 +08:00
|
|
|
|
if (vkCreateGraphicsPipelines(device, cache, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS)
|
2019-04-18 16:53:14 +08:00
|
|
|
|
return(nullptr);
|
2019-04-18 16:38:58 +08:00
|
|
|
|
|
2019-05-23 13:29:23 +08:00
|
|
|
|
return(new Pipeline(device,graphicsPipeline,alpha_test>0,alpha_blend));
|
2019-04-18 16:38:58 +08:00
|
|
|
|
}
|
|
|
|
|
VK_NAMESPACE_END
|