Erros in create a pipeline and renderpass from a json file

#1

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;
}
#2

I have post my code at this git.

#3

-> VK_PIPELINE_BIND_POINT_GRAPHICS

Also you did not say what “problems”. Use Validation Layers; they will probably tell you exactly what the errors are.

BTW: your post is broken.

#4

sorry, I forgot.
enabled layers:
VK_LAYER_LUNARG_core_validation
VK_LAYER_LUNARG_standard_validation

enabled extensions:
VK_KHR_surface
VK_KHR_xcb_surface

but there was no error remind when I debug the program, only a crash with lldb
the crash info :

  • thread #1, name = ‘light’, stop reason = signal SIGSEGV: invalid address (fault address: 0x10)
    • frame #0: 0x00007ffff766a155 libc.so.6__memmove_avx_unaligned_erms at memmove-vec-unaligned-erms.S:345 frame #1: 0x00007fffedf74c4b libVkLayer_core_validation.sosafe_VkGraphicsPipelineCreateInfo::initialize(VkGraphicsPipelineCreateInfo const*, bool, bool) + 523
      frame #2: 0x00007fffedfb9921 libVkLayer_core_validation.socore_validation::PreCallValidateCreateGraphicsPipelines(VkDevice_T*, VkPipelineCache_T*, unsigned int, VkGraphicsPipelineCreateInfo const*, VkAllocationCallbacks const*, VkPipeline_T**, create_graphics_pipeline_api_state*) + 1745 frame #3: 0x00007fffedf51abc libVkLayer_core_validation.socore_validation::CreateGraphicsPipelines(VkDevice_T*, VkPipelineCache_T*, unsigned int, VkGraphicsPipelineCreateInfo const*, VkAllocationCallbacks const*, VkPipeline_T**) + 140

I have no idea now.
I have to check step by step now.
Can you give me some ideas? thanks.
I am a Chinese, my English is not quite well.

#5

VK_LAYER_LUNARG_standard_validation implies VK_LAYER_LUNARG_core_validation. Do not enable both.

Does not contain reporting extension. Are you enabling the layers via env?

Possibly some NULL pointer to struct. Just check the arguments to vkCreateGraphicsPipelines in your debuger.

Your post is broken again. Do it like this:
```
code
```

results in:

code