Skip to content

RT SPIR-V has wrong error with multiple pipelines built at once #13048

Description

@spencer-lunarg

AI generated error, test fails though, so error seems real

In PreCallValidateCreateRayTracingPipelinesKHR:

  for (uint32_t i = 0; i < count; i++) {
      ...
      uint32_t stateless_data_i = 0;                    // <-- reset for every pipeline
      for (uint32_t stage = 0; stage < pCreateInfos[i].stageCount; stage++) {
          if (const auto shader_ci = FindStructInPNextChain<VkShaderModuleCreateInfo>(...)) {
              skip |= stateless_spirv_validator.Validate(
                  *chassis_state.stateless_data[stateless_data_i].pipeline_pnext_module, ...);
              ++stateless_data_i;

So pipeline 1's entries start where pipeline 0's ended, but the index restarts at 0.

With two create infos that both inline SPIR-V:

  • i=0 validates stateless_data[0] ✅
  • i=1 validates stateless_data[0] again, now labelled pCreateInfos[1]

This is the gap the code already documents at

▎ // TODO - #10029
▎ // This works for Compute because there is a single shader, but stateless_data will need to be indexed into

Compute genuinely is safe (one shader, and it guards on i == 0). Ray tracing is the case that TODO was worried about.

(feel free to add a way to vkt::rt to write the following test)

TEST_F(NegativeRayTracingPipeline, AtomicsSecondCreateInfo) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::rayTracingPipeline);
    AddRequiredFeature(vkt::Feature::maintenance5);
    AddRequiredFeature(vkt::Feature::shaderInt64);
    AddRequiredFeature(vkt::Feature::shaderSharedInt64Atomics);
    RETURN_IF_SKIP(InitFrameworkForRayTracingTest());
    RETURN_IF_SKIP(InitState());

    const char* bad_closest_hit_shader = R"glsl(
        #version 460
        #extension GL_EXT_ray_tracing : require
        #extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
        #extension GL_EXT_shader_atomic_int64 : enable
        #extension GL_KHR_memory_scope_semantics : enable
        layout(set = 0, binding = 0) buffer ssbo { uint64_t y; };
        void main() {
           atomicAdd(y, 1);
        }
    )glsl";

    const char* good_closest_hit_shader = R"glsl(
        #version 460
        #extension GL_EXT_ray_tracing : require
        layout(set = 0, binding = 0) buffer ssbo { uint y; };
        void main() {
           y = 0;
        }
    )glsl";

    std::vector<uint32_t> good_shader;
    GLSLtoSPV(m_device->Physical().limits_, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, good_closest_hit_shader, good_shader,
              SPV_ENV_VULKAN_1_2);
    std::vector<uint32_t> bad_shader;
    GLSLtoSPV(m_device->Physical().limits_, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, bad_closest_hit_shader, bad_shader,
              SPV_ENV_VULKAN_1_2);

    VkShaderModuleCreateInfo good_module_ci = vku::InitStructHelper();
    good_module_ci.pCode = good_shader.data();
    good_module_ci.codeSize = good_shader.size() * sizeof(uint32_t);
    VkShaderModuleCreateInfo bad_module_ci = vku::InitStructHelper();
    bad_module_ci.pCode = bad_shader.data();
    bad_module_ci.codeSize = bad_shader.size() * sizeof(uint32_t);

    VkShaderObj miss_shader(*m_device, kMissGlsl, VK_SHADER_STAGE_MISS_BIT_KHR, SPV_ENV_VULKAN_1_2);

    std::array<VkPipelineShaderStageCreateInfo, 2> good_stages;
    good_stages[0] = vku::InitStructHelper();
    good_stages[0].stage = VK_SHADER_STAGE_MISS_BIT_KHR;
    good_stages[0].module = miss_shader;
    good_stages[0].pName = "main";
    good_stages[1] = vku::InitStructHelper(&good_module_ci);
    good_stages[1].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
    good_stages[1].module = VK_NULL_HANDLE;
    good_stages[1].pName = "main";

    std::array<VkPipelineShaderStageCreateInfo, 2> bad_stages = good_stages;
    bad_stages[1] = vku::InitStructHelper(&bad_module_ci);
    bad_stages[1].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
    bad_stages[1].module = VK_NULL_HANDLE;
    bad_stages[1].pName = "main";

    VkRayTracingShaderGroupCreateInfoKHR group_ci = vku::InitStructHelper();
    group_ci.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
    group_ci.generalShader = VK_SHADER_UNUSED_KHR;
    group_ci.closestHitShader = 1;
    group_ci.anyHitShader = VK_SHADER_UNUSED_KHR;
    group_ci.intersectionShader = VK_SHADER_UNUSED_KHR;

    VkRayTracingPipelineInterfaceCreateInfoKHR interface_ci = vku::InitStructHelper();
    interface_ci.maxPipelineRayHitAttributeSize = 4;
    interface_ci.maxPipelineRayPayloadSize = 4;

    const vkt::DescriptorSetLayout ds_layout(*m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}});
    const vkt::PipelineLayout pipeline_layout(*m_device, {&ds_layout});

    std::array<VkRayTracingPipelineCreateInfoKHR, 2> pipeline_cis;
    pipeline_cis[0] = vku::InitStructHelper();
    pipeline_cis[0].flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
    pipeline_cis[0].stageCount = size32(good_stages);
    pipeline_cis[0].pStages = good_stages.data();
    pipeline_cis[0].groupCount = 1;
    pipeline_cis[0].pGroups = &group_ci;
    pipeline_cis[0].layout = pipeline_layout;
    pipeline_cis[0].pLibraryInterface = &interface_ci;
    pipeline_cis[1] = pipeline_cis[0];
    pipeline_cis[1].pStages = bad_stages.data();

    std::array<VkPipeline, 2> pipelines = {{VK_NULL_HANDLE, VK_NULL_HANDLE}};
    m_errorMonitor->SetDesiredErrorRegex("VUID-RuntimeSpirv-None-06278", "pCreateInfos\\[1\\]");
    vk::CreateRayTracingPipelinesKHR(*m_device, VK_NULL_HANDLE, VK_NULL_HANDLE, size32(pipeline_cis), pipeline_cis.data(), nullptr,
                                     pipelines.data());
    m_errorMonitor->VerifyFound();

    for (VkPipeline pipeline : pipelines) {
        if (pipeline != VK_NULL_HANDLE) {
            vk::DestroyPipeline(*m_device, pipeline, nullptr);
        }
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BugSomething isn't workingRTRay Tracing

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions