diff options
| author | Chris Forbes <chrisforbes@google.com> | 2016-04-05 17:51:35 +1200 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-04-06 08:51:02 -0600 |
| commit | e927ae89168f927e12861f550677cf386d860642 (patch) | |
| tree | fdd2232e315864e9c778f8329bf2d1d2c7ba8a77 /layers/core_validation.cpp | |
| parent | 718f8ba2c42cbb0f470a4728abc78ef66a6115b0 (diff) | |
| download | usermoji-e927ae89168f927e12861f550677cf386d860642.tar.xz | |
layers: Implement relaxed vec-vec and vec-scalar matching rules
- Track whether we've seen anything disqualifying -- non-stripped
arrays, matrices, structures, etc.
- Add relaxed vec/scalar and vec/vec matches if not disqualified.
Signed-off-by: Chris Forbes <chrisforbes@google.com>
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 0058069d..0c8d07d2 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -1245,7 +1245,15 @@ static std::string describe_type(shader_module const *src, unsigned type) { } -static bool types_match(shader_module const *a, shader_module const *b, unsigned a_type, unsigned b_type, bool a_arrayed, bool b_arrayed) { +static bool is_narrow_numeric_type(spirv_inst_iter type) +{ + if (type.opcode() != spv::OpTypeInt && type.opcode() != spv::OpTypeFloat) + return false; + return type.word(2) < 64; +} + + +static bool types_match(shader_module const *a, shader_module const *b, unsigned a_type, unsigned b_type, bool a_arrayed, bool b_arrayed, bool relaxed) { /* walk two type trees together, and complain about differences */ auto a_insn = a->get_def(a_type); auto b_insn = b->get_def(b_type); @@ -1253,12 +1261,16 @@ static bool types_match(shader_module const *a, shader_module const *b, unsigned assert(b_insn != b->end()); if (a_arrayed && a_insn.opcode() == spv::OpTypeArray) { - return types_match(a, b, a_insn.word(2), b_type, false, b_arrayed); + return types_match(a, b, a_insn.word(2), b_type, false, b_arrayed, relaxed); } if (b_arrayed && b_insn.opcode() == spv::OpTypeArray) { /* we probably just found the extra level of arrayness in b_type: compare the type inside it to a_type */ - return types_match(a, b, a_type, b_insn.word(2), a_arrayed, false); + return types_match(a, b, a_type, b_insn.word(2), a_arrayed, false, relaxed); + } + + if (a_insn.opcode() == spv::OpTypeVector && relaxed && is_narrow_numeric_type(b_insn)) { + return types_match(a, b, a_insn.word(2), b_type, a_arrayed, b_arrayed, false); } if (a_insn.opcode() != b_insn.opcode()) { @@ -1267,7 +1279,7 @@ static bool types_match(shader_module const *a, shader_module const *b, unsigned if (a_insn.opcode() == spv::OpTypePointer) { /* match on pointee type. storage class is expected to differ */ - return types_match(a, b, a_insn.word(3), b_insn.word(3), a_arrayed, b_arrayed); + return types_match(a, b, a_insn.word(3), b_insn.word(3), a_arrayed, b_arrayed, relaxed); } if (a_arrayed || b_arrayed) { @@ -1285,14 +1297,23 @@ static bool types_match(shader_module const *a, shader_module const *b, unsigned /* match on width */ return a_insn.word(2) == b_insn.word(2); case spv::OpTypeVector: + /* match on element type, count. */ + if (!types_match(a, b, a_insn.word(2), b_insn.word(2), a_arrayed, b_arrayed, false)) + return false; + if (relaxed && is_narrow_numeric_type(a->get_def(a_insn.word(2)))) { + return a_insn.word(3) >= b_insn.word(3); + } + else { + return a_insn.word(3) == b_insn.word(3); + } case spv::OpTypeMatrix: - /* match on element type, count. these all have the same layout. */ - return types_match(a, b, a_insn.word(2), b_insn.word(2), a_arrayed, b_arrayed) && a_insn.word(3) == b_insn.word(3); + /* match on element type, count. */ + return types_match(a, b, a_insn.word(2), b_insn.word(2), a_arrayed, b_arrayed, false) && a_insn.word(3) == b_insn.word(3); case spv::OpTypeArray: /* match on element type, count. these all have the same layout. we don't get here if * b_arrayed. This differs from vector & matrix types in that the array size is the id of a constant instruction, * not a literal within OpTypeArray */ - return types_match(a, b, a_insn.word(2), b_insn.word(2), a_arrayed, b_arrayed) && + return types_match(a, b, a_insn.word(2), b_insn.word(2), a_arrayed, b_arrayed, false) && get_constant_value(a, a_insn.word(3)) == get_constant_value(b, b_insn.word(3)); case spv::OpTypeStruct: /* match on all element types */ @@ -1302,7 +1323,7 @@ static bool types_match(shader_module const *a, shader_module const *b, unsigned } for (unsigned i = 2; i < a_insn.len(); i++) { - if (!types_match(a, b, a_insn.word(i), b_insn.word(i), a_arrayed, b_arrayed)) { + if (!types_match(a, b, a_insn.word(i), b_insn.word(i), a_arrayed, b_arrayed, false)) { return false; } } @@ -1628,7 +1649,8 @@ static bool validate_interface_between_stages(layer_data *my_data, shader_module } else { if (!types_match(producer, consumer, a_it->second.type_id, b_it->second.type_id, producer_stage->arrayed_output && !a_it->second.is_patch, - consumer_stage->arrayed_input && !b_it->second.is_patch)) { + consumer_stage->arrayed_input && !b_it->second.is_patch, + true)) { if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", "Type mismatch on location %u.%u: '%s' vs '%s'", a_first.first, a_first.second, |
