diff options
author | Mark Young <marky@lunarg.com> | 2018-05-21 15:53:59 -0600 |
---|---|---|
committer | Mark Lobodzinski <mark@lunarg.com> | 2018-05-23 08:08:53 -0600 |
commit | 4e919b2b9a22b3d31f6c8f79af868494ecd2fa8e (patch) | |
tree | e683eae008f0e55a3a398b0485853e05d10f84c1 /layers | |
parent | 779dd9ccd486979ddbf9984f3acea7981492307f (diff) | |
download | vulkan-validation-layers-4e919b2b9a22b3d31f6c8f79af868494ecd2fa8e.tar.gz |
layers: Github #94-Use VkShaderModule
The shader_module validation didn't have a mechanism to correlate
messages back to the original VkShaderModule. This was necessary
to pin-point which shader had issues once it was created (typically
when a pipeline was bound).
Change-Id: Iee5a6993abc67479f3ac2343388499ec6b6ba3c1
Diffstat (limited to 'layers')
-rw-r--r-- | layers/core_validation.cpp | 3 | ||||
-rw-r--r-- | layers/shader_validation.cpp | 59 | ||||
-rw-r--r-- | layers/shader_validation.h | 8 |
3 files changed, 39 insertions, 31 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 14b8559be..2a4014f34 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -9060,7 +9060,8 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShade if (res == VK_SUCCESS) { lock_guard_t lock(global_lock); - unique_ptr<shader_module> new_shader_module(spirv_valid ? new shader_module(pCreateInfo) : new shader_module()); + unique_ptr<shader_module> new_shader_module(spirv_valid ? new shader_module(pCreateInfo, *pShaderModule) + : new shader_module()); dev_data->shaderModuleMap[*pShaderModule] = std::move(new_shader_module); } return res; diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp index 9949a3608..e926578f8 100644 --- a/layers/shader_validation.cpp +++ b/layers/shader_validation.cpp @@ -778,17 +778,18 @@ static bool validate_vi_against_vs_inputs(debug_report_data const *report_data, auto a_first = a_at_end ? 0 : it_a->first; auto b_first = b_at_end ? 0 : it_b->first.first; if (!a_at_end && (b_at_end || a_first < b_first)) { - if (!used && log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, - "Vertex attribute at location %d not consumed by vertex shader", a_first)) { + if (!used && + log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(vs->vk_shader_module), SHADER_CHECKER_OUTPUT_NOT_CONSUMED, + "Vertex attribute at location %d not consumed by vertex shader", a_first)) { skip = true; } used = false; it_a++; } else if (!b_at_end && (a_at_end || b_first < a_first)) { - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 0, - SHADER_CHECKER_INPUT_NOT_PRODUCED, "Vertex shader consumes input at location %d but not provided", b_first); + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(vs->vk_shader_module), SHADER_CHECKER_INPUT_NOT_PRODUCED, + "Vertex shader consumes input at location %d but not provided", b_first); it_b++; } else { unsigned attrib_type = get_format_type(it_a->second->format); @@ -796,8 +797,8 @@ static bool validate_vi_against_vs_inputs(debug_report_data const *report_data, // Type checking if (!(attrib_type & input_type)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(vs->vk_shader_module), SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "Attribute type of `%s` at location %d does not match vertex shader input type of `%s`", string_VkFormat(it_a->second->format), a_first, describe_type(vs, it_b->second.type_id).c_str()); } @@ -842,16 +843,17 @@ static bool validate_fs_outputs_against_render_pass(debug_report_data const *rep bool b_at_end = color_attachments.size() == 0 || it_b == color_attachments.end(); if (!a_at_end && (b_at_end || it_a->first.first < it_b->first)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_OUTPUT_NOT_CONSUMED, + skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(fs->vk_shader_module), SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "fragment shader writes to output location %d with no matching attachment", it_a->first.first); it_a++; } else if (!b_at_end && (a_at_end || it_a->first.first > it_b->first)) { // Only complain if there are unmasked channels for this attachment. If the writemask is 0, it's acceptable for the // shader to not produce a matching output. if (pipeline->attachments[it_b->first].colorWriteMask != 0) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_INPUT_NOT_PRODUCED, "Attachment %d not written by fragment shader", it_b->first); + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(fs->vk_shader_module), SHADER_CHECKER_INPUT_NOT_PRODUCED, + "Attachment %d not written by fragment shader", it_b->first); } it_b++; } else { @@ -860,8 +862,8 @@ static bool validate_fs_outputs_against_render_pass(debug_report_data const *rep // Type checking if (!(output_type & att_type)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(fs->vk_shader_module), SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "Attachment %d of type `%s` does not match fragment shader output type of `%s`", it_b->first, string_VkFormat(it_b->second), describe_type(fs, it_a->second.type_id).c_str()); } @@ -1552,14 +1554,16 @@ static bool validate_interface_between_stages(debug_report_data const *report_da auto b_first = b_at_end ? std::make_pair(0u, 0u) : b_it->first; if (b_at_end || ((!a_at_end) && (a_first < b_first))) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "%s writes to output location %u.%u which is not consumed by %s", - producer_stage->name, a_first.first, a_first.second, consumer_stage->name); + skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(producer->vk_shader_module), SHADER_CHECKER_OUTPUT_NOT_CONSUMED, + "%s writes to output location %u.%u which is not consumed by %s", producer_stage->name, a_first.first, + a_first.second, consumer_stage->name); a_it++; } else if (a_at_end || a_first > b_first) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_INPUT_NOT_PRODUCED, "%s consumes input location %u.%u which is not written by %s", - consumer_stage->name, b_first.first, b_first.second, producer_stage->name); + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(consumer->vk_shader_module), SHADER_CHECKER_INPUT_NOT_PRODUCED, + "%s consumes input location %u.%u which is not written by %s", consumer_stage->name, b_first.first, + b_first.second, producer_stage->name); b_it++; } else { // subtleties of arrayed interfaces: @@ -1569,21 +1573,22 @@ static bool validate_interface_between_stages(debug_report_data const *report_da if (!types_match(producer, consumer, a_it->second.type_id, b_it->second.type_id, producer_stage->arrayed_output && !a_it->second.is_patch && !a_it->second.is_block_member, consumer_stage->arrayed_input && !b_it->second.is_patch && !b_it->second.is_block_member, true)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "Type mismatch on location %u.%u: '%s' vs '%s'", - a_first.first, a_first.second, describe_type(producer, a_it->second.type_id).c_str(), + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(producer->vk_shader_module), SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, + "Type mismatch on location %u.%u: '%s' vs '%s'", a_first.first, a_first.second, + describe_type(producer, a_it->second.type_id).c_str(), describe_type(consumer, b_it->second.type_id).c_str()); } if (a_it->second.is_patch != b_it->second.is_patch) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 0, - SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(producer->vk_shader_module), SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "Decoration mismatch on location %u.%u: is per-%s in %s stage but per-%s in %s stage", a_first.first, a_first.second, a_it->second.is_patch ? "patch" : "vertex", producer_stage->name, b_it->second.is_patch ? "patch" : "vertex", consumer_stage->name); } if (a_it->second.is_relaxed_precision != b_it->second.is_relaxed_precision) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 0, - SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, + HandleToUint64(producer->vk_shader_module), SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "Decoration mismatch on location %u.%u: %s and %s stages differ in precision", a_first.first, a_first.second, producer_stage->name, consumer_stage->name); } diff --git a/layers/shader_validation.h b/layers/shader_validation.h index 10d97655a..8fe5aba83 100644 --- a/layers/shader_validation.h +++ b/layers/shader_validation.h @@ -74,15 +74,17 @@ struct shader_module { // trees, constant expressions, etc requires jumping all over the instruction stream. std::unordered_map<unsigned, unsigned> def_index; bool has_valid_spirv; + VkShaderModule vk_shader_module; - shader_module(VkShaderModuleCreateInfo const *pCreateInfo) + shader_module(VkShaderModuleCreateInfo const *pCreateInfo, VkShaderModule shaderModule) : words((uint32_t *)pCreateInfo->pCode, (uint32_t *)pCreateInfo->pCode + pCreateInfo->codeSize / sizeof(uint32_t)), def_index(), - has_valid_spirv(true) { + has_valid_spirv(true), + vk_shader_module(shaderModule) { build_def_index(); } - shader_module() : has_valid_spirv(false) {} + shader_module() : has_valid_spirv(false), vk_shader_module(VK_NULL_HANDLE) {} // Expose begin() / end() to enable range-based for spirv_inst_iter begin() const { return spirv_inst_iter(words.begin(), words.begin() + 5); } // First insn |