I'm trying to create a pipeline for a compute shader.
The program crashes at the "vkCreateComputePipelines" line without anything in the validation layers.
Here's the code :
/* Pipeline layout */
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = descriptorSetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout(vk->getDevice(), &pipelineLayoutInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS)
throw std::runtime_error("Error : pipeline layout creation");
/* Shader */
std::vector<char> computeShaderCode = readFile(computeShader);
VkShaderModule computeShaderModule = createShaderModule(computeShaderCode, vk->getDevice());
VkPipelineShaderStageCreateInfo compShaderStageInfo = {};
compShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
compShaderStageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
compShaderStageInfo.module = computeShaderModule;
compShaderStageInfo.pName = "main";
/* Pipeline */
VkComputePipelineCreateInfo pipelineInfo;
pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pipelineInfo.stage = compShaderStageInfo;
pipelineInfo.layout = m_pipelineLayout;
if (vkCreateComputePipelines(vk->getDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_computePipeline) != VK_SUCCESS)
throw std::runtime_error("Error : compute pipeline creation");
The description set layout is created here :
VkDescriptorSetLayoutBinding inputImageLayoutBinding = {};
inputImageLayoutBinding.binding = 0;
inputImageLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
inputImageLayoutBinding.descriptorCount = 1;
inputImageLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
inputImageLayoutBinding.pImmutableSamplers = nullptr;
VkDescriptorSetLayoutBinding outputImageLayoutBinding = {};
outputImageLayoutBinding.binding = 1;
outputImageLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
outputImageLayoutBinding.descriptorCount = 1;
outputImageLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
outputImageLayoutBinding.pImmutableSamplers = nullptr;
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayouts = { inputImageLayoutBinding, outputImageLayoutBinding };
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(descriptorSetLayouts.size());
layoutInfo.pBindings = descriptorSetLayouts.data();
VkDescriptorSetLayout descriptorSetLayout;
if (vkCreateDescriptorSetLayout(vk->getDevice(), &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
throw std::runtime_error("Erreur : descriptor set layout");
The compute shader code :
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout (local_size_x = 16, local_size_y = 16) in;
layout (binding = 0, rgba8) uniform readonly image2D inputImage;
layout (binding = 1, rgba8) uniform image2D resultImage;
void main()
{
float blurImpact = 1.0;
ivec2 offsets[9] = ivec2[](
ivec2(-1, 1), // top-left
ivec2(0, 1), // top-center
ivec2(1, 1), // top-right
ivec2(-1, 0), // center-left
ivec2(0, 0), // center-center
ivec2(1, 0), // center-right
ivec2(-1, -1), // bottom-left
ivec2(0, -1), // bottom-center
ivec2(0, -1) // bottom-right
);
float kernel[9] = float[](
blurImpact, 2.0 * blurImpact, blurImpact,
2.0 * blurImpact, 4.0, 2.0 * blurImpact,
blurImpact, 2.0 * blurImpact, blurImpact
);
float sum = 12.0 * blurImpact + 4.0;
vec3 resultColor = vec3(0.0);
for(int i = 0; i < 9; ++i)
{
resultColor += imageLoad(inputImage, ivec2(gl_GlobalInvocationID.x + offsets[i].x, gl_GlobalInvocationID.y + offsets[i].y)).rgb * (kernel[i] / sum);
}
imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(resultColor, 1.0));
}
I've tried to add a pipeline cache but that doesn't fix the problem. From the specification (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCreateComputePipelines.html), I think this parameter is optionnal.
Thanks !
vkCreateComputePipelinesreturns either success or one of three error codes that indicate an out of memory situation or an invalid shader handle. You could log the return result code or add it to your exception message. I'm not sure if the Vulkan API has agetLastErrorfunction that could give you more info, however, the documentation mentions that the Vulkan API does not capture error information about API misuse (e.g. wrong parameters).m_computePipelineset up? Is it properly initialized?vkCreateComputePipelinespopulates that array, but it does not initialize it. You need to initialize it beforehand and it has to have the right size. From the documentation: "pPipelines must be a valid pointer to an array of createInfoCount VkPipeline handles".