Access Violation Reading Location in vkCreateGraphicsPipelines

VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {};
	colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;

	VkPipelineColorBlendStateCreateInfo colorBlendStates = {};
	colorBlendStates.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
	colorBlendStates.attachmentCount = 1;
	colorBlendStates.pAttachments = &colorBlendAttachmentState;

	VkVertexInputBindingDescription vertexInputBindingDesc = {};
	vertexInputBindingDesc.binding = 0;
	vertexInputBindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
	vertexInputBindingDesc.stride = sizeof(float) * 6;

	VkVertexInputAttributeDescription vertexInputAttribDescs[2] = {};
	vertexInputAttribDescs[0].binding = 0;
	vertexInputAttribDescs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
	vertexInputAttribDescs[0].location = 0;
	vertexInputAttribDescs[0].offset = 0;

	vertexInputAttribDescs[1].binding = 0;
	vertexInputAttribDescs[1].format = VK_FORMAT_R32G32B32_SFLOAT;
	vertexInputAttribDescs[1].location = 1;
	vertexInputAttribDescs[1].offset = sizeof(float) * 3;

	VkPipelineVertexInputStateCreateInfo vertexInputState = {};
	vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
	vertexInputState.vertexBindingDescriptionCount = 1;
	vertexInputState.pVertexBindingDescriptions = &vertexInputBindingDesc;
	vertexInputState.vertexAttributeDescriptionCount = 2;
	vertexInputState.pVertexAttributeDescriptions = vertexInputAttribDescs;

	VkPipelineViewportStateCreateInfo viewportState = {};
	viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
	viewportState.viewportCount = 1;
	viewportState.scissorCount = 1;

	VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {};
	inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
	inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

	VkPipelineRasterizationStateCreateInfo rasterizerState = {};
	rasterizerState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
	rasterizerState.cullMode = VK_CULL_MODE_NONE;
	rasterizerState.polygonMode = VK_POLYGON_MODE_FILL;
	rasterizerState.lineWidth = 1.0f;
	rasterizerState.frontFace = VK_FRONT_FACE_CLOCKWISE;

	VkPipelineMultisampleStateCreateInfo multisampleState = {};
	multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
	multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_8_BIT;

	VkDynamicState dynamicState[2] = { VK_DYNAMIC_STATE_VIEWPORT,VK_DYNAMIC_STATE_SCISSOR };

	VkPipelineDynamicStateCreateInfo dynamicPipelineState = {};
	dynamicPipelineState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
	dynamicPipelineState.dynamicStateCount = 2;
	dynamicPipelineState.pDynamicStates = dynamicState;
	
	VkShaderModule shaders[2];

	std::ifstream inputFile("Shaders/color.vert.spv");
	inputFile.seekg(0, std::ios_base::end);
	uint64 fileSize = inputFile.tellg();
	inputFile.seekg(0, std::ios_base::beg);

	std::vector<char> byteCode(fileSize);
	inputFile.read(byteCode.data(), fileSize);
	inputFile.close();

	VkShaderModuleCreateInfo shaderModuleCreateInfo = {};
	shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
	shaderModuleCreateInfo.codeSize = fileSize;
	shaderModuleCreateInfo.pCode = (uint*)byteCode.data();

	CHECK_VK_RESULT_2(vkCreateShaderModule(mpDeviceContext->GetVkDevice(), &shaderModuleCreateInfo, nullptr, &shaders[0]));

	inputFile.open("Shaders/color.frag.spv");
	inputFile.seekg(0, std::ios_base::end);
	fileSize = inputFile.tellg();
	inputFile.seekg(0, std::ios_base::beg);

	byteCode.resize(fileSize);
	inputFile.read(byteCode.data(), fileSize);
	inputFile.close();

	shaderModuleCreateInfo.codeSize = fileSize;
	shaderModuleCreateInfo.pCode = (uint*)byteCode.data();

	CHECK_VK_RESULT_2(vkCreateShaderModule(mpDeviceContext->GetVkDevice(), &shaderModuleCreateInfo, nullptr, &shaders[1]));

	VkPipelineShaderStageCreateInfo shaderStages[2];
	shaderStages[0] = {};
	shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
	shaderStages[0].module = shaders[0];
	shaderStages[0].pName = "main";
	shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;

	shaderStages[1] = {};
	shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
	shaderStages[1].module = shaders[1];
	shaderStages[1].pName = "main";
	shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;

	VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo[1];
	graphicsPipelineCreateInfo[0] = {};
	graphicsPipelineCreateInfo[0].layout = mPipelineLayout;
	graphicsPipelineCreateInfo[0].pColorBlendState = &colorBlendStates;
	graphicsPipelineCreateInfo[0].stageCount = 2;
	graphicsPipelineCreateInfo[0].pStages = shaderStages;
	graphicsPipelineCreateInfo[0].pDynamicState = &dynamicPipelineState;
	graphicsPipelineCreateInfo[0].pInputAssemblyState = &inputAssemblyState;
	graphicsPipelineCreateInfo[0].pRasterizationState = &rasterizerState;
	graphicsPipelineCreateInfo[0].pVertexInputState = &vertexInputState;
	graphicsPipelineCreateInfo[0].pMultisampleState = &multisampleState;
	graphicsPipelineCreateInfo[0].renderPass = mRenderPass;
	graphicsPipelineCreateInfo[0].pViewportState = &viewportState;
	graphicsPipelineCreateInfo[0].subpass = 0;

	CHECK_VK_RESULT_2(vkCreateGraphicsPipelines(mpDeviceContext->GetVkDevice(), VK_NULL_HANDLE,1, graphicsPipelineCreateInfo, nullptr, &mPipeline));

