Arthur Monteiro
Arthur Monteiro

Reputation: 319

Compute shader pipeline creation crash

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 !

Upvotes: 0

Views: 1089

Answers (1)

krOoze
krOoze

Reputation: 13276

Your VkComputePipelineCreateInfo pipelineInfo; is not zeroed. Therefore pNext can be garbage. Therefore it may cause dereferencing of garbage pointer by the driver or layers.

Upvotes: 2

Related Questions