From bb3d3f48ef9fdcf026fa5491971631173c4cbf4e Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 13 Jun 2017 13:59:41 -0700 Subject: layers: Fix SC interface matching over complex types --- layers/shader_validation.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'layers/shader_validation.cpp') diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp index b95c55e1..27190564 100644 --- a/layers/shader_validation.cpp +++ b/layers/shader_validation.cpp @@ -455,18 +455,19 @@ static spirv_inst_iter get_struct_type(shader_module const *src, spirv_inst_iter } } -static void collect_interface_block_members(shader_module const *src, std::map *out, +static bool collect_interface_block_members(shader_module const *src, std::map *out, std::unordered_map const &blocks, bool is_array_of_verts, - uint32_t id, uint32_t type_id, bool is_patch) { + uint32_t id, uint32_t type_id, bool is_patch, int /*first_location*/) { // Walk down the type_id presented, trying to determine whether it's actually an interface block. auto type = get_struct_type(src, src->get_def(type_id), is_array_of_verts && !is_patch); if (type == src->end() || blocks.find(type.word(1)) == blocks.end()) { // This isn't an interface block. - return; + return false; } std::unordered_map member_components; std::unordered_map member_relaxed_precision; + std::unordered_map member_patch; // Walk all the OpMemberDecorate for type's result id -- first pass, collect components. for (auto insn : *src) { @@ -481,9 +482,15 @@ static void collect_interface_block_members(shader_module const *src, std::mapsecond; bool is_relaxed_precision = member_relaxed_precision.find(member_index) != member_relaxed_precision.end(); + bool member_is_patch = is_patch || member_patch.count(member_index)>0; for (unsigned int offset = 0; offset < num_locations; offset++) { interface_var v = {}; @@ -503,7 +511,7 @@ static void collect_interface_block_members(shader_module const *src, std::map collect_interface_by_location(shader_module const *src, spirv_inst_iter entrypoint, @@ -587,7 +597,8 @@ static std::map collect_interface_by_location(shader_ // this path for the interface block case, as the individual members of the type are decorated, rather than // variable declarations. - if (location != -1) { + if (builtin != -1) continue; + else if (!collect_interface_block_members(src, &out, blocks, is_array_of_verts, id, type, is_patch, location)) { // A user-defined interface variable, with a location. Where a variable occupied multiple locations, emit // one result for each. unsigned num_locations = get_locations_consumed_by_type(src, type, is_array_of_verts && !is_patch); @@ -600,9 +611,6 @@ static std::map collect_interface_by_location(shader_ v.is_relaxed_precision = is_relaxed_precision; out[std::make_pair(location + offset, component)] = v; } - } else if (builtin == -1) { - // An interface block instance - collect_interface_block_members(src, &out, blocks, is_array_of_verts, id, type, is_patch); } } } -- cgit v1.2.3