No validation. I’ve spent 3 hours to find where problem is but no success.

Dunno if that could cause a crash, but I don’t see any code initializing the sType for your graphicsPipleineCreateInfo to VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO.

Also check if all involved pointers actually point to something, e.g. GetVkDevice.

The result is still same. BTW GetDevice return VkDevice. This first time it failed to create pipeline after several practice with Vulkan.

I’ve been encountering more or less the same problem all day, on code which was working.

In my case, I’ve narrowed it down to saving the VkShaderModule produced by vkCreateShaderModule.

My original code was recompiling the shaders many times, so I created a shader pool. The idea being compile each shader once and then pool the VkShaderModule for building the pipeline.

The value of each VkShaderModule looks like it’s valid etc.

I tried to validate the pointer using the recommended GetDevice method, but couldn’t find a function with a similar name or one that seemed applicable.

It appears that the shader module pointer went stale, as in it was deleted by someone else.

No, I have not called the destroy function. It’s only called from one location and that break point isn’t hit.

Thanks,
Bob

oops, ‘pull the’, not ‘pool the’. As in pull the module from the pool.

Still haven’t found a solution.

I added my own allocation call backs and the memory is not being deleted between the call to vkCreateShaderModule and the point where it’s used in vkCreateGraphicsPipeline.

Further, the first call to vkCreateGraphicsPipeline (from init) works. It’s the second call (in recreateSwapChain) that has the NPE/segfault. I’m developing on Win10, we don’t actually have segfaults.

This is not blocking, but it’s very confusing. One of the precepts of Vulkan is being able to build your own pipeline to improve performance. If shader modules can’t be cached and shared, that seem contrary to the intent.

I’m sure there’s an error somewhere, probably one my part.

BT

The forum has blocked me from posting this in the primary thread. (Admin note: fixed)

The crash resulted from setting VkPipelineShaderStageCreateInfo.pName incorrectly.

It must be a valid entry point into the shader. If not an NPR exception occurs on windows. I assume a segfault would occur on Linux.

The spec is quite clear on what’s required. IMO the field should be rename pEntryPointName or something more informative.

One thing that would helped would be placing the struct name in front of the invalid field name when the validator posts a message.

There was another error where I had to do a treasure hunt of the entire structure to find a field matching the message name.

Problem resolved. First cut at VulkanQuickStart is now on github.

Many thanks to all.