diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 8fd18389..24cf43d8 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -3,6 +3,7 @@ #include"VulkanAppFramework.h" #include +#include using namespace hgl; using namespace hgl::graph; @@ -105,22 +106,24 @@ private: { constexpr os_char PIPELINE_FILENAME[]=OS_TEXT("2DSolid.pipeline"); - { - vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass()); - pipeline_creater->SetDepthTest(false); - pipeline_creater->SetDepthWrite(false); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(PRIM_TRIANGLES); + //{ + // vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent()); + // pipeline_creater->SetDepthTest(false); + // pipeline_creater->SetDepthWrite(false); + // pipeline_creater->CloseCullFace(); + // pipeline_creater->Set(PRIM_TRIANGLES); - SaveToFile(PIPELINE_FILENAME,pipeline_creater); + // SaveToFile(PIPELINE_FILENAME,pipeline_creater); - delete pipeline_creater; - } + // delete pipeline_creater; + //} { - vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass()); + void *data; + uint size=filesystem::LoadFileToMemory(PIPELINE_FILENAME,(void **)&data); + + vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent(),(uchar *)data,size); - LoadFromFile(PIPELINE_FILENAME,pipeline_creater); pipeline=pipeline_creater->Create(); delete pipeline_creater; diff --git a/inc/hgl/graph/vulkan/VKPipeline.h b/inc/hgl/graph/vulkan/VKPipeline.h index 39c71f5e..5f224e74 100644 --- a/inc/hgl/graph/vulkan/VKPipeline.h +++ b/inc/hgl/graph/vulkan/VKPipeline.h @@ -17,6 +17,8 @@ public: operator VkPipeline(){return pipeline;} };//class GraphicsPipeline +constexpr size_t MAX_SAMPLE_MASK_COUNT=(VK_SAMPLE_COUNT_64_BIT+31)/32; + class PipelineCreater { VkDevice device; @@ -25,26 +27,37 @@ class PipelineCreater VkGraphicsPipelineCreateInfo pipelineInfo; VkPipelineVertexInputStateCreateInfo vis_create_info; + + void InitVertexInputState(const Material *); + VkPipelineInputAssemblyStateCreateInfo inputAssembly; + VkPipelineTessellationStateCreateInfo tessellation; VkViewport viewport; VkRect2D scissor; VkPipelineViewportStateCreateInfo viewportState; - VkPipelineDepthStencilStateCreateInfo depthStencilState; + + void InitViewportState(); VkPipelineRasterizationStateCreateInfo rasterizer; VkPipelineMultisampleStateCreateInfo multisampling; + VkSampleMask sample_mask[MAX_SAMPLE_MASK_COUNT]; + + VkPipelineDepthStencilStateCreateInfo depthStencilState; - VkPipelineColorBlendAttachmentState colorBlendAttachment; VkPipelineColorBlendStateCreateInfo colorBlending; + List colorBlendAttachments; VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; VkPipelineDynamicStateCreateInfo dynamicState; + void InitDynamicState(); + public: - PipelineCreater(Device *dev,const Material *,RenderPass *rp); + PipelineCreater(Device *dev,const Material *,RenderPass *rp,const VkExtent2D &); + PipelineCreater(Device *dev,const Material *,RenderPass *rp,const VkExtent2D &,uchar *,uint); ~PipelineCreater()=default; bool Set(const VkPrimitiveTopology,bool=false); @@ -80,19 +93,43 @@ public: multisampling.rasterizationSamples=sc; } - void SetColorWriteMask(bool r,bool g,bool b,bool a) + bool SetColorWriteMask(uint index,bool r,bool g,bool b,bool a) { - colorBlendAttachment.colorWriteMask=0; + VkPipelineColorBlendAttachmentState *cba=colorBlendAttachments.GetPointer(index); + + if(!cba)return(false); - if(r)colorBlendAttachment.colorWriteMask|=VK_COLOR_COMPONENT_R_BIT; - if(r)colorBlendAttachment.colorWriteMask|=VK_COLOR_COMPONENT_G_BIT; - if(g)colorBlendAttachment.colorWriteMask|=VK_COLOR_COMPONENT_B_BIT; - if(a)colorBlendAttachment.colorWriteMask|=VK_COLOR_COMPONENT_A_BIT; + cba->colorWriteMask=0; + + if(r)cba->colorWriteMask|=VK_COLOR_COMPONENT_R_BIT; + if(r)cba->colorWriteMask|=VK_COLOR_COMPONENT_G_BIT; + if(g)cba->colorWriteMask|=VK_COLOR_COMPONENT_B_BIT; + if(a)cba->colorWriteMask|=VK_COLOR_COMPONENT_A_BIT; + + return(true); } - void SetBlend( bool blend) {colorBlendAttachment.blendEnable=blend;} - void SetLogicOp( VkLogicOp logic_op) {colorBlending.logicOpEnable=VK_TRUE;colorBlending.logicOp=logic_op;} - void DisableLogicOp() {colorBlending.logicOpEnable=VK_FALSE;} + void AddColorBlendAttachment(const VkPipelineColorBlendAttachmentState *cba) + { + if(!cba)return; + + colorBlendAttachments.Add(*cba); + colorBlending.attachmentCount=colorBlendAttachments.GetCount(); + } + + bool SetBlend(uint index,bool blend) + { + VkPipelineColorBlendAttachmentState *cba=colorBlendAttachments.GetPointer(index); + + if(!cba)return(false); + + cba->blendEnable=blend; + + return(true); + } + + void SetLogicOp(VkLogicOp logic_op) {colorBlending.logicOpEnable=VK_TRUE;colorBlending.logicOp=logic_op;} + void DisableLogicOp() {colorBlending.logicOpEnable=VK_FALSE;} void SetBlendConstans(float r,float g,float b,float a) { diff --git a/inc/hgl/type/List.h b/inc/hgl/type/List.h index 3caf0105..11c6616a 100644 --- a/inc/hgl/type/List.h +++ b/inc/hgl/type/List.h @@ -62,6 +62,11 @@ namespace hgl virtual void operator << (const T &obj){Add(obj);} ///<操作符重载添加一个数据 virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据 + T * GetPointer(const int index) ///<取得指定序列号数据的索引 + { + return(index>=count?nullptr:items+index); + } + bool Get(int,T &)const; ///<取得指定索引处的数据 void Set(int,const T &); ///<设置指定索引处的数据 bool Rand(T &)const; ///<随机取得一个数据 diff --git a/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp b/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp index 0a72a67e..df6d637d 100644 --- a/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp +++ b/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -42,6 +42,11 @@ bool PipelineCreater::SaveToStream(io::DataOutputStream *dos) return(true); } +#define CHECK_SIZE_AND_COPY(ptr,type) if(size0) { - pipelineInfo.pMultisampleState->pSampleMask=(const VkSampleMask *)data; + memcpy(sample_mask,data,count); + multisampling.pSampleMask=sample_mask; data+=count; size=count; } else { - pipelineInfo.pMultisampleState->pSampleMask=nullptr; + multisampling.pSampleMask=nullptr; } - if(size0) + { + if(sizeGetDevice(); - extent=dev->GetExtent(); - cache=dev->GetPipelineCache(); - - //未来这里需要增加是否有vs/fs的检测 - - hgl_zero(pipelineInfo); - pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineInfo.layout = material->GetPipelineLayout(); pipelineInfo.stageCount = material->GetStageCount(); pipelineInfo.pStages = material->GetStages(); - { - pipelineInfo.renderPass = *rp; - pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进 - } - { vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vis_create_info.pNext = nullptr; @@ -37,7 +23,10 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass pipelineInfo.pVertexInputState=&vis_create_info; } +} +void PipelineCreater::InitViewportState() +{ viewport.x = 0.0f; viewport.y = 0.0f; viewport.width = extent.width; @@ -57,27 +46,40 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass viewportState.pScissors = &scissor; pipelineInfo.pViewportState = &viewportState; +} - 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; +void PipelineCreater::InitDynamicState() +{ + memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); - pipelineInfo.pDepthStencilState=&depthStencilState; + 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); + + pipelineInfo.pTessellationState=nullptr; + + InitViewportState(); rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.pNext = nullptr; @@ -107,22 +109,46 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass pipelineInfo.pMultisampleState = &multisampling; - colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - colorBlendAttachment.blendEnable = VK_FALSE; - colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; - colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; - colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + 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; + + 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; + + colorBlendAttachments.Add(cba); colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.pNext = nullptr; colorBlending.flags = 0; colorBlending.logicOpEnable = VK_FALSE; colorBlending.logicOp = VK_LOGIC_OP_COPY; - colorBlending.attachmentCount = 1; - colorBlending.pAttachments = &colorBlendAttachment; + colorBlending.attachmentCount = colorBlendAttachments.GetCount(); + colorBlending.pAttachments = colorBlendAttachments.GetData(); colorBlending.blendConstants[0] = 0.0f; colorBlending.blendConstants[1] = 0.0f; colorBlending.blendConstants[2] = 0.0f; @@ -130,19 +156,52 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,RenderPass pipelineInfo.pColorBlendState = &colorBlending; - memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); - 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; + InitDynamicState(); - pipelineInfo.pDynamicState=&dynamicState; + pipelineInfo.layout = material->GetPipelineLayout(); + { + pipelineInfo.renderPass = *rp; + pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进 + } - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - pipelineInfo.basePipelineIndex = 0; + { + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + pipelineInfo.basePipelineIndex = 0; + } +} + +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; + pipelineInfo.basePipelineIndex = 0; + } } bool PipelineCreater::Set(const VkPrimitiveTopology topology,bool restart)