From d2ccbedbb5b5752da5b083e446b67310be9748ce Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 1 Feb 2016 12:00:21 +1300 Subject: layers: Look up entrypoint for each shader stage Not doing anything useful with this yet beyond insisting that it is present, but that will come in later patches. V4: Add new enum to md Signed-off-by: Chris Forbes --- layers/draw_state.cpp | 35 ++++++++++++++++++++++++++++++++++- layers/draw_state.h | 1 + layers/vk_validation_layer_details.md | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index e7801bfd..81b9bb68 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -152,6 +152,8 @@ struct spirv_inst_iter { uint32_t const & word(unsigned n) { return it[n]; } uint32_t offset() { return (uint32_t)(it - zero); } + spirv_inst_iter() {} + spirv_inst_iter(std::vector::const_iterator zero, std::vector::const_iterator it) : zero(zero), it(it) {} @@ -399,6 +401,25 @@ build_def_index(shader_module *module) } } + +static spirv_inst_iter +find_entrypoint(shader_module *src, char const *name, VkShaderStageFlagBits stageBits) +{ + for (auto insn : *src) { + if (insn.opcode() == spv::OpEntryPoint) { + auto entrypointName = (char const *) &insn.word(3); + auto entrypointStageBits = 1u << insn.word(1); + + if (!strcmp(entrypointName, name) && (entrypointStageBits & stageBits)) { + return insn; + } + } + } + + return src->end(); +} + + bool shader_is_spirv(VkShaderModuleCreateInfo const *pCreateInfo) { @@ -1391,6 +1412,8 @@ validate_pipeline_shaders(layer_data *my_data, VkDevice dev, PIPELINE_NODE* pPip shader_module *shaders[5]; memset(shaders, 0, sizeof(shaders)); + spirv_inst_iter entrypoints[5]; + memset(entrypoints, 0, sizeof(entrypoints)); RENDER_PASS_NODE const *rp = 0; VkPipelineVertexInputStateCreateInfo const *vi = 0; VkBool32 pass = VK_TRUE; @@ -1409,8 +1432,18 @@ validate_pipeline_shaders(layer_data *my_data, VkDevice dev, PIPELINE_NODE* pPip else { pass = validate_specialization_offsets(my_data, pStage) && pass; + auto stage_id = get_shader_stage_id(pStage->stage); shader_module *module = my_data->shaderModuleMap[pStage->module]; - shaders[get_shader_stage_id(pStage->stage)] = module; + shaders[stage_id] = module; + + /* find the entrypoint */ + entrypoints[stage_id] = find_entrypoint(module, pStage->pName, pStage->stage); + if (entrypoints[stage_id] == module->end()) { + if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/0, __LINE__, SHADER_CHECKER_MISSING_ENTRYPOINT, "SC", + "No entrypoint found named `%s` for stages %u", pStage->pName, pStage->stage)) { + pass = VK_FALSE; + } + } /* validate descriptor set layout against what the spirv module actually uses */ std::map, interface_var> descriptor_uses; diff --git a/layers/draw_state.h b/layers/draw_state.h index 2de94ea2..a84ebd1f 100755 --- a/layers/draw_state.h +++ b/layers/draw_state.h @@ -208,6 +208,7 @@ typedef enum _SHADER_CHECKER_ERROR { 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_BAD_SPECIALIZATION, /* Specialization map entry points outside specialization data block */ + SHADER_CHECKER_MISSING_ENTRYPOINT, /* Shader module does not contain the requested entrypoint */ } SHADER_CHECKER_ERROR; typedef enum _DRAW_TYPE diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md index adbded53..4ad2abe3 100644 --- a/layers/vk_validation_layer_details.md +++ b/layers/vk_validation_layer_details.md @@ -129,6 +129,7 @@ depends on the pair of pipeline stages involved. | Shader Stage Check | Warns if shader stage is unsupported | UNKNOWN_STAGE | vkCreateGraphicsPipelines | TBD | NA | | Shader Specialization | Error if specialization entry data is not fully contained within the specialization data block. | BAD_SPECIALIZATION | vkCreateGraphicsPipelines vkCreateComputePipelines | TBD | NA | | Missing Descriptor | Flags error if shader attempts to use a descriptor binding not declared in the layout | MISSING_DESCRIPTOR | vkCreateGraphicsPipelines | CreatePipelineUniformBlockNotProvided | NA | +| Missing Entrypoint | Flags error if specified entrypoint is not present in the shader module | MISSING_ENTRYPOINT | vkCreateGraphicsPipelines | TBD | NA | | NA | Enum used for informational messages | NONE | | NA | None | ### VK_LAYER_LUNARG_ShaderChecker Pending Work -- cgit v1.2.3