2525#include < vulkan/vk_enum_string_helper.h>
2626#include < vulkan/utility/vk_format_utils.h>
2727#include < vulkan/vulkan_core.h>
28+ #include " containers/custom_containers.h"
2829#include " core_checks/cc_state_tracker.h"
2930#include " error_message/logging.h"
3031#include " state_tracker/last_bound_state.h"
32+ #include " utils/assert_utils.h"
3133#include " utils/math_utils.h"
3234#include " utils/vk_struct_compare.h"
3335#include " core_validation.h"
@@ -3403,7 +3405,7 @@ bool CoreChecks::ValidateDrawPipeline(const LastBound &last_bound_state, const v
34033405 }
34043406
34053407 skip |= ValidateDrawPipelineFramebuffer (cb_state, pipeline, vuid);
3406- skip |= ValidateDrawPipelineVertexBinding (cb_state, pipeline, vuid);
3408+ skip |= ValidateDrawPipelineVertexBinding (cb_state, last_bound_state, pipeline, vuid);
34073409 skip |= ValidateDrawPipelineFragmentDensityMapLayered (cb_state, pipeline, *rp_state, vuid);
34083410 skip |= ValidateDrawPipelineRasterizationState (last_bound_state, pipeline, vuid);
34093411
@@ -4213,10 +4215,18 @@ bool CoreChecks::ValidateDrawPipelineFragmentDensityMapLayered(const vvl::Comman
42134215 return skip;
42144216}
42154217
4216- bool CoreChecks::ValidateDrawPipelineVertexBinding (const vvl::CommandBuffer &cb_state, const vvl::Pipeline &pipeline ,
4217- const vvl::DrawDispatchVuid &vuid) const {
4218+ bool CoreChecks::ValidateDrawPipelineVertexBinding (const vvl::CommandBuffer &cb_state, const LastBound &last_bound ,
4219+ const vvl::Pipeline &pipeline, const vvl:: DrawDispatchVuid &vuid) const {
42184220 bool skip = false ;
4219- if (!pipeline.vertex_input_state ) return skip;
4221+ // TODO - Seems even if using mesh shaders, the vertex_input_state is non-null (but emmpty)
4222+ if (!pipeline.vertex_input_state || ((pipeline.active_shaders & VK_SHADER_STAGE_VERTEX_BIT) == 0 )) {
4223+ return skip;
4224+ }
4225+ // Since we need to know if the Vertex shader actually declares/uses the Input Location, if the shader validation was disabled,
4226+ // there will no SPIR-V to reflect the information from.
4227+ if (disabled[shader_validation]) {
4228+ return skip;
4229+ }
42204230
42214231 const bool has_dynamic_descriptions = pipeline.IsDynamic (CB_DYNAMIC_STATE_VERTEX_INPUT_EXT);
42224232 const auto &vertex_bindings =
@@ -4230,14 +4240,41 @@ bool CoreChecks::ValidateDrawPipelineVertexBinding(const vvl::CommandBuffer &cb_
42304240 ss << " the last bound pipeline" ;
42314241 }
42324242 ss << " has pVertexBindingDescriptions[" << binding_description.index << " ].binding (" << binding_description.desc .binding
4233- << " )" ;
4243+ << " ) (pointing to Locations [" ;
4244+ const char *separator = " " ;
4245+ for (const auto &location : binding_description.locations ) {
4246+ ss << separator << location.first ;
4247+ separator = " , " ;
4248+ }
4249+ ss << " ])" ;
42344250 return ss.str ();
42354251 };
42364252
4253+ const spirv::EntryPoint *vertex_entry_point = last_bound.GetVertexEntryPoint ();
4254+ ASSERT_AND_RETURN_SKIP (vertex_entry_point);
4255+ vvl::unordered_set<uint32_t > spirv_input_locations;
4256+ for (const auto &pair : vertex_entry_point->input_interface_slots ) {
4257+ spirv_input_locations.emplace (pair.first .Location ());
4258+ }
4259+
42374260 // It is ok to have binding descriptions not used, them and find if there is matching buffer tied to it or not
42384261 for (const auto &[binding_index, binding_description] : vertex_bindings) {
42394262 // If no attribute points to a binding, it is unused
4240- if (binding_description.locations .empty ()) continue ;
4263+ if (binding_description.locations .empty ()) {
4264+ continue ;
4265+ }
4266+
4267+ bool shader_has_location = false ;
4268+ for (const auto &location : binding_description.locations ) {
4269+ if (spirv_input_locations.find (location.first ) != spirv_input_locations.end ()) {
4270+ shader_has_location = true ;
4271+ break ;
4272+ }
4273+ }
4274+ if (!shader_has_location) {
4275+ // If the Vertex shader doesn't declare the vertex input, there can be invalid/unbound bindings
4276+ continue ;
4277+ }
42414278
42424279 const auto *vertex_buffer_binding = vvl::Find (cb_state.current_vertex_buffer_binding_info , binding_index);
42434280 if (!vertex_buffer_binding || !vertex_buffer_binding->bound ) {
0 commit comments