From e5c1b496841f9a5cdeaee1859806ee00030b7dd0 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 14 Aug 2015 12:04:59 +1200 Subject: [PATCH] layers: Require pipeline layout to contain all referenced descriptors If the SPIRV image uses a descriptor (for constant buffer, image, etc) we must declare it in the pipeline layout. We won't complain about unused junk in the pipeline layout, but not declaring something that *is* used is an error. Signed-off-by: Chris Forbes Reviewed-by: Courtney Goeltzenleuchter --- layers/shader_checker.cpp | 46 +++++++++++++++++++++++++++++++++++++++ layers/shader_checker.h | 1 + 2 files changed, 47 insertions(+) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index 1d5b08a5..b4d1a59c 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -991,6 +991,25 @@ shader_stage_attribs[VK_SHADER_STAGE_FRAGMENT + 1] = { }; +static VkDescriptorSetLayoutBinding * +find_descriptor_binding(std::vector*>* layout, + std::pair slot) +{ + if (!layout) + return nullptr; + + if (slot.first >= layout->size()) + return nullptr; + + auto set = (*layout)[slot.first]; + + if (slot.second >= set->size()) + return nullptr; + + return &(*set)[slot.second]; +} + + static bool validate_graphics_pipeline(VkDevice dev, VkGraphicsPipelineCreateInfo const *pCreateInfo) { @@ -1016,6 +1035,33 @@ validate_graphics_pipeline(VkDevice dev, VkGraphicsPipelineCreateInfo const *pCr else { struct shader_object *shader = shader_object_map[pStage->shader.handle]; shaders[pStage->stage] = shader->module; + + /* validate descriptor set layout against what the spirv module actually uses */ + if (shader->module->is_spirv) { + std::map, interface_var> descriptor_uses; + collect_interface_by_descriptor_slot(dev, shader->module, spv::StorageClassUniform, + descriptor_uses); + + auto layout = pCreateInfo->layout.handle ? + pipeline_layout_map[pCreateInfo->layout.handle] : nullptr; + + for (auto it = descriptor_uses.begin(); it != descriptor_uses.end(); it++) { + + /* find the matching binding */ + auto binding = find_descriptor_binding(layout, it->first); + + if (binding == nullptr) { + char type_name[1024]; + describe_type(type_name, shader->module, it->second.type_id); + log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE, /*dev*/0, 0, + SHADER_CHECKER_MISSING_DESCRIPTOR, "SC", + "Shader uses descriptor slot %u.%u (used as type `%s`) but not declared in pipeline layout", + it->first.first, it->first.second, type_name); + pass = false; + } + + } + } } } } diff --git a/layers/shader_checker.h b/layers/shader_checker.h index 4e7eddf0..2c3868b4 100644 --- a/layers/shader_checker.h +++ b/layers/shader_checker.h @@ -37,4 +37,5 @@ typedef enum _SHADER_CHECKER_ERROR SHADER_CHECKER_INCONSISTENT_SPIRV, /* General inconsistency within a SPIR-V module */ SHADER_CHECKER_UNKNOWN_STAGE, /* Stage is not supported by analysis */ SHADER_CHECKER_INCONSISTENT_VI, /* VI state contains conflicting binding or attrib descriptions */ + SHADER_CHECKER_MISSING_DESCRIPTOR, /* Shader attempts to use a descriptor binding not declared in the layout */ } SHADER_CHECKER_ERROR; -- 2.34.1