计算着色器管道创建崩溃

时间:2019-09-17 17:15:13

标签: c++ vulkan

我正在尝试为计算着色器创建管道。

程序在“ vkCreateComputePipelines”行崩溃,而验证层中没有任何内容。

这是代码:

/* 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");

在这里创建描述集布局:

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");

计算着色器代码:

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

我尝试添加管道缓存,但这不能解决问题。根据规范(https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCreateComputePipelines.html),我认为该参数是可选的。

谢谢!

1 个答案:

答案 0 :(得分:2)

您的VkComputePipelineCreateInfo pipelineInfo;未清零。因此pNext可能是垃圾。因此,它可能导致驱动程序或层取消对垃圾指针的引用。