Hi, guys, I have a new idea with how to create a pipeline and render pass,
I create de json file with all of the paramenter needed in a json file. a renderpass with a json file, a pipeline with a json file. now I get some problem which I can’t resovle. I create the renderpass success, and the pipeline layout success, but it is failed when create the pipeline. I think there should be some error parameters in the json file
{
"subpassDesc":[
{
"pipelineBindPoint":"VK_PIPELINE_BIND_POINT_GRAPHIC",
"inputAttachments":[],
"colorAttachments":[
{
"attachment":0,
"layout":"VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL"
}
],
"depthStencilAttachment":[
{
"attachment":1,
"layout":"VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL"
}
],
"resolveAttachments":[],
"preserveAttachments":[]
}
],
"attachDesc":[
{
"format":"VK_FORMAT_B8G8R8A8_UNORM",
"loadOp":"VK_ATTACHMENT_LOAD_OP_CLEAR",
"storeOp":"VK_ATTACHMENT_STORE_OP_STORE",
"stencilLoadOp":"VK_ATACHMENT_LOAD_OP_DONT_CARE",
"stencilStoreOp":"VK_ATTACHMENT_STORE_OP_DONT_CARE",
"initialLayout":"VK_IMAGE_LAYOUT_UNDEFINED",
"finalLayout":"VK_IMAGE_LAYOUT_PRESENT_SRC_KHR",
"samples":"VK_SAMPLE_COUNT_1_BIT"
},
{
"format":"VK_FORMAT_D32_SFLOAT",
"loadOp":"VK_ATTACHMENT_LOAD_OP_CLEAR",
"storeOp":"VK_ATTACHMENT_STORE_OP_DONT_CARE",
"stencilLoadOp":"VK_ATACHMENT_LOAD_OP_DONT_CARE",
"stencilStoreOp":"VK_ATTACHMENT_STORE_OP_STORE",
"initialLayout":"VK_IMAGE_LAYOUT_UNDEFINED",
"finalLayout":"VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL",
"samples":"VK_SAMPLE_COUNT_1_BIT"
}
],
"dependencies":[
{
"dependencyFlags":"VK_DEPENDENCY_BY_REGION_BIT",
"srcSubpass":"VK_SUBPASS_EXTERNAL",
"dstSubpass":0,
"srcStageMask":"VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT",
"dstStageMask":"VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT",
"srcAccessMask":["VK_ACCESS_MEMORY_READ_BIT"],
"dstAccessMask":["VK_ACCESS_COLOR_ATTACHMENT_READ_BIT", "VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT"]
},
{
"dependencyFlags":"VK_DEPENDENCY_BY_REGION_BIT",
"srcSubpass":0,
"dstSubpass":"VK_SUBPASS_EXTERNAL",
"srcStageMask":"VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT",
"dstStageMask":"VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT",
"srcAccessMask":["VK_ACCESS_COLOR_ATTACHMENT_READ_BIT", "VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT"],
"dstAccessMask":["VK_ACCESS_MEMORY_READ_BIT"]
}
]
}
{
"name":"first",
"ShaderStages":[
{
"stage":1,
"module":"vert_fst.spv",
"pName":"main",
"pSpecializationInfo":""
},
{
"stage":5,
"module":"frag_fst.spv",
"pName":"main",
"pSpecializationInfo":""
}
],
"VertexInput":{},
"InputAssemble":{
"topology":"VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST",
"primitiveRestart":0
},
"Tessellation":{
"patchControlPoints":0
},
"Viewport":{
"pViewports":[
{"x":0,"y":0, "w":1000, "h":1000, "minDepth":0.0, "maxDepth":1.0}
],
"pScissors":[
{
"offset":{"x":0, "y":0},
"extent":{"w":1000, "h":1000}
}
]
},
"Rasterization":{
"depthClampEnable":"VK_FALSE",
"rasterDiscard":"VK_FALSE",
"polygonMode":"VK_POLYGON_MODE_FILL",
"cullMode":"VK_CULL_MODE_NONE",
"frontFace":"VK_FRONT_FACE_COUNTER_CLOCKWISE",
"depthBiasEnable":"VK_FALSE",
"depthBiasConstantFactor":1.0,
"depthBiasClamp":0.0,
"depthBiasSlopeFactor":0.0,
"lineWidth":1.0
},
"MultiSample":{
"rasterizationSamples":"VK_SAMPLE_COUNT_1_BIT",
"sampleShadingEnable":"VK_FALSE",
"minSampleShading":1.0,
"pSampleMask":[1],
"alphaToCoverageEnable":"VK_FALSE",
"alphaToOneEnable":"VK_FALSE"
},
"DepthStencil":{
"depthTestEnable":"VK_FALSE",
"depthWriteEnable":"VK_TRUE",
"depthCompareOp":"VK_COMPARE_OP_LESS_OR_EQUAL",
"depthBoundsTestEnable":"VK_FALSE",
"front":{
"failOp":"VK_STENCIL_OP_KEEP",
"passOp":"VK_STENCIL_OP_KEEP",
"depthFailOp":"VK_STENCIL_OP_KEEP",
"compareOp":"VK_COMPARE_OP_ALWAYS",
"compareMask":1,
"writeMask":1,
"reference":0
},
"back":{
"failOp":"VK_STENCIL_OP_KEEP",
"passOp":"VK_STENCIL_OP_KEEP",
"depthFailOp":"VK_STENCIL_OP_KEEP",
"compareOp":"VK_COMPARE_OP_ALWAYS",
"compareMask":0,
"writeMask":0,
"reference":0
},
"minDepthBounds":0.0,
"maxDepthBounds":1.0,
"stencilTestEnable":"VK_FALSE"
},
"ColorBlend":{
"logicOpEnable":"VK_FALSE",
"logicOp":"VK_LOGIC_OP_COPY",
"pAttachments":[
{
"blendEnable":"VK_TRUE",
"srcColorBlendFactor":"VK_BLEND_FACTOR_SRC_COLOR",
"dstColorBlendFactor":"VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR",
"colorBlendOp":"VK_BLEND_OP_ADD",
"srcAlphaBlendFactor":"VK_BLEND_FACTOR_SRC_ALPHA",
"dstAlphaBlendFactor":"VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA",
"alphaBlendOp":"VK_BLEND_OP_ADD",
"colorWriteMask":["VK_COLOR_COMPONENT_R_BIT","VK_COLOR_COMPONENT_G_BIT",
"VK_COLOR_COMPONENT_B_BIT","VK_COLOR_COMPONENT_A_BIT"]
}
],
"blendConstants":[1.0, 1.0, 1.0, 1.0]
},
"DynamicState":[
"VK_DYNAMIC_STATE_VIEWPORT",
"VK_DYNAMIC_STATE_SCISSOR",
"VK_DYNAMIC_STATE_LINE_WIDTH",
"VK_DYNAMIC_STATE_DEPTH_BIAS"
],
"layout":[]
}
here is the code about how to create pipeline layout from json
bool TKPipelineLayout::initWithJsonValue(const Json::Value &value){
if(value.isArray() == false){
return false;
}
uint32_t size = value.size();
VkDevice device = VK_INFO->device;
std::vector<VkDescriptorSetLayoutBinding> bindings;
for(uint32_t i=0; i<size; ++i){
VkDescriptorSetLayoutBinding layoutBind;
layoutBind.binding = value[i]["binding"].asUInt();
layoutBind.descriptorCount = value[i]["descriptorCount"].asUInt();
layoutBind.descriptorType = TKVkUtility::VkDecriptorTypeFrom(value[i]["desciptorType"].asString());
layoutBind.stageFlags = TKVkUtility::VkShaderStageFlagBitsFrom(value[i]["stageFlags"].asString());
layoutBind.pImmutableSamplers = nullptr;
bindings.push_back(layoutBind);
}
TKLog("binding count %lu, data %p\n", bindings.size(), bindings.data());
uint32_t swapCount = VK_INFO->swapchainImageViews.size();
m_descSets.resize(swapCount);
m_descSetLayouts.resize(swapCount);
for(uint32_t i=0; i<swapCount; ++i){
std::vector<VkDescriptorSetLayoutCreateInfo> setLayoutCreateInfo(1);
setLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
setLayoutCreateInfo[0].pNext = nullptr;
setLayoutCreateInfo[0].flags = 0;
setLayoutCreateInfo[0].bindingCount = bindings.size();
setLayoutCreateInfo[0].pBindings = bindings.data();
vkCreateDescriptorSetLayout(device, &setLayoutCreateInfo[0],
nullptr, &m_descSetLayouts[i]);
}
VkPipelineLayoutCreateInfo layoutInfo;
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
layoutInfo.pNext = nullptr;
layoutInfo.flags = 0;
layoutInfo.setLayoutCount = m_descSetLayouts.size();
layoutInfo.pSetLayouts = m_descSetLayouts.data();
layoutInfo.pushConstantRangeCount = 0;
layoutInfo.pPushConstantRanges = nullptr;
if(VK_SUCCESS != vkCreatePipelineLayout(device, &layoutInfo, nullptr, &m_layout)){
TKLog("init pipeline layout failed!\n");
return false;
}
TKLog("init pipeline layout %p success!\n", m_layout);
for(uint32_t i=0; i<swapCount; ++i){
VkDescriptorSetAllocateInfo descSetAllocInfo;
descSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
descSetAllocInfo.pNext = nullptr;
descSetAllocInfo.descriptorPool = VK_INFO->descriptorPool;
descSetAllocInfo.descriptorSetCount = 1;
descSetAllocInfo.pSetLayouts = &m_descSetLayouts[i];
vkAllocateDescriptorSets(device, &descSetAllocInfo, &m_descSets[i]);
TKLog("alloc descriptor sets %p\n", m_descSets[i]);
}
return true;
}
here is the code about how to create reanderpass
bool TKRenderPass::initWithJson(const std::string &fileName){
char buf0[512];
sprintf(buf0, "%s/Json/%s", PROJECT_PATH, fileName.c_str());
FILE *fp = fopen(buf0, "rt");
if(fp == nullptr){
TKLog("Open file %s failed!\n", fileName.c_str());
assert(fp != nullptr);
return false;
}
char tmp;
uint64_t size = 1;
while(fread(&tmp, sizeof(char), 1, fp)==1){
++ size;
}
char buf[size];
buf[size-1] = '\0';
fseek(fp, 0, SEEK_SET);
fread(buf, sizeof(char), size, fp);
fclose(fp);
std::string content(buf);
Json::Value root;
Json::Reader reader;
reader.parse(content, root);
VkRenderPassCreateInfo info;
Json::Value subpassDesValue = root["subpassDesc"];
std::vector<VkSubpassDescription> subpassDescArr;
if(false == subpassDesValue.isArray()){
return false;
}else{
for(uint32_t i=0; i<subpassDesValue.size();++i){
subpassDescArr.push_back(this->_getSubpassDescFromJson(subpassDesValue[i], i));
}
}
info.subpassCount = subpassDescArr.size();
info.pSubpasses = subpassDescArr.data();
Json::Value attachDescValue = root["attachDesc"];
std::vector<VkAttachmentDescription> attachmentDescArr;
if(false == attachDescValue.isArray()){
return false;
}else{
for(uint32_t i=0; i<attachDescValue.size(); ++i){
attachmentDescArr.push_back(this->_getAttachmentDescription(attachDescValue[i]));
}
}
info.attachmentCount = attachmentDescArr.size();
info.pAttachments = attachmentDescArr.data();
m_colorAttachmentCount = info.attachmentCount;
Json::Value dependencyValue = root["dependencies"];
if(false == dependencyValue.isArray()){
return false;
}
std::vector<VkSubpassDependency> subpassDepArr;
if(dependencyValue.size()==0){
info.dependencyCount = 0;
info.pDependencies = nullptr;
}else{
for(uint32_t i=0; i<dependencyValue.size(); ++i){
subpassDepArr.push_back(this->_getDependencyFromJson(dependencyValue[i]));
}
}
info.dependencyCount = subpassDepArr.size();
info.pDependencies = subpassDepArr.data();
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
int ret = vkCreateRenderPass(VK_INFO->device, &info, nullptr, &m_renderPass);
if(ret != VK_SUCCESS){
return false;
}
TKLog("init render pass with json success\n");
return true;
}
VkRenderPass TKRenderPass::renderPass() const {
return m_renderPass;
}
uint32_t TKRenderPass::ColorAttachCount() const {
return m_colorAttachmentCount;
}
VkSubpassDependency TKRenderPass::_getDependencyFromJson(const Json::Value &value){
VkSubpassDependency dependency;
dependency.dependencyFlags = TKVkUtility::VkDependencyFlagBitsFromString(value["dependencyFlags"].asString());
if(value["srcSubpass"].isIntegral() == true){
dependency.srcSubpass = value["srcSubpass"].asUInt();
}
if(value["srcSubpass"].isString() == true){
if(value["srcSubpass"].asString() == "VK_SUBPASS_EXTERNAL"){
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
}
}
if(value["dstSubpass"].isIntegral()==true){
dependency.dstSubpass = value["dstSubpass"].asUInt();
}else if(value["dstSubpass"].isString()==true){
if(value["dstSubpass"].asString() == "VK_SUBPASS_EXTERNAL"){
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
}
}
dependency.srcStageMask = TKVkUtility::VkPipelineStageFlagBitFrom(value["srcStageMask"].asString());
dependency.dstStageMask = TKVkUtility::VkPipelineStageFlagBitFrom(value["dstStageMask"].asString());
if(value["srcAccessMask"].isArray()==true){
uint32_t accessMask = TKVkUtility::VkAccessFlagBitFrom(value["srcAccessMask"][0].asString());
for(uint32_t i=1; i<value["srcAccessMask"].size(); ++i){
accessMask |= TKVkUtility::VkAccessFlagBitFrom(value["srcAccessMask"][i].asString());
}
dependency.srcAccessMask = accessMask;
}
if(value["dstAccessMask"].isArray()==true){
uint32_t accessMask = TKVkUtility::VkAccessFlagBitFrom(value["dstAccessMask"][0].asString());;
for(uint32_t i=1; i<value["dstAccessMask"].size(); ++i){
accessMask |= TKVkUtility::VkAccessFlagBitFrom(value["dstAccessMask"][i].asString());
}
dependency.dstAccessMask = accessMask;
}
return dependency;
}
VkAttachmentReference TKRenderPass::_getAttachmentRefFromJson(const Json::Value &value){
VkAttachmentReference attachRef;
attachRef.attachment = value["attachment"].asUInt();
attachRef.layout = TKVkUtility::VkImageLayoutFromString(value["layout"].asString());
return attachRef;
}
VkSubpassDescription TKRenderPass::_getSubpassDescFromJson(const Json::Value &value, uint32_t idx){
std::string idxStr = std::to_string(idx);
VkSubpassDescription subpassDesc;
subpassDesc.pipelineBindPoint = TKVkUtility::VkPipelineBindPointFromString(value["pipelineBindPoint"].asString());
std::vector<VkAttachmentReference> inputRefArr;
if(value["inputAttachments"].isArray()==true){
for(uint32_t i=0; i<value["inputAttachments"].size(); ++i){
inputRefArr.push_back(this->_getAttachmentRefFromJson(value["inputAttachments"][i]));
}
}
m_allAttachmentRefInfo["input"+idxStr] = inputRefArr;
std::vector<VkAttachmentReference> colorRefArr;
if(value["colorAttachments"].isArray()==true){
for(uint32_t i=0; i<value["colorAttachments"].size(); ++i){
inputRefArr.push_back(this->_getAttachmentRefFromJson(value["colorAttachments"][i]));
}
}
m_allAttachmentRefInfo["color"+idxStr] = colorRefArr;
std::vector<VkAttachmentReference> depthRefArr;
if(value["depthAttachments"].isArray()==true){
for(uint32_t i=0; i<value["depthAttachments"].size(); ++i){
inputRefArr.push_back(this->_getAttachmentRefFromJson(value["depthAttachments"][i]));
}
}
m_allAttachmentRefInfo["depth"+idxStr] = depthRefArr;
std::vector<VkAttachmentReference> resolveRefArr;
if(value["resolveAttachments"].isArray()==true){
for(uint32_t i=0; i<value["resolveAttachments"].size(); ++i){
inputRefArr.push_back(this->_getAttachmentRefFromJson(value["resolveAttachments"][i]));
}
}
m_allAttachmentRefInfo["resolve"+idxStr] = resolveRefArr;
std::vector<uint32_t> preserveAttachments;
if(value["preserveAttachments"].isArray()==true){
for(uint32_t i=0; i<value["preserveAttachments"].size(); ++i){
preserveAttachments.push_back(value["preserveAttachments"][i].asUInt());
}
}
m_IntAttachInfo["preserve"+idxStr] = preserveAttachments;
subpassDesc.colorAttachmentCount = m_allAttachmentRefInfo["color"+idxStr].size();
subpassDesc.pColorAttachments = m_allAttachmentRefInfo["color"+idxStr].data();
subpassDesc.inputAttachmentCount = m_allAttachmentRefInfo["input"+idxStr].size();
subpassDesc.pInputAttachments = m_allAttachmentRefInfo["input"+idxStr].data();
subpassDesc.pResolveAttachments = m_allAttachmentRefInfo["resolve"+idxStr].data();
subpassDesc.pDepthStencilAttachment = m_allAttachmentRefInfo["depth"+idxStr].data();
subpassDesc.preserveAttachmentCount = m_IntAttachInfo["preserve"+idxStr].size();
subpassDesc.pPreserveAttachments = m_IntAttachInfo["preserve"+idxStr].data();
subpassDesc.flags = 0;
return subpassDesc;
}
VkAttachmentDescription TKRenderPass::_getAttachmentDescription(const Json::Value &value){
VkAttachmentDescription attachDesc;
attachDesc.format = TKVkUtility::VkFormatFrom(value["format"].asString());
attachDesc.loadOp = TKVkUtility::VkAttachmentLoadOpFromString(value["loadOp"].asString());
attachDesc.storeOp = TKVkUtility::VkAttachmentStoreOpFromString(value["storeOp"].asString());
attachDesc.stencilLoadOp = TKVkUtility::VkAttachmentLoadOpFromString(value["stencilLoadOp"].asString());
attachDesc.stencilStoreOp = TKVkUtility::VkAttachmentStoreOpFromString(value["stencilStoreOp"].asString());
attachDesc.initialLayout = TKVkUtility::VkImageLayoutFromString(value["initialLayout"].asString());
attachDesc.finalLayout = TKVkUtility::VkImageLayoutFromString(value["finalLayout"].asString());
attachDesc.samples = TKVkUtility::VkSampleCountFlagBitFrom(value["samples"].asString());
attachDesc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
return attachDesc;
}