From 7b63987a4d0cb966a5f2bddb1522495ee75c59c3 Mon Sep 17 00:00:00 2001 From: Arno Date: Mon, 16 Dec 2024 19:47:26 +0100 Subject: [PATCH] gpuav: Vertex attributes OOB - Move vertex attributes OOB validation to instrumentation => faster, simpler - Handle VK_VERTEX_INPUT_RATE_INSTANCE --- BUILD.gn | 4 + layers/VkLayer_khronos_validation.json.in | 16 + layers/gpuav/core/gpuav_record.cpp | 15 +- layers/gpuav/core/gpuav_settings.h | 5 +- layers/gpuav/core/gpuav_setup.cpp | 2 + .../instrumentation/gpuav_instrumentation.cpp | 274 ++++++++- .../instrumentation/gpuav_instrumentation.h | 25 +- .../gpuav_shader_instrumentor.cpp | 6 + .../gpuav/resources/gpuav_state_trackers.cpp | 4 + layers/gpuav/resources/gpuav_state_trackers.h | 2 +- layers/gpuav/shaders/gpuav_error_codes.h | 6 + layers/gpuav/shaders/gpuav_error_header.h | 2 +- .../gpuav/shaders/gpuav_shaders_constants.h | 1 + .../vertex_attribute_fetch_oob.vert | 78 +++ layers/gpuav/spirv/CMakeLists.txt | 9 +- layers/gpuav/spirv/function_basic_block.h | 5 +- .../spirv/vertex_attribute_fetch_oob.cpp | 90 +++ .../gpuav/spirv/vertex_attribute_fetch_oob.h | 44 ++ .../gpuav_copy_buffer_to_image.cpp | 3 - layers/gpuav/validation_cmd/gpuav_draw.cpp | 566 ------------------ layers/layer_options.cpp | 6 + layers/state_tracker/pipeline_state.cpp | 15 + layers/state_tracker/pipeline_state.h | 1 + ...tation_vertex_attribute_fetch_oob_vert.cpp | 131 ++++ ...entation_vertex_attribute_fetch_oob_vert.h | 30 + .../validation_cmd_trace_rays_rgen.cpp | 316 +++++----- scripts/generate_source.py | 2 + tests/unit/gpu_av_index_buffer.cpp | 204 ++++--- tests/unit/gpu_av_index_buffer_positive.cpp | 71 +++ 29 files changed, 1106 insertions(+), 827 deletions(-) create mode 100644 layers/gpuav/shaders/instrumentation/vertex_attribute_fetch_oob.vert create mode 100644 layers/gpuav/spirv/vertex_attribute_fetch_oob.cpp create mode 100644 layers/gpuav/spirv/vertex_attribute_fetch_oob.h create mode 100644 layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp create mode 100644 layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.h diff --git a/BUILD.gn b/BUILD.gn index 2a5f193d685..9e47b1cd466 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -206,6 +206,8 @@ vvl_sources = [ "layers/gpuav/spirv/buffer_device_address_pass.h", "layers/gpuav/spirv/post_process_descriptor_indexing_pass.cpp", "layers/gpuav/spirv/post_process_descriptor_indexing_pass.h", + "layers/gpuav/spirv/vertex_attribute_fetch_oob.cpp", + "layers/gpuav/spirv/vertex_attribute_fetch_oob.h", "layers/gpuav/spirv/function_basic_block.cpp", "layers/gpuav/spirv/function_basic_block.h", "layers/gpuav/spirv/instruction.cpp", @@ -402,6 +404,8 @@ vvl_sources = [ "layers/vulkan/generated/instrumentation_ray_query_comp.h", "layers/vulkan/generated/instrumentation_post_process_descriptor_index_comp.cpp", "layers/vulkan/generated/instrumentation_post_process_descriptor_index_comp.h", + "layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp", + "layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.h", "layers/vulkan/generated/object_tracker.cpp", "layers/vulkan/generated/object_tracker_device_methods.h", "layers/vulkan/generated/object_tracker_instance_methods.h", diff --git a/layers/VkLayer_khronos_validation.json.in b/layers/VkLayer_khronos_validation.json.in index b973157c4f1..422c4647ce5 100644 --- a/layers/VkLayer_khronos_validation.json.in +++ b/layers/VkLayer_khronos_validation.json.in @@ -683,6 +683,22 @@ ] } }, + { + "key": "gpuav_vertex_attribute_fetch_oob", + "label": "Out of bounds vertex attribute fetching", + "description": "Validate that no vertex attribute fetching is out of bonds", + "type": "BOOL", + "default": true, + "platforms": [ "WINDOWS", "LINUX" ], + "dependence": { + "mode": "ALL", + "settings": [ + { "key": "gpuav_enable", "value": true }, + { "key": "gpuav_shader_instrumentation", "value": true } + ] + } + }, + { "key": "gpuav_select_instrumented_shaders", "label": "Enable instrumenting shaders selectively", diff --git a/layers/gpuav/core/gpuav_record.cpp b/layers/gpuav/core/gpuav_record.cpp index 22285bc7554..b3e66712119 100644 --- a/layers/gpuav/core/gpuav_record.cpp +++ b/layers/gpuav/core/gpuav_record.cpp @@ -455,8 +455,7 @@ void Validator::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint3 InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer."); return; } - valcmd::DrawIndexed(*this, *cb_state, record_obj.location, indexCount, firstIndex, vertexOffset, - "VUID-vkCmdDrawIndexed-None-02721"); + PreCallSetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location); descriptor::PreCallActionCommand(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location); } @@ -557,11 +556,7 @@ void Validator::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffe valcmd::DrawIndexedIndirectIndexBuffer(*this, *cb_state, record_obj.location, buffer, offset, stride, count, VK_NULL_HANDLE, 0, "VUID-VkDrawIndexedIndirectCommand-robustBufferAccess2-08798"); -// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -#if 0 - valcmd::DrawIndexedIndirectVertexBuffer(*this, *cb_state, record_obj.location, buffer, offset, stride, count, VK_NULL_HANDLE, 0, - "VUID-vkCmdDrawIndexedIndirect-None-02721"); -#endif + valcmd::FirstInstance(*this, *cb_state, record_obj.location, buffer, offset, count, VK_NULL_HANDLE, 0, "VUID-VkDrawIndexedIndirectCommand-firstInstance-00554"); PreCallSetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location); @@ -705,11 +700,7 @@ void Validator::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer command valcmd::DrawIndexedIndirectIndexBuffer(*this, *cb_state, record_obj.location, buffer, offset, stride, maxDrawCount, countBuffer, countBufferOffset, "VUID-VkDrawIndexedIndirectCommand-robustBufferAccess2-08798"); -// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -#if 0 - valcmd::DrawIndexedIndirectVertexBuffer(*this, *cb_state, record_obj.location, buffer, offset, stride, maxDrawCount, - countBuffer, countBufferOffset, "VUID-vkCmdDrawIndexedIndirectCount-None-02721"); -#endif + PreCallSetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location); descriptor::PreCallActionCommand(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location); } diff --git a/layers/gpuav/core/gpuav_settings.h b/layers/gpuav/core/gpuav_settings.h index 0e727c1d290..593e53b9979 100644 --- a/layers/gpuav/core/gpuav_settings.h +++ b/layers/gpuav/core/gpuav_settings.h @@ -48,11 +48,13 @@ struct GpuAVSettings { bool buffer_device_address = true; bool ray_query = true; bool post_process_descriptor_index = true; + bool vertex_attribute_fetch_oob = true; } shader_instrumentation; bool IsShaderInstrumentationEnabled() const { return shader_instrumentation.descriptor_checks || shader_instrumentation.buffer_device_address || - shader_instrumentation.ray_query || shader_instrumentation.post_process_descriptor_index; + shader_instrumentation.ray_query || shader_instrumentation.post_process_descriptor_index || + shader_instrumentation.vertex_attribute_fetch_oob; } bool IsSpirvModified() const { return IsShaderInstrumentationEnabled() || debug_printf_enabled; } @@ -62,6 +64,7 @@ struct GpuAVSettings { shader_instrumentation.buffer_device_address = false; shader_instrumentation.ray_query = false; shader_instrumentation.post_process_descriptor_index = false; + shader_instrumentation.vertex_attribute_fetch_oob = false; // Because of this setting, cannot really have an "enabled" parameter to pass to this method select_instrumented_shaders = false; } diff --git a/layers/gpuav/core/gpuav_setup.cpp b/layers/gpuav/core/gpuav_setup.cpp index 6ae6b1fb5ff..a83a2e0c887 100644 --- a/layers/gpuav/core/gpuav_setup.cpp +++ b/layers/gpuav/core/gpuav_setup.cpp @@ -458,6 +458,8 @@ void Validator::PostCreateDevice(const VkDeviceCreateInfo *pCreateInfo, const Lo {glsl::kBindingInstCmdResourceIndex, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, nullptr}, // Commands errors counts buffer {glsl::kBindingInstCmdErrorsCount, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, + // Smallest vertex buffer binding + {glsl::kBindingInstSmallestVertexBufferBinding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, }; // TODO - Now that GPU-AV and DebugPrintf are merged, we should just have a single PostCreateDevice if possible (or at least diff --git a/layers/gpuav/instrumentation/gpuav_instrumentation.cpp b/layers/gpuav/instrumentation/gpuav_instrumentation.cpp index ed6e8f46a6a..214898eb4b9 100644 --- a/layers/gpuav/instrumentation/gpuav_instrumentation.cpp +++ b/layers/gpuav/instrumentation/gpuav_instrumentation.cpp @@ -27,6 +27,7 @@ #include "state_tracker/cmd_buffer_state.h" #include "state_tracker/shader_object_state.h" +#include "state_tracker/shader_module.h" namespace gpuav { @@ -165,8 +166,95 @@ static VkPipelineLayout CreateInstrumentationPipelineLayout(Validator &gpuav, Vk } } +// Computes the smallest vertex attributes count among the set of bound vertex buffers. +// Used to detect out of bounds indices in index buffers. +// If no vertex buffer is bound, smallest_vertex_attributes_count is std::numeric_limits::max() +// indicating that no index can be out of bound +static std::pair, std::optional> +SmallestVertexAttributesCount(const vvl::CommandBuffer &cb_state) { + const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS); + const LastBound &last_bound = cb_state.lastBound[lv_bind_point]; + const vvl::Pipeline *pipeline_state = last_bound.pipeline_state; + const bool use_shader_objects = pipeline_state == nullptr; + + const bool dynamic_vertex_input = use_shader_objects || pipeline_state->IsDynamic(CB_DYNAMIC_STATE_VERTEX_INPUT_EXT); + + const auto &vertex_binding_descriptions = + dynamic_vertex_input ? cb_state.dynamic_state_value.vertex_bindings : pipeline_state->vertex_input_state->bindings; + + std::optional smallest_vbb_vertex_input_rate; + std::optional smallest_vbb_instance_input_rate; + + vvl::unordered_set vertex_shader_used_locations; + { + const ::spirv::EntryPoint *vertex_entry_point = last_bound.GetVertexEntryPoint(); + if (!vertex_entry_point) { + return {smallest_vbb_vertex_input_rate, smallest_vbb_instance_input_rate}; + } + for (const ::spirv::StageInterfaceVariable &interface_var : vertex_entry_point->stage_interface_variables) { + for (const ::spirv::InterfaceSlot &interface_slot : interface_var.interface_slots) { + vertex_shader_used_locations.insert(interface_slot.Location()); + } + } + } + + for (const auto &[binding, vertex_binding_desc] : vertex_binding_descriptions) { + auto find_vbb = cb_state.current_vertex_buffer_binding_info.find(binding); + if (find_vbb == cb_state.current_vertex_buffer_binding_info.cend()) { + // This is a validation error + continue; + } + + const vvl::VertexBufferBinding &vbb = find_vbb->second; + + for (const auto &[location, attrib] : vertex_binding_desc.locations) { + if (vertex_shader_used_locations.find(location) == vertex_shader_used_locations.end()) { + continue; + } + const VkDeviceSize attribute_size = vkuFormatElementSize(attrib.desc.format); + + const VkDeviceSize stride = + vbb.stride != 0 ? vbb.stride : attribute_size; // Tracked stride should already handle all possible value origin + + VkDeviceSize vertex_buffer_remaining_size = + vbb.effective_size > attrib.desc.offset ? vbb.effective_size - attrib.desc.offset : 0; + + VkDeviceSize vertex_attributes_count = vertex_buffer_remaining_size / stride; + if (vertex_buffer_remaining_size > vertex_attributes_count * stride) { + vertex_buffer_remaining_size -= vertex_attributes_count * stride; + } else { + vertex_buffer_remaining_size = 0; + } + + // maybe room for one more attribute but not full stride - not having stride space does not matter for last element + if (vertex_buffer_remaining_size >= attribute_size) { + vertex_attributes_count += 1; + } + + std::optional *smallest_vbb_to_update = + (vertex_binding_desc.desc.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? &smallest_vbb_vertex_input_rate + : &smallest_vbb_instance_input_rate; + + if (!smallest_vbb_to_update->has_value()) { + *smallest_vbb_to_update = SmallestVertexBufferBinding{}; + } + (*smallest_vbb_to_update)->smallest_vertex_attributes_count = + std::min((*smallest_vbb_to_update)->smallest_vertex_attributes_count, vertex_attributes_count); + if ((*smallest_vbb_to_update)->smallest_vertex_attributes_count == vertex_attributes_count) { + (*smallest_vbb_to_update)->binding = binding; + (*smallest_vbb_to_update)->binding_info = vbb; + (*smallest_vbb_to_update)->attribute.location = attrib.desc.location; + (*smallest_vbb_to_update)->attribute.binding = attrib.desc.binding; + (*smallest_vbb_to_update)->attribute.format = attrib.desc.format; + (*smallest_vbb_to_update)->attribute.offset = attrib.desc.offset; + } + } + } + return {smallest_vbb_vertex_input_rate, smallest_vbb_instance_input_rate}; +} + void UpdateInstrumentationDescSet(Validator &gpuav, CommandBuffer &cb_state, VkDescriptorSet instrumentation_desc_set, - const Location &loc) { + const Location &loc, InstrumentationErrorBlob &out_instrumentation_error_blob) { std::vector desc_writes = {}; // Error output buffer @@ -276,6 +364,56 @@ void UpdateInstrumentationDescSet(Validator &gpuav, CommandBuffer &cb_state, VkD desc_writes.emplace_back(wds); } + vko::Buffer max_vertex_buffer(gpuav); + VkBufferCreateInfo buffer_info = vku::InitStructHelper(); + buffer_info.size = 4 * sizeof(uint32_t); + buffer_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + VmaAllocationCreateInfo alloc_info = {}; + alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + // #ARNO_TODO - optimize buffer allocation as much as possible, + // alloc_info.pool = shared_copy_validation_resources.copy_regions_pool; + + const bool success = max_vertex_buffer.Create(loc, &buffer_info, &alloc_info); + if (!success) { + return; + } + + const auto [smallest_vbb_vertex_input_rate, smallest_vbb_instance_input_rate] = SmallestVertexAttributesCount(cb_state); + auto max_vertex_buffer_ptr = (uint32_t *)max_vertex_buffer.MapMemory(loc); + if (smallest_vbb_vertex_input_rate.has_value()) { + max_vertex_buffer_ptr[0] = 1u; + max_vertex_buffer_ptr[1] = (uint32_t)smallest_vbb_vertex_input_rate->smallest_vertex_attributes_count; + } else { + max_vertex_buffer_ptr[0] = 0u; + max_vertex_buffer_ptr[1] = std::numeric_limits::max(); + } + if (smallest_vbb_instance_input_rate.has_value()) { + max_vertex_buffer_ptr[2] = 1u; + max_vertex_buffer_ptr[3] = (uint32_t)smallest_vbb_instance_input_rate->smallest_vertex_attributes_count; + } else { + max_vertex_buffer_ptr[2] = 0u; + max_vertex_buffer_ptr[3] = std::numeric_limits::max(); + } + + max_vertex_buffer.UnmapMemory(); + out_instrumentation_error_blob.smallest_vbb_vertex_input_rate = smallest_vbb_vertex_input_rate; + out_instrumentation_error_blob.smallest_vbb_instance_input_rate = smallest_vbb_instance_input_rate; + out_instrumentation_error_blob.index_buffer_binding = cb_state.index_buffer_binding; + + cb_state.gpu_resources_manager.ManageBuffer(max_vertex_buffer); + VkDescriptorBufferInfo max_vertex_index_buffer_info = {}; + max_vertex_index_buffer_info.buffer = max_vertex_buffer.VkHandle(); + max_vertex_index_buffer_info.offset = 0; + max_vertex_index_buffer_info.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet wds = vku::InitStructHelper(); + wds.dstSet = instrumentation_desc_set; + wds.dstBinding = glsl::kBindingInstSmallestVertexBufferBinding; + wds.descriptorCount = 1; + wds.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + wds.pBufferInfo = &max_vertex_index_buffer_info; + desc_writes.emplace_back(wds); + DispatchUpdateDescriptorSets(gpuav.device, static_cast(desc_writes.size()), desc_writes.data(), 0, nullptr); } @@ -306,7 +444,7 @@ void PreCallSetupShaderInstrumentationResources(Validator &gpuav, CommandBuffer // Pathetic way of trying to make sure we take care of updating all // bindings of the instrumentation descriptor set - assert(gpuav.instrumentation_bindings_.size() == 8); + assert(gpuav.instrumentation_bindings_.size() == 9); if (gpuav.gpuav_settings.debug_printf_enabled) { if (!debug_printf::UpdateInstrumentationDescSet(gpuav, cb_state, instrumentation_desc_set, bind_point, loc)) { @@ -315,8 +453,9 @@ void PreCallSetupShaderInstrumentationResources(Validator &gpuav, CommandBuffer return; } } + InstrumentationErrorBlob instrumentation_error_blob; if (gpuav.gpuav_settings.IsShaderInstrumentationEnabled()) { - UpdateInstrumentationDescSet(gpuav, cb_state, instrumentation_desc_set, loc); + UpdateInstrumentationDescSet(gpuav, cb_state, instrumentation_desc_set, loc, instrumentation_error_blob); } const uint32_t operation_index = (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) ? cb_state.draw_index @@ -441,15 +580,15 @@ void PreCallSetupShaderInstrumentationResources(Validator &gpuav, CommandBuffer CommandBuffer::ErrorLoggerFunc error_logger = [loc, descriptor_binding_index, descriptor_binding_list = &cb_state.descriptor_command_bindings, bind_point, - last_label_command_i, operation_index, uses_shader_object, - uses_robustness](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record, - const LogObjectList &objlist, const std::vector &initial_label_stack) { + last_label_command_i, operation_index, uses_shader_object, uses_robustness, + instrumentation_error_blob](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record, + const LogObjectList &objlist, const std::vector &initial_label_stack) { bool skip = false; const DescriptorCommandBinding *descriptor_command_binding = descriptor_binding_index != vvl::kU32Max ? &(*descriptor_binding_list)[descriptor_binding_index] : nullptr; - skip |= LogInstrumentationError(gpuav, cb_state, objlist, initial_label_stack, last_label_command_i, operation_index, - error_record, + skip |= LogInstrumentationError(gpuav, cb_state, objlist, instrumentation_error_blob, initial_label_stack, + last_label_command_i, operation_index, error_record, descriptor_command_binding ? descriptor_command_binding->bound_descriptor_sets : std::vector>(), bind_point, uses_shader_object, uses_robustness, loc); @@ -738,6 +877,121 @@ bool LogMessageInstRayQuery(const uint32_t *error_record, std::string &out_error return error_found; } +bool LogMessageInstIndexedDraw(Validator &gpuav, const uint32_t *error_record, std::string &out_error_msg, + std::string &out_vuid_msg, const Location &loc, const InstrumentationErrorBlob &inst_error_blob) { + const uint32_t error_sub_code = error_record[glsl::kHeaderErrorSubCodeOffset]; + if (error_sub_code != glsl::kErrorSubCode_IndexedDraw_OOBVertexIndex && + error_sub_code != glsl::kErrorSubCode_IndexedDraw_OOBInstanceIndex) { + return false; + } + + switch (loc.function) { + case vvl::Func::vkCmdDrawIndexed: + out_vuid_msg = "VUID-vkCmdDrawIndexed-None-02721"; + break; + case vvl::Func::vkCmdDrawIndexedIndirectCount: + out_vuid_msg = "VUID-vkCmdDrawIndexedIndirectCount-None-02721"; + break; + case vvl::Func::vkCmdDrawIndexedIndirect: + out_vuid_msg = "VUID-vkCmdDrawIndexedIndirect-None-02721"; + break; + default: + return false; + } + + assert(inst_error_blob.smallest_vbb_vertex_input_rate.has_value() || + inst_error_blob.smallest_vbb_instance_input_rate.has_value()); + assert(inst_error_blob.index_buffer_binding.has_value()); + + auto add_vertex_buffer_binding_info = [&gpuav](const SmallestVertexBufferBinding &smallest_vbb, std::string &out) { + out += "- Buffer: "; + out += gpuav.FormatHandle(smallest_vbb.binding_info.buffer); + out += '\n'; + out += "- Binding: "; + out += std::to_string(smallest_vbb.binding); + out += '\n'; + out += "- Binding size (effective): "; + out += std::to_string(smallest_vbb.binding_info.effective_size); + out += " bytes\n"; + out += "- Binding offset: "; + out += std::to_string(smallest_vbb.binding_info.offset); + out += " bytes\n"; + out += "- Binding stride: "; + out += std::to_string(smallest_vbb.binding_info.stride); + out += " bytes\n"; + out += "- Vertices count: "; + out += std::to_string(smallest_vbb.smallest_vertex_attributes_count); + out += '\n'; + }; + + auto add_vertex_attribute_info = [](const SmallestVertexBufferBinding &smallest_vbb, std::string &out) { + out += "At least the following vertex attribute caused OOB access:\n"; + out += "- Location: "; + out += std::to_string(smallest_vbb.attribute.location); + out += '\n'; + out += "- Binding: "; + out += std::to_string(smallest_vbb.attribute.binding); + out += '\n'; + out += "- Format: "; + out += string_VkFormat(smallest_vbb.attribute.format); + out += '\n'; + out += "- Offset: "; + out += std::to_string(smallest_vbb.attribute.offset); + out += " bytes\n"; + }; + + if (error_sub_code == glsl::kErrorSubCode_IndexedDraw_OOBVertexIndex) { + out_error_msg += "Vertex index "; + const uint32_t oob_vertex_index = error_record[glsl::kHeaderStageInfoOffset_0]; + out_error_msg += std::to_string(oob_vertex_index); + } else { + out_error_msg += "Instance index "; + const uint32_t oob_instance_index = error_record[glsl::kHeaderStageInfoOffset_1]; + out_error_msg += std::to_string(oob_instance_index); + } + + out_error_msg += " is not within the smallest bound vertex buffer.\n"; + + if (error_sub_code == glsl::kErrorSubCode_IndexedDraw_OOBVertexIndex) { + out_error_msg += "Smallest vertex buffer binding info, causing OOB access with VK_VERTEX_INPUT_RATE_VERTEX:\n"; + add_vertex_buffer_binding_info(*inst_error_blob.smallest_vbb_vertex_input_rate, out_error_msg); + add_vertex_attribute_info(*inst_error_blob.smallest_vbb_vertex_input_rate, out_error_msg); + + } else { + out_error_msg += "Smallest vertex buffer binding info, causing OOB access with VK_VERTEX_INPUT_RATE_INSTANCE:\n"; + add_vertex_buffer_binding_info(*inst_error_blob.smallest_vbb_instance_input_rate, out_error_msg); + add_vertex_attribute_info(*inst_error_blob.smallest_vbb_instance_input_rate, out_error_msg); + } + + if (error_sub_code == glsl::kErrorSubCode_IndexedDraw_OOBVertexIndex) { + const uint32_t index_bits_size = GetIndexBitsSize(inst_error_blob.index_buffer_binding->index_type); + const uint32_t max_indices_in_buffer = + static_cast(inst_error_blob.index_buffer_binding->size / (index_bits_size / 8u)); + out_error_msg += "Index buffer binding info:\n"; + out_error_msg += "- Buffer: "; + out_error_msg += gpuav.FormatHandle(inst_error_blob.index_buffer_binding->buffer); + out_error_msg += '\n'; + out_error_msg += "- Index type: "; + out_error_msg += string_VkIndexType(inst_error_blob.index_buffer_binding->index_type); + out_error_msg += '\n'; + out_error_msg += "- Binding offset: "; + out_error_msg += std::to_string(inst_error_blob.index_buffer_binding->offset); + out_error_msg += " bytes\n"; + out_error_msg += "- Binding size: "; + out_error_msg += std::to_string(inst_error_blob.index_buffer_binding->size); + out_error_msg += " bytes (or "; + out_error_msg += std::to_string(max_indices_in_buffer); + out_error_msg += ' '; + out_error_msg += string_VkIndexType(inst_error_blob.index_buffer_binding->index_type); + out_error_msg += ")\n"; + } + out_error_msg += + "Note: Vertex buffer binding size is the effective, valid one, based on how the VkBuffer was created and " + "vertex buffer binding parameters. So it can be clamped up to 0 if binding was invalid."; + + return true; +} + // Pull together all the information from the debug record to build the error message strings, // and then assemble them into a single message string. // Retrieve the shader program referenced by the unique shader ID provided in the debug record. @@ -746,6 +1000,7 @@ bool LogMessageInstRayQuery(const uint32_t *error_record, std::string &out_error // keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.) // bool LogInstrumentationError(Validator &gpuav, const CommandBuffer &cb_state, const LogObjectList &objlist, + const InstrumentationErrorBlob &instrumentation_error_blob, const std::vector &initial_label_stack, uint32_t label_command_i, uint32_t operation_index, const uint32_t *error_record, const std::vector> &descriptor_sets, @@ -780,6 +1035,9 @@ bool LogInstrumentationError(Validator &gpuav, const CommandBuffer &cb_state, co case glsl::kErrorGroupInstRayQuery: error_found = LogMessageInstRayQuery(error_record, error_msg, vuid_msg); break; + case glsl::kErrorGroupInstIndexedDraw: + error_found = LogMessageInstIndexedDraw(gpuav, error_record, error_msg, vuid_msg, loc, instrumentation_error_blob); + break; default: break; } diff --git a/layers/gpuav/instrumentation/gpuav_instrumentation.h b/layers/gpuav/instrumentation/gpuav_instrumentation.h index d882e01c352..d7c612fce08 100644 --- a/layers/gpuav/instrumentation/gpuav_instrumentation.h +++ b/layers/gpuav/instrumentation/gpuav_instrumentation.h @@ -18,10 +18,14 @@ #pragma once #include + +#include "state_tracker/vertex_index_buffer_state.h" + #include #include #include #include +#include struct Location; struct LogObjectList; @@ -36,9 +40,10 @@ class DescriptorSet; class Validator; class CommandBuffer; class Queue; +struct InstrumentationErrorBlob; void UpdateInstrumentationDescSet(Validator& gpuav, CommandBuffer& cb_state, VkDescriptorSet instrumentation_desc_set, - const Location& loc); + const Location& loc, InstrumentationErrorBlob& out_instrumentation_error_blob); void PreCallSetupShaderInstrumentationResources(Validator& gpuav, CommandBuffer& cb_state, VkPipelineBindPoint bind_point, const Location& loc); @@ -46,8 +51,26 @@ void PreCallSetupShaderInstrumentationResources(Validator& gpuav, CommandBuffer& void PostCallSetupShaderInstrumentationResources(Validator& gpuav, CommandBuffer& cb_statee, VkPipelineBindPoint bind_point, const Location& loc); +struct SmallestVertexBufferBinding { + VkDeviceSize smallest_vertex_attributes_count = std::numeric_limits::max(); + uint32_t binding = std::numeric_limits::max(); + vvl::VertexBufferBinding binding_info{}; + struct Attribute { + uint32_t location{}; + uint32_t binding{}; + VkFormat format{}; + uint32_t offset{}; + } attribute; +}; + +struct InstrumentationErrorBlob { + std::optional smallest_vbb_vertex_input_rate{}; + std::optional smallest_vbb_instance_input_rate{}; + std::optional index_buffer_binding; +}; // Return true iff an error has been found bool LogInstrumentationError(Validator& gpuav, const CommandBuffer& cb_state, const LogObjectList& objlist, + const InstrumentationErrorBlob& instrumentation_error_blob, const std::vector& initial_label_stack, uint32_t label_command_i, uint32_t operation_index, const uint32_t* error_record, const std::vector>& descriptor_sets, diff --git a/layers/gpuav/instrumentation/gpuav_shader_instrumentor.cpp b/layers/gpuav/instrumentation/gpuav_shader_instrumentor.cpp index 39bf085fc3e..e3c1735749b 100644 --- a/layers/gpuav/instrumentation/gpuav_shader_instrumentor.cpp +++ b/layers/gpuav/instrumentation/gpuav_shader_instrumentor.cpp @@ -44,6 +44,7 @@ #include "gpuav/spirv/ray_query_pass.h" #include "gpuav/spirv/debug_printf_pass.h" #include "gpuav/spirv/post_process_descriptor_indexing_pass.h" +#include "gpuav/spirv/vertex_attribute_fetch_oob.h" #include #include @@ -1204,6 +1205,11 @@ bool GpuShaderInstrumentor::InstrumentShader(const vvl::span &in modified |= pass.Run(); } + if (gpuav_settings.shader_instrumentation.vertex_attribute_fetch_oob) { + spirv::VertexAttributeFetchOob pass(module); + modified |= pass.Run(); + } + // If there were GLSL written function injected, we will grab them and link them in here for (const auto &info : module.link_info_) { module.LinkFunction(info); diff --git a/layers/gpuav/resources/gpuav_state_trackers.cpp b/layers/gpuav/resources/gpuav_state_trackers.cpp index ec59858a343..124c4def77f 100644 --- a/layers/gpuav/resources/gpuav_state_trackers.cpp +++ b/layers/gpuav/resources/gpuav_state_trackers.cpp @@ -25,6 +25,8 @@ #include "gpuav/shaders/gpuav_error_header.h" #include "gpuav/debug_printf/debug_printf.h" +#include "profiling/profiling.h" + namespace gpuav { Buffer::Buffer(ValidationStateTracker &dev_data, VkBuffer buff, const VkBufferCreateInfo *pCreateInfo, DescriptorHeap &desc_heap_) @@ -531,6 +533,8 @@ void CommandBuffer::PostProcess(VkQueue queue, const std::vector &i record_size = error_record_ptr[glsl::kHeaderErrorRecordSizeOffset]; } + VVL_TracyPlot("GPU-AV errors count", int64_t(total_words / glsl::kErrorRecordSize)); + // Clear the written size and any error messages. Note that this preserves the first word, which contains flags. assert(glsl::kErrorBufferByteSize > cst::stream_output_data_offset); memset(&error_output_buffer_ptr[cst::stream_output_data_offset], 0, diff --git a/layers/gpuav/resources/gpuav_state_trackers.h b/layers/gpuav/resources/gpuav_state_trackers.h index 09a293c8b8f..2ae9b51b328 100644 --- a/layers/gpuav/resources/gpuav_state_trackers.h +++ b/layers/gpuav/resources/gpuav_state_trackers.h @@ -125,7 +125,7 @@ class CommandBuffer : public vvl::CommandBuffer { using ErrorLoggerFunc = stdext::inplace_function &initial_label_stack), - 192 /*lambda storage size (bytes), large enough to storest biggest error lambda*/>; + 256 /*lambda storage size (bytes), large enough to storest biggest error lambda*/>; std::vector per_command_error_loggers; using ValidationCommandFunc = stdext::inplace_function; diff --git a/layers/gpuav/shaders/gpuav_error_codes.h b/layers/gpuav/shaders/gpuav_error_codes.h index be33e582079..c52cdabe894 100644 --- a/layers/gpuav/shaders/gpuav_error_codes.h +++ b/layers/gpuav/shaders/gpuav_error_codes.h @@ -35,6 +35,7 @@ const int kErrorGroupGpuPreDispatch = 5; const int kErrorGroupGpuPreTraceRays = 6; const int kErrorGroupGpuCopyBufferToImage = 7; const int kErrorGroupInstDescriptorClass = 8; +const int kErrorGroupInstIndexedDraw = 9; // Used for MultiEntry and there is no single stage set const int kHeaderStageIdMultiEntryPoint = 0x7fffffff; // same as spv::ExecutionModelMax @@ -72,6 +73,11 @@ const int kErrorSubCodeRayQueryDirectionNaN = 10; const int kErrorSubCodeRayQueryOriginFinite = 11; const int kErrorSubCodeRayQueryDirectionFinite = 12; +// Indexed Draw +// +const int kErrorSubCode_IndexedDraw_OOBVertexIndex = 1; +const int kErrorSubCode_IndexedDraw_OOBInstanceIndex = 2; + // Pre Draw // // The draw count exceeded the draw buffer size diff --git a/layers/gpuav/shaders/gpuav_error_header.h b/layers/gpuav/shaders/gpuav_error_header.h index f04b2e8d836..f8a1d0cbcb0 100644 --- a/layers/gpuav/shaders/gpuav_error_header.h +++ b/layers/gpuav/shaders/gpuav_error_header.h @@ -113,7 +113,7 @@ const int kInstBuffAddrAccessAlignmentOffset = kHeaderSize + 4; // --- const int kInstRayQueryParamOffset_0 = kHeaderSize; -// Pre shaders +// Validation commands shaders // --- const int kPreActionParamOffset_0 = kHeaderSize; const int kPreActionParamOffset_1 = kHeaderSize + 1; diff --git a/layers/gpuav/shaders/gpuav_shaders_constants.h b/layers/gpuav/shaders/gpuav_shaders_constants.h index 76e6e0112a2..69dda2d6619 100644 --- a/layers/gpuav/shaders/gpuav_shaders_constants.h +++ b/layers/gpuav/shaders/gpuav_shaders_constants.h @@ -59,6 +59,7 @@ const int kBindingInstBufferDeviceAddress = 4; const int kBindingInstActionIndex = 5; const int kBindingInstCmdResourceIndex = 6; const int kBindingInstCmdErrorsCount = 7; +const int kBindingInstSmallestVertexBufferBinding = 8; // Diagnostic calls // --- diff --git a/layers/gpuav/shaders/instrumentation/vertex_attribute_fetch_oob.vert b/layers/gpuav/shaders/instrumentation/vertex_attribute_fetch_oob.vert new file mode 100644 index 00000000000..c943bdc8b14 --- /dev/null +++ b/layers/gpuav/shaders/instrumentation/vertex_attribute_fetch_oob.vert @@ -0,0 +1,78 @@ +// Copyright (c) 2024 The Khronos Group Inc. +// Copyright (c) 2024 Valve Corporation +// Copyright (c) 2024 LunarG, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// NOTE: This file doesn't contain any entrypoints and should be compiled with the --no-link option for glslang + +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "gpuav_error_header.h" +#include "gpuav_shaders_constants.h" +#include "common_descriptor_sets.h" + +layout(set = kInstDefaultDescriptorSet, binding = kBindingInstSmallestVertexBufferBinding, std430) +readonly buffer MaxVertexIndex { + uint has_smallest_vbb_vertex_input_rate; + uint smallest_vbb_vertex_input_rate; + uint has_smallest_vbb_instance_input_rate; + uint smallest_vbb_instance_input_rate; +}; + +void inst_vertex_attribute_fetch_oob(const uvec4 stage_info) +{ + const uint vertex_index = stage_info[1]; + const uint instance_index = stage_info[2]; + + bool valid_vertex_attribute_fetch_vertex_input_rate = true; + bool valid_vertex_attribute_fetch_instance_input_rate = true; + + if (has_smallest_vbb_vertex_input_rate == 1u) { + valid_vertex_attribute_fetch_vertex_input_rate = vertex_index < smallest_vbb_vertex_input_rate; + } + if (has_smallest_vbb_instance_input_rate == 1u) { + valid_vertex_attribute_fetch_instance_input_rate = instance_index < smallest_vbb_instance_input_rate; + } + + if (!valid_vertex_attribute_fetch_vertex_input_rate || !valid_vertex_attribute_fetch_instance_input_rate) { + const uint cmd_id = inst_cmd_resource_index_buffer.index[0]; + const uint cmd_errors_count = atomicAdd(inst_cmd_errors_count_buffer.errors_count[cmd_id], 1); + const bool max_cmd_errors_count_reached = cmd_errors_count >= kMaxErrorsPerCmd; + + if (max_cmd_errors_count_reached) return; + + uint write_pos = atomicAdd(inst_errors_buffer.written_count, kErrorRecordSize); + const bool errors_buffer_not_filled = (write_pos + kErrorRecordSize) <= uint(inst_errors_buffer.data.length()); + + if (errors_buffer_not_filled) { + inst_errors_buffer.data[write_pos + kHeaderErrorRecordSizeOffset] = kErrorRecordSize; + inst_errors_buffer.data[write_pos + kHeaderShaderIdOffset] = kLinkShaderId; + inst_errors_buffer.data[write_pos + kHeaderInstructionIdOffset] = 0;// Irrelevant + inst_errors_buffer.data[write_pos + kHeaderStageIdOffset] = stage_info[0]; + inst_errors_buffer.data[write_pos + kHeaderStageInfoOffset_0] = stage_info[1]; + inst_errors_buffer.data[write_pos + kHeaderStageInfoOffset_1] = stage_info[2]; + inst_errors_buffer.data[write_pos + kHeaderStageInfoOffset_2] = stage_info[3]; + + inst_errors_buffer.data[write_pos + kHeaderErrorGroupOffset] = kErrorGroupInstIndexedDraw; + inst_errors_buffer.data[write_pos + kHeaderErrorSubCodeOffset] = + !valid_vertex_attribute_fetch_vertex_input_rate ? + kErrorSubCode_IndexedDraw_OOBVertexIndex : + kErrorSubCode_IndexedDraw_OOBInstanceIndex; + + inst_errors_buffer.data[write_pos + kHeaderActionIdOffset] = inst_action_index_buffer.index[0]; + inst_errors_buffer.data[write_pos + kHeaderCommandResourceIdOffset] = inst_cmd_resource_index_buffer.index[0]; + } + } +} diff --git a/layers/gpuav/spirv/CMakeLists.txt b/layers/gpuav/spirv/CMakeLists.txt index 6f3c1f12ed9..05d05801308 100644 --- a/layers/gpuav/spirv/CMakeLists.txt +++ b/layers/gpuav/spirv/CMakeLists.txt @@ -31,6 +31,8 @@ target_sources(gpu_av_spirv PRIVATE debug_printf_pass.cpp post_process_descriptor_indexing_pass.h post_process_descriptor_indexing_pass.cpp + vertex_attribute_fetch_oob.h + vertex_attribute_fetch_oob.cpp # Framework instruction.h @@ -65,7 +67,8 @@ target_sources(gpu_av_spirv PRIVATE ${VVL_SOURCE_DIR}/layers/${API_TYPE}/generated/instrumentation_ray_query_comp.cpp ${VVL_SOURCE_DIR}/layers/${API_TYPE}/generated/instrumentation_post_process_descriptor_index_comp.h ${VVL_SOURCE_DIR}/layers/${API_TYPE}/generated/instrumentation_post_process_descriptor_index_comp.cpp - + ${VVL_SOURCE_DIR}/layers/${API_TYPE}/generated/instrumentation_vertex_attribute_fetch_oob_vert.h + ${VVL_SOURCE_DIR}/layers/${API_TYPE}/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp ) target_include_directories(gpu_av_spirv PRIVATE . @@ -78,6 +81,10 @@ target_link_libraries(gpu_av_spirv PRIVATE VkLayer_utils # To pull in compile_definitions ) +if (VVL_ENABLE_TRACY) + target_link_libraries(gpu_av_spirv PRIVATE TracyClient) +endif() + if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") target_compile_options(gpu_av_spirv PRIVATE -Wno-sign-conversion diff --git a/layers/gpuav/spirv/function_basic_block.h b/layers/gpuav/spirv/function_basic_block.h index 47e7dec3b8a..af502133747 100644 --- a/layers/gpuav/spirv/function_basic_block.h +++ b/layers/gpuav/spirv/function_basic_block.h @@ -49,8 +49,9 @@ struct BasicBlock { // Finds instruction before the Block Termination Instruction. InstructionIt GetLastInjectableInstrution(); - // Creates instruction and inserts it before the Instruction, updates poistion after new instruciton. - // If no InstructionIt is provided, it will add it to the end of the block. + // Creates an instruction and inserts it before an optional target inst_it. + // If an InstructionIt is provided, inst_it will be updated to still point at the original target instruction. + // Otherwise, the new instruction will be created at block end. void CreateInstruction(spv::Op opcode, const std::vector& words, InstructionIt* inst_it = nullptr); InstructionList instructions_; diff --git a/layers/gpuav/spirv/vertex_attribute_fetch_oob.cpp b/layers/gpuav/spirv/vertex_attribute_fetch_oob.cpp new file mode 100644 index 00000000000..32270096d99 --- /dev/null +++ b/layers/gpuav/spirv/vertex_attribute_fetch_oob.cpp @@ -0,0 +1,90 @@ +/* Copyright (c) 2018-2024 The Khronos Group Inc. + * Copyright (c) 2018-2024 Valve Corporation + * Copyright (c) 2018-2024 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "vertex_attribute_fetch_oob.h" +#include "module.h" +#include "generated/instrumentation_vertex_attribute_fetch_oob_vert.h" + +#include + +#include "profiling/profiling.h" + +namespace gpuav { +namespace spirv { + +uint32_t VertexAttributeFetchOob::GetLinkFunctionId() { + static LinkInfo link_info = {instrumentation_vertex_attribute_fetch_oob_vert, + instrumentation_vertex_attribute_fetch_oob_vert_size, 0, "inst_vertex_attribute_fetch_oob"}; + + if (link_function_id == 0) { + link_function_id = module_.TakeNextId(); + link_info.function_id = link_function_id; + module_.link_info_.push_back(link_info); + } + return link_function_id; +} + +VertexAttributeFetchOob::VertexAttributeFetchOob(Module& module) : Pass(module) {} + +bool VertexAttributeFetchOob::Instrument() { + for (const auto& entry_point_inst : module_.entry_points_) { + const uint32_t execution_model = entry_point_inst->Word(1); + if (execution_model != spv::ExecutionModelVertex) continue; + + const uint32_t vertex_shader_entry_point_id = entry_point_inst->Word(2); + for (const auto& function : module_.functions_) { + const uint32_t function_id = function->GetDef().Word(2); + if (vertex_shader_entry_point_id != function_id) continue; + + BasicBlock& first_block = *function->blocks_[0]; + InstructionIt first_injectable_instruction = first_block.GetFirstInjectableInstrution(); + target_instruction_ = first_injectable_instruction->get(); + + const uint32_t stage_info_id = GetStageInfo(*function, function->blocks_.begin(), first_injectable_instruction); + + InstructionIt stage_info_inst_it; + for (auto inst_it = first_block.instructions_.begin(); inst_it != first_block.instructions_.end(); ++inst_it) { + if ((*inst_it)->ResultId() == stage_info_id) { + stage_info_inst_it = inst_it; + break; + } + } + ++stage_info_inst_it; + + std::vector index_validation_inst_words; + const uint32_t void_type = module_.type_manager_.GetTypeVoid().Id(); + const uint32_t function_result = module_.TakeNextId(); + const uint32_t function_def = GetLinkFunctionId(); + + first_block.CreateInstruction(spv::OpFunctionCall, {void_type, function_result, function_def, stage_info_id}, + &stage_info_inst_it); + + instrumentation_performed = true; + VVL_TracyPlot(__FUNCTION__, int64_t(1)); + return true; + } + } + return false; +} + +void VertexAttributeFetchOob::PrintDebugInfo() const { + std::cout << "VertexAttributeFetchOob instrumentation performed: " << std::boolalpha << instrumentation_performed << '\n'; +} + +} // namespace spirv + +} // namespace gpuav diff --git a/layers/gpuav/spirv/vertex_attribute_fetch_oob.h b/layers/gpuav/spirv/vertex_attribute_fetch_oob.h new file mode 100644 index 00000000000..0e9ad0bcba4 --- /dev/null +++ b/layers/gpuav/spirv/vertex_attribute_fetch_oob.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2018-2024 The Khronos Group Inc. + * Copyright (c) 2018-2024 Valve Corporation + * Copyright (c) 2018-2024 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "pass.h" + +namespace gpuav { +namespace spirv { + +// Validating validating that gl_VertexID is an index within bound vertex buffers +class VertexAttributeFetchOob : public Pass { + public: + VertexAttributeFetchOob(Module& module); + const char* Name() const final { return "VertexAttributeFetchOob"; } + + bool Instrument(); + void PrintDebugInfo() const final; + + private: + uint32_t GetLinkFunctionId(); + void Reset() final {} + + uint32_t link_function_id = 0; + bool instrumentation_performed = false; +}; + +} // namespace spirv +} // namespace gpuav diff --git a/layers/gpuav/validation_cmd/gpuav_copy_buffer_to_image.cpp b/layers/gpuav/validation_cmd/gpuav_copy_buffer_to_image.cpp index 6db52b9eba5..36d02468394 100644 --- a/layers/gpuav/validation_cmd/gpuav_copy_buffer_to_image.cpp +++ b/layers/gpuav/validation_cmd/gpuav_copy_buffer_to_image.cpp @@ -196,9 +196,6 @@ void InsertCopyBufferToImageValidation(Validator &gpuav, const Location &loc, Co VmaAllocationCreateInfo alloc_info = {}; alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - uint32_t mem_type_index = 0; - vmaFindMemoryTypeIndexForBufferInfo(gpuav.vma_allocator_, &buffer_info, &alloc_info, &mem_type_index); - alloc_info.pool = shared_copy_validation_resources.copy_regions_pool; const bool success = copy_src_regions_mem_buffer.Create(loc, &buffer_info, &alloc_info); if (!success) { diff --git a/layers/gpuav/validation_cmd/gpuav_draw.cpp b/layers/gpuav/validation_cmd/gpuav_draw.cpp index 39baaac95e9..ffdef2b598a 100644 --- a/layers/gpuav/validation_cmd/gpuav_draw.cpp +++ b/layers/gpuav/validation_cmd/gpuav_draw.cpp @@ -799,304 +799,6 @@ void DrawMeshIndirect(Validator &gpuav, CommandBuffer &cb_state, const Location cb_state.per_command_error_loggers.emplace_back(std::move(error_logger)); } -struct SmallestVertexBufferBinding { - VkDeviceSize smallest_vertex_attributes_count = std::numeric_limits::max(); - uint32_t binding = std::numeric_limits::max(); - vvl::VertexBufferBinding binding_info{}; - struct Attribute { - uint32_t location{}; - uint32_t binding{}; - VkFormat format{}; - uint32_t offset{}; - } attribute; -}; -// Computes the smallest vertex attributes count among the set of bound vertex buffers. -// Used to detect out of bounds indices in index buffers. -// If no vertex buffer is bound, smallest_vertex_attributes_count is std::numeric_limits::max() -// indicating that no index can be out of bound -static std::optional SmallestVertexAttributesCount(const vvl::CommandBuffer &cb_state) { - const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS); - const LastBound &last_bound = cb_state.lastBound[lv_bind_point]; - const vvl::Pipeline *pipeline_state = last_bound.pipeline_state; - const bool use_shader_objects = pipeline_state == nullptr; - - const bool dynamic_vertex_input = use_shader_objects || pipeline_state->IsDynamic(CB_DYNAMIC_STATE_VERTEX_INPUT_EXT); - - const auto &vertex_binding_descriptions = - dynamic_vertex_input ? cb_state.dynamic_state_value.vertex_bindings : pipeline_state->vertex_input_state->bindings; - - std::optional smallest_vertex_buffer_binding; - - for (const auto &[binding, vertex_binding_desc] : vertex_binding_descriptions) { - auto find_vbb = cb_state.current_vertex_buffer_binding_info.find(binding); - if (find_vbb == cb_state.current_vertex_buffer_binding_info.cend()) { - // This is a validation error - continue; - } - - const vvl::VertexBufferBinding &vbb = find_vbb->second; - - // #ARNO_TODO: Should I only loop over vertex attributes actually used by bound pipelines, - // according to its vertex shader? - for (const auto &[Location, attrib] : vertex_binding_desc.locations) { - const VkDeviceSize attribute_size = GetVertexInputFormatSize(attrib.desc.format); - - const VkDeviceSize stride = - vbb.stride != 0 ? vbb.stride : attribute_size; // Tracked stride should already handle all possible value origin - - VkDeviceSize vertex_buffer_remaining_size = - vbb.effective_size > attrib.desc.offset ? vbb.effective_size - attrib.desc.offset : 0; - - VkDeviceSize vertex_attributes_count = vertex_buffer_remaining_size / stride; - if (vertex_buffer_remaining_size > vertex_attributes_count * stride) { - vertex_buffer_remaining_size -= vertex_attributes_count * stride; - } else { - vertex_buffer_remaining_size = 0; - } - - // maybe room for one more attribute but not full stride - not having stride space does not matter for last element - if (vertex_buffer_remaining_size >= attribute_size) { - vertex_attributes_count += 1; - } - - if (!smallest_vertex_buffer_binding.has_value()) { - smallest_vertex_buffer_binding = SmallestVertexBufferBinding{}; - } - smallest_vertex_buffer_binding->smallest_vertex_attributes_count = - std::min(smallest_vertex_buffer_binding->smallest_vertex_attributes_count, vertex_attributes_count); - if (smallest_vertex_buffer_binding->smallest_vertex_attributes_count == vertex_attributes_count) { - smallest_vertex_buffer_binding->binding = binding; - smallest_vertex_buffer_binding->binding_info = vbb; - smallest_vertex_buffer_binding->attribute.location = attrib.desc.location; - smallest_vertex_buffer_binding->attribute.binding = attrib.desc.binding; - smallest_vertex_buffer_binding->attribute.format = attrib.desc.format; - smallest_vertex_buffer_binding->attribute.offset = attrib.desc.offset; - } - } - } - return smallest_vertex_buffer_binding; -} - -struct IndexBufferValidationShader { - static size_t GetSpirvSize() { return validation_cmd_draw_indexed_comp_size * sizeof(uint32_t); } - static const uint32_t *GetSpirv() { return validation_cmd_draw_indexed_comp; } - - static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet; - - glsl::IndexedDrawPushData push_constants{}; - BoundStorageBuffer index_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndexBuffer}; - - static std::vector GetDescriptorSetLayoutBindings() { - std::vector bindings = { - {gpuav::glsl::kPreDrawBinding_IndexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; - - return bindings; - } - - std::vector GetDescriptorWrites(VkDescriptorSet desc_set) const { - std::vector desc_writes(1); - - desc_writes[0] = vku::InitStructHelper(); - desc_writes[0].dstSet = desc_set; - desc_writes[0].dstBinding = index_buffer_binding.binding; - desc_writes[0].dstArrayElement = 0; - desc_writes[0].descriptorCount = 1; - desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - desc_writes[0].pBufferInfo = &index_buffer_binding.info; - - return desc_writes; - } -}; - -void DrawIndexed(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, uint32_t index_count, uint32_t first_index, - uint32_t vertex_offset, const char *vuid_oob_vertex) { - if (!gpuav.gpuav_settings.validate_index_buffers) { - return; - } - - if (gpuav.enabled_features.robustBufferAccess) { - return; - } - - const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS); - const LastBound &last_bound = cb_state.lastBound[lv_bind_point]; - const vvl::Pipeline *pipeline_state = last_bound.pipeline_state; - if (pipeline_state) { - const auto robustness_ci = - vku::FindStructInPNextChain(pipeline_state->GraphicsCreateInfo().pNext); - if (robustness_ci && robustness_ci->vertexInputs) { - return; - } - } - - if (!cb_state.IsPrimary()) { - // TODO Unhandled for now. Potential issues with accessing the right vertex buffers - // in secondary command buffers - return; - } - - if (!cb_state.index_buffer_binding.buffer) { - return; - } - - const std::optional smallest_vertex_buffer_binding = SmallestVertexAttributesCount(cb_state); - if (!smallest_vertex_buffer_binding.has_value()) { - // cannot overrun index buffer, skip validation - return; - } - - CommandBuffer::ValidationCommandFunc validation_cmd = [index_buffer_binding = cb_state.index_buffer_binding, index_count, - first_index, vertex_offset, - smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding, - draw_i = cb_state.draw_index, - error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()), - loc](Validator &gpuav, CommandBuffer &cb_state) { - SharedDrawValidationResources &shared_draw_validation_resources = - gpuav.shared_resources_manager.Get(gpuav, loc); - if (!shared_draw_validation_resources.valid) return; - ComputeValidationPipeline &validation_pipeline = - gpuav.shared_resources_manager.Get>( - gpuav, loc, cb_state.GetErrorLoggingDescSetLayout()); - if (!validation_pipeline.valid) return; - - const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type); - const uint32_t max_indices_in_buffer = static_cast(index_buffer_binding.size / (index_bits_size / 8u)); - const uint32_t indices_to_check = std::min(index_count, max_indices_in_buffer); - - { - IndexBufferValidationShader shader_resources; - shader_resources.push_constants.smallest_vertex_attributes_count = - static_cast(smallest_vertex_buffer_binding.smallest_vertex_attributes_count); - shader_resources.push_constants.index_width = index_bits_size; - shader_resources.push_constants.vertex_offset = vertex_offset; - shader_resources.push_constants.first_index = first_index; - - shader_resources.index_buffer_binding.info = {index_buffer_binding.buffer, 0, - index_buffer_binding.offset + index_buffer_binding.size}; - shader_resources.push_constants.index_buffer_dwords_offset = (uint32_t)index_buffer_binding.offset / sizeof(uint32_t); - shader_resources.push_constants.indices_to_check = indices_to_check; - - validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources); - } - - { - DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline); - - // Do not overrun index buffer - constexpr uint32_t work_group_size = 64; - const uint32_t work_group_count = - indices_to_check / work_group_size + uint32_t(indices_to_check % work_group_size != 0); - VVL_TracyPlot("gpuav::valcmd::DrawIndexed Dispatch size", int64_t(work_group_count)); - DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1); - // synchronize draw buffer validation (read) against subsequent writes - VkBufferMemoryBarrier index_buffer_memory_barrier = vku::InitStructHelper(); - index_buffer_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - index_buffer_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; - index_buffer_memory_barrier.buffer = index_buffer_binding.buffer; - index_buffer_memory_barrier.offset = index_buffer_binding.offset; - index_buffer_memory_barrier.size = index_buffer_binding.size; - - DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 1, &index_buffer_memory_barrier, 0, - nullptr); - } - }; - cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd)); - - const uint32_t label_command_i = - !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max; - CommandBuffer::ErrorLoggerFunc error_logger = - [loc, vuid_oob_vertex, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding, - index_buffer_binding = cb_state.index_buffer_binding, - label_command_i](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record, - const LogObjectList &objlist, const std::vector &initial_label_stack) { - bool skip = false; - - using namespace glsl; - - switch (error_record[kHeaderErrorSubCodeOffset]) { - case kErrorSubCode_OobVertexBuffer: { - const uint32_t index_buffer_offset = error_record[kPreActionParamOffset_0]; - const int32_t vertex_offset = static_cast(error_record[kPreActionParamOffset_1]); - const uint32_t vertex_index = error_record[kPreActionParamOffset_2]; - const uint32_t index_buffer_value = static_cast(int32_t(vertex_index) - vertex_offset); - const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type); - const uint32_t max_indices_in_buffer = - static_cast(index_buffer_binding.size / (index_bits_size / 8u)); - - std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack); - Location loc_with_debug_region(loc, debug_region_name); - skip |= gpuav.LogError( - vuid_oob_vertex, objlist, loc_with_debug_region, - "Vertex index %" PRIu32 - " is not within the smallest bound vertex buffer.\n" - "index_buffer[ %" PRIu32 " ] (%" PRIu32 ") + vertexOffset (%" PRIi32 ") = Vertex index %" PRIu32 - "\n" - - "Smallest vertex buffer binding info, causing OOB access:\n" - "- Buffer: %s\n" - "- Binding: %" PRIu32 - "\n" - "- Binding size (effective): %" PRIu64 - " bytes\n" - "- Binding offset: %" PRIu64 - " bytes\n" - "- Binding stride: %" PRIu64 - " bytes\n" - "- Vertices count: %" PRIu64 - "\n" - - "At least the following vertex attribute caused OOB access:\n" - "- location: %" PRIu32 - "\n" - "- binding: %" PRIu32 - "\n" - "- format: %s\n" - "- offset: %" PRIu32 - " bytes\n" - - "Index buffer binding info:\n" - "- Buffer: %s\n" - "- Index type: %s\n" - "- Binding offset: %" PRIu64 - " bytes\n" - "- Binding size: %" PRIu64 " bytes (or %" PRIu32 - " %s)\n" - - "Note: Vertex buffer binding size is the effective, valid one, based on how the VkBuffer was created and " - "vertex buffer binding parameters. So it can be clamped up to 0 if binding was invalid.\n", - // OOB vertex index info - vertex_index, index_buffer_offset, index_buffer_value, vertex_offset, vertex_index, - - // Vertex buffer binding info - gpuav.FormatHandle(smallest_vertex_buffer_binding.binding_info.buffer).c_str(), - smallest_vertex_buffer_binding.binding, smallest_vertex_buffer_binding.binding_info.effective_size, - smallest_vertex_buffer_binding.binding_info.offset, smallest_vertex_buffer_binding.binding_info.stride, - smallest_vertex_buffer_binding.smallest_vertex_attributes_count, - - // Vertex Attribute info - smallest_vertex_buffer_binding.attribute.location, smallest_vertex_buffer_binding.attribute.binding, - string_VkFormat(smallest_vertex_buffer_binding.attribute.format), - smallest_vertex_buffer_binding.attribute.offset, - - // Index buffer binding info - gpuav.FormatHandle(index_buffer_binding.buffer).c_str(), - string_VkIndexType(index_buffer_binding.index_type), index_buffer_binding.offset, index_buffer_binding.size, - max_indices_in_buffer, string_VkIndexType(index_buffer_binding.index_type)); - break; - } - - default: - assert(false); - return skip; - } - - return skip; - }; - - cb_state.per_command_error_loggers.emplace_back(std::move(error_logger)); -} - struct DrawIndexedIndirectIndexBufferShader { static size_t GetSpirvSize() { return validation_cmd_draw_indexed_indirect_index_buffer_comp_size * sizeof(uint32_t); } static const uint32_t *GetSpirv() { return validation_cmd_draw_indexed_indirect_index_buffer_comp; } @@ -1305,273 +1007,5 @@ void DrawIndexedIndirectIndexBuffer(Validator &gpuav, CommandBuffer &cb_state, c cb_state.per_command_error_loggers.emplace_back(std::move(error_logger)); } -struct DrawIndexedIndirectVertexBufferShader { - static size_t GetSpirvSize() { return validation_cmd_draw_indexed_indirect_vertex_buffer_comp_size * sizeof(uint32_t); } - static const uint32_t *GetSpirv() { return validation_cmd_draw_indexed_indirect_vertex_buffer_comp; } - - static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet; - - glsl::DrawIndexedIndirectVertexBufferPushData push_constants{}; - BoundStorageBuffer draw_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndirectBuffer}; - BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer}; - BoundStorageBuffer index_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndexBuffer}; - - static std::vector GetDescriptorSetLayoutBindings() { - std::vector bindings = { - {gpuav::glsl::kPreDrawBinding_IndirectBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, - nullptr}, - {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, - {gpuav::glsl::kPreDrawBinding_IndexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; - - return bindings; - } - - std::vector GetDescriptorWrites(VkDescriptorSet desc_set) const { - std::vector desc_writes(3); - - desc_writes[0] = vku::InitStructHelper(); - desc_writes[0].dstSet = desc_set; - desc_writes[0].dstBinding = draw_buffer_binding.binding; - desc_writes[0].dstArrayElement = 0; - desc_writes[0].descriptorCount = 1; - desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - desc_writes[0].pBufferInfo = &draw_buffer_binding.info; - - desc_writes[1] = vku::InitStructHelper(); - desc_writes[1].dstSet = desc_set; - desc_writes[1].dstBinding = count_buffer_binding.binding; - desc_writes[1].dstArrayElement = 0; - desc_writes[1].descriptorCount = 1; - desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - desc_writes[1].pBufferInfo = &count_buffer_binding.info; - - desc_writes[2] = vku::InitStructHelper(); - desc_writes[2].dstSet = desc_set; - desc_writes[2].dstBinding = index_buffer_binding.binding; - desc_writes[2].dstArrayElement = 0; - desc_writes[2].descriptorCount = 1; - desc_writes[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - desc_writes[2].pBufferInfo = &index_buffer_binding.info; - - return desc_writes; - } -}; - -void DrawIndexedIndirectVertexBuffer(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer, - VkDeviceSize draw_buffer_offset, uint32_t draw_cmds_byte_stride, uint32_t draw_count, - VkBuffer count_buffer, VkDeviceSize count_buffer_offset, const char *vuid_oob_vertex) { - if (!gpuav.gpuav_settings.validate_index_buffers) { - return; - } - - if (gpuav.enabled_features.robustBufferAccess) { - return; - } - - if (!cb_state.IsPrimary()) { - // TODO Unhandled for now. Potential issues with accessing the right vertex buffers - // in secondary command buffers - return; - } - - if (!cb_state.index_buffer_binding.buffer) { - return; - } - - const std::optional smallest_vertex_buffer_binding = SmallestVertexAttributesCount(cb_state); - if (!smallest_vertex_buffer_binding.has_value()) { - return; - } - - CommandBuffer::ValidationCommandFunc validation_cmd = - [index_buffer_binding = cb_state.index_buffer_binding, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding, - draw_buffer, draw_buffer_offset, draw_cmds_byte_stride, draw_count, count_buffer, count_buffer_offset, - draw_i = cb_state.draw_index, error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()), - loc](Validator &gpuav, CommandBuffer &cb_state) { - SharedDrawValidationResources &shared_draw_validation_resources = - gpuav.shared_resources_manager.Get(gpuav, loc); - if (!shared_draw_validation_resources.valid) return; - ComputeValidationPipeline &validation_pipeline = - gpuav.shared_resources_manager.Get>( - gpuav, loc, cb_state.GetErrorLoggingDescSetLayout()); - if (!validation_pipeline.valid) return; - - const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type); - const uint32_t max_indices_in_buffer = static_cast(index_buffer_binding.size / (index_bits_size / 8u)); - - { - DrawIndexedIndirectVertexBufferShader shader_resources; - if (count_buffer != VK_NULL_HANDLE) { - shader_resources.push_constants.flags |= glsl::kIndexedIndirectDrawFlags_DrawCountFromBuffer; - shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)}; - shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t); - } else { - shader_resources.count_buffer_binding.info = {shared_draw_validation_resources.dummy_buffer.VkHandle(), 0, - VK_WHOLE_SIZE}; - } - - shader_resources.push_constants.index_width = index_bits_size; - shader_resources.push_constants.draw_cmds_stride_dwords = draw_cmds_byte_stride / sizeof(uint32_t); - shader_resources.push_constants.bound_index_buffer_indices_count = max_indices_in_buffer; - shader_resources.push_constants.cpu_draw_count = draw_count; - - shader_resources.push_constants.smallest_vertex_attributes_count = - static_cast(smallest_vertex_buffer_binding.smallest_vertex_attributes_count); - - shader_resources.draw_buffer_binding.info = {draw_buffer, 0, VK_WHOLE_SIZE}; - shader_resources.push_constants.draw_indexed_indirect_cmds_buffer_dwords_offset = - (uint32_t)draw_buffer_offset / sizeof(uint32_t); - shader_resources.index_buffer_binding.info = {index_buffer_binding.buffer, 0, - index_buffer_binding.offset + index_buffer_binding.size}; - shader_resources.push_constants.index_buffer_dwords_offset = - (uint32_t)index_buffer_binding.offset / sizeof(uint32_t); - - validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources); - } - - { - DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline); - - // Dispatch as many draws as there are indices in index buffer. - // Each shader invocation will inspect one index, for all draw commands. - // Shader is in charge of performing validation only for indices within the supplied ranges. - constexpr uint32_t work_group_size = 64; - const uint32_t indices_to_check = max_indices_in_buffer; - const uint32_t work_group_count = - indices_to_check / work_group_size + uint32_t(indices_to_check % work_group_size != 0); - VVL_TracyPlot("gpuav::valcmd::DrawIndexedIndirectVertexBuffer Dispatch size", int64_t(work_group_count)); - DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1); - // synchronize draw buffer validation (read) against subsequent writes - std::array buffer_memory_barriers = {}; - uint32_t buffer_memory_barriers_count = 2; - buffer_memory_barriers[0] = vku::InitStructHelper(); - buffer_memory_barriers[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - buffer_memory_barriers[0].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; - buffer_memory_barriers[0].buffer = draw_buffer; - buffer_memory_barriers[0].offset = draw_buffer_offset; - buffer_memory_barriers[0].size = VK_WHOLE_SIZE; - - buffer_memory_barriers[1] = vku::InitStructHelper(); - buffer_memory_barriers[1].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - buffer_memory_barriers[1].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; - buffer_memory_barriers[1].buffer = index_buffer_binding.buffer; - buffer_memory_barriers[1].offset = index_buffer_binding.offset; - buffer_memory_barriers[1].size = index_buffer_binding.size; - - if (count_buffer) { - buffer_memory_barriers[2] = vku::InitStructHelper(); - buffer_memory_barriers[2].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - buffer_memory_barriers[2].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; - buffer_memory_barriers[2].buffer = count_buffer; - buffer_memory_barriers[2].offset = count_buffer_offset; - buffer_memory_barriers[2].size = sizeof(uint32_t); - ++buffer_memory_barriers_count; - } - - DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, buffer_memory_barriers_count, - buffer_memory_barriers.data(), 0, nullptr); - } - }; - cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd)); - - const uint32_t label_command_i = - !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max; - CommandBuffer::ErrorLoggerFunc error_logger = - [loc, vuid_oob_vertex, draw_buffer, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding, - index_buffer_binding = cb_state.index_buffer_binding, - label_command_i](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record, - const LogObjectList &objlist, const std::vector &initial_label_stack) { - bool skip = false; - - using namespace glsl; - - switch (error_record[kHeaderErrorSubCodeOffset]) { - case kErrorSubCode_OobVertexBuffer: { - const uint32_t draw_i = error_record[kPreActionParamOffset_0]; - const uint32_t index_buffer_offset = error_record[kPreActionParamOffset_1]; - const int32_t vertex_offset = static_cast(error_record[kPreActionParamOffset_2]); - const uint32_t vertex_index = error_record[kPreActionParamOffset_3]; - const uint32_t index_buffer_value = static_cast(int32_t(vertex_index) - vertex_offset); - const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type); - const uint32_t max_indices_in_buffer = - static_cast(index_buffer_binding.size / (index_bits_size / 8u)); - - std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack); - Location loc_with_debug_region(loc, debug_region_name); - skip |= gpuav.LogError( - vuid_oob_vertex, objlist, loc_with_debug_region, - "Vertex index %" PRIu32 - " is not within the smallest bound vertex buffer. Computed from VkDrawIndexedIndirectCommand[ %" PRIu32 - " ], stored in %s.\n" - "index_buffer[ %" PRIu32 " ] (%" PRIu32 ") + vertexOffset (%" PRIi32 ") = Vertex index %" PRIu32 - "\n" - - "Smallest vertex buffer binding info, causing OOB access:\n" - "- Buffer: %s\n" - "- Binding: %" PRIu32 - "\n" - "- Binding size (effective): %" PRIu64 - " bytes\n" - "- Binding offset: %" PRIu64 - " bytes\n" - "- Binding stride: %" PRIu64 - " bytes\n" - "- Vertices count: %" PRIu64 - "\n" - - "At least the following vertex attribute caused OOB access:\n" - "- location: %" PRIu32 - "\n" - "- binding: %" PRIu32 - "\n" - "- format: %s\n" - "- offset: %" PRIu32 - " bytes\n" - - "Index buffer binding info:\n" - "- Buffer: %s\n" - "- Index type: %s\n" - "- Binding offset: %" PRIu64 - " bytes\n" - "- Binding size: %" PRIu64 " bytes (or %" PRIu32 - " %s)\n" - - "Note: Vertex buffer binding size is the effective, valid one, based on how the VkBuffer was created and " - "vertex buffer binding parameters. So it can be clamped up to 0 if binding was invalid.\n", - // OOB vertex index info - vertex_index, draw_i, gpuav.FormatHandle(draw_buffer).c_str(), index_buffer_offset, index_buffer_value, - vertex_offset, vertex_index, - - // Vertex buffer binding info - gpuav.FormatHandle(smallest_vertex_buffer_binding.binding_info.buffer).c_str(), - smallest_vertex_buffer_binding.binding, smallest_vertex_buffer_binding.binding_info.effective_size, - smallest_vertex_buffer_binding.binding_info.offset, smallest_vertex_buffer_binding.binding_info.stride, - smallest_vertex_buffer_binding.smallest_vertex_attributes_count, - - // Vertex Attribute info - smallest_vertex_buffer_binding.attribute.location, smallest_vertex_buffer_binding.attribute.binding, - string_VkFormat(smallest_vertex_buffer_binding.attribute.format), - smallest_vertex_buffer_binding.attribute.offset, - - // Index buffer binding info - gpuav.FormatHandle(index_buffer_binding.buffer).c_str(), - string_VkIndexType(index_buffer_binding.index_type), index_buffer_binding.offset, index_buffer_binding.size, - max_indices_in_buffer, string_VkIndexType(index_buffer_binding.index_type)); - - break; - } - - default: - assert(false); - return skip; - } - - return skip; - }; - - cb_state.per_command_error_loggers.emplace_back(std::move(error_logger)); -} - } // namespace valcmd } // namespace gpuav diff --git a/layers/layer_options.cpp b/layers/layer_options.cpp index 89c92185b87..28b08410989 100644 --- a/layers/layer_options.cpp +++ b/layers/layer_options.cpp @@ -197,6 +197,7 @@ const char *VK_LAYER_GPUAV_VALIDATE_RAY_QUERY = "gpuav_validate_ray_query"; // Post Process are designed to allow the user to "assume" the access is valid and want to know after the GPU executes what // happened. These are much lighter checks and can be used while the rest of GPU-AV is turned off const char *VK_LAYER_GPUAV_POST_PROCESS_DESCRIPTOR_INDEXING = "gpuav_post_process_descriptor_indexing"; +const char *VK_LAYER_GPUAV_VERTEX_ATTRIBUTE_FETCH_OOB = "gpuav_vertex_attribute_fetch_oob"; const char *VK_LAYER_GPUAV_SELECT_INSTRUMENTED_SHADERS = "gpuav_select_instrumented_shaders"; const char *VK_LAYER_GPUAV_BUFFERS_VALIDATION = "gpuav_buffers_validation"; @@ -1045,6 +1046,11 @@ void ProcessConfigAndEnvSettings(ConfigAndEnvSettings *settings_data) { gpuav_settings.shader_instrumentation.post_process_descriptor_index); } + if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_GPUAV_VERTEX_ATTRIBUTE_FETCH_OOB)) { + vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_GPUAV_VERTEX_ATTRIBUTE_FETCH_OOB, + gpuav_settings.shader_instrumentation.vertex_attribute_fetch_oob); + } + if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_GPUAV_WARN_ON_ROBUST_OOB)) { vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_GPUAV_WARN_ON_ROBUST_OOB, gpuav_settings.warn_on_robust_oob); } else if (vkuHasLayerSetting(layer_setting_set, DEPRECATED_GPUAV_WARN_ON_ROBUST_OOB)) { diff --git a/layers/state_tracker/pipeline_state.cpp b/layers/state_tracker/pipeline_state.cpp index e910625304c..e237a0db160 100644 --- a/layers/state_tracker/pipeline_state.cpp +++ b/layers/state_tracker/pipeline_state.cpp @@ -1422,6 +1422,21 @@ std::string DescribePipelineLayoutSetNonCompatible(uint32_t set, const vvl::Pipe return ss.str(); } +const spirv::EntryPoint *LastBound::GetVertexEntryPoint() const { + if (pipeline_state) { + for (const ShaderStageState &shader_stage_state : pipeline_state->stage_states) { + if (shader_stage_state.GetStage() != VK_SHADER_STAGE_VERTEX_BIT) { + continue; + } + return shader_stage_state.entrypoint.get(); + } + return nullptr; + } else if (const auto *shader_object = GetShaderState(ShaderObjectStage::VERTEX)) { + return shader_object->entrypoint.get(); + } + return nullptr; +} + const spirv::EntryPoint *LastBound::GetFragmentEntryPoint() const { if (pipeline_state && pipeline_state->fragment_shader_state) { return pipeline_state->fragment_shader_state->fragment_entry_point.get(); diff --git a/layers/state_tracker/pipeline_state.h b/layers/state_tracker/pipeline_state.h index 7f236be972f..8b992886c56 100644 --- a/layers/state_tracker/pipeline_state.h +++ b/layers/state_tracker/pipeline_state.h @@ -753,6 +753,7 @@ struct LastBound { std::string DescribeNonCompatibleSet(uint32_t set, const vvl::PipelineLayout &pipeline_layout) const; std::string DescribeNonCompatibleSet(uint32_t set, const vvl::ShaderObject &shader_object_state) const; + const spirv::EntryPoint *GetVertexEntryPoint() const; const spirv::EntryPoint *GetFragmentEntryPoint() const; // For GPU-AV diff --git a/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp b/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp new file mode 100644 index 00000000000..0d5f8bdecc6 --- /dev/null +++ b/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.cpp @@ -0,0 +1,131 @@ +// *** THIS FILE IS GENERATED - DO NOT EDIT *** +// See generate_spirv.py for modifications + +/*************************************************************************** + * + * Copyright (c) 2021-2025 The Khronos Group Inc. + * Copyright (c) 2021-2025 Valve Corporation + * Copyright (c) 2021-2025 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include "instrumentation_vertex_attribute_fetch_oob_vert.h" + +// To view SPIR-V, copy contents of array and paste in https://www.khronos.org/spir/visualizer/ +[[maybe_unused]] const uint32_t instrumentation_vertex_attribute_fetch_oob_vert_size = 1017; +[[maybe_unused]] const uint32_t instrumentation_vertex_attribute_fetch_oob_vert[1017] = { + 0x07230203, 0x00010300, 0x0008000b, 0x0000009a, 0x00000000, 0x00020011, 0x00000001, 0x00020011, 0x00000005, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x00030003, 0x00000002, + 0x000001c2, 0x000a0004, 0x475f4c47, 0x4c474f4f, 0x70635f45, 0x74735f70, 0x5f656c79, 0x656e696c, 0x7269645f, 0x69746365, + 0x00006576, 0x00080004, 0x475f4c47, 0x4c474f4f, 0x6e695f45, 0x64756c63, 0x69645f65, 0x74636572, 0x00657669, 0x000c0005, + 0x00000007, 0x74736e69, 0x7265765f, 0x5f786574, 0x72747461, 0x74756269, 0x65665f65, 0x5f686374, 0x28626f6f, 0x3b347576, + 0x00000000, 0x00050005, 0x00000006, 0x67617473, 0x6e695f65, 0x00006f66, 0x000e0005, 0x00000012, 0x696c6176, 0x65765f64, + 0x78657472, 0x7474615f, 0x75626972, 0x665f6574, 0x68637465, 0x7265765f, 0x5f786574, 0x75706e69, 0x61725f74, 0x00006574, + 0x000f0005, 0x00000014, 0x696c6176, 0x65765f64, 0x78657472, 0x7474615f, 0x75626972, 0x665f6574, 0x68637465, 0x736e695f, + 0x636e6174, 0x6e695f65, 0x5f747570, 0x65746172, 0x00000000, 0x00060005, 0x00000015, 0x5678614d, 0x65747265, 0x646e4978, + 0x00007865, 0x000c0006, 0x00000015, 0x00000000, 0x5f736168, 0x6c616d73, 0x7473656c, 0x6262765f, 0x7265765f, 0x5f786574, + 0x75706e69, 0x61725f74, 0x00006574, 0x000b0006, 0x00000015, 0x00000001, 0x6c616d73, 0x7473656c, 0x6262765f, 0x7265765f, + 0x5f786574, 0x75706e69, 0x61725f74, 0x00006574, 0x000d0006, 0x00000015, 0x00000002, 0x5f736168, 0x6c616d73, 0x7473656c, + 0x6262765f, 0x736e695f, 0x636e6174, 0x6e695f65, 0x5f747570, 0x65746172, 0x00000000, 0x000c0006, 0x00000015, 0x00000003, + 0x6c616d73, 0x7473656c, 0x6262765f, 0x736e695f, 0x636e6174, 0x6e695f65, 0x5f747570, 0x65746172, 0x00000000, 0x00030005, + 0x00000017, 0x00000000, 0x00080005, 0x00000039, 0x52646d43, 0x756f7365, 0x49656372, 0x7865646e, 0x66667542, 0x00007265, + 0x00050006, 0x00000039, 0x00000000, 0x65646e69, 0x00000078, 0x000a0005, 0x0000003b, 0x74736e69, 0x646d635f, 0x7365725f, + 0x6372756f, 0x6e695f65, 0x5f786564, 0x66667562, 0x00007265, 0x00080005, 0x00000040, 0x45646d43, 0x726f7272, 0x756f4373, + 0x7542746e, 0x72656666, 0x00000000, 0x00070006, 0x00000040, 0x00000000, 0x6f727265, 0x635f7372, 0x746e756f, 0x00000000, + 0x000a0005, 0x00000042, 0x74736e69, 0x646d635f, 0x7272655f, 0x5f73726f, 0x6e756f63, 0x75625f74, 0x72656666, 0x00000000, + 0x00060005, 0x00000051, 0x7074754f, 0x75427475, 0x72656666, 0x00000000, 0x00050006, 0x00000051, 0x00000000, 0x67616c66, + 0x00000073, 0x00070006, 0x00000051, 0x00000001, 0x74697277, 0x5f6e6574, 0x6e756f63, 0x00000074, 0x00050006, 0x00000051, + 0x00000002, 0x61746164, 0x00000000, 0x00070005, 0x00000053, 0x74736e69, 0x7272655f, 0x5f73726f, 0x66667562, 0x00007265, + 0x00070005, 0x0000008e, 0x69746341, 0x6e496e6f, 0x42786564, 0x65666675, 0x00000072, 0x00050006, 0x0000008e, 0x00000000, + 0x65646e69, 0x00000078, 0x00090005, 0x00000090, 0x74736e69, 0x7463615f, 0x5f6e6f69, 0x65646e69, 0x75625f78, 0x72656666, + 0x00000000, 0x000c0047, 0x00000007, 0x00000029, 0x74736e69, 0x7265765f, 0x5f786574, 0x72747461, 0x74756269, 0x65665f65, + 0x5f686374, 0x00626f6f, 0x00000000, 0x00030047, 0x00000015, 0x00000002, 0x00040048, 0x00000015, 0x00000000, 0x00000018, + 0x00050048, 0x00000015, 0x00000000, 0x00000023, 0x00000000, 0x00040048, 0x00000015, 0x00000001, 0x00000018, 0x00050048, + 0x00000015, 0x00000001, 0x00000023, 0x00000004, 0x00040048, 0x00000015, 0x00000002, 0x00000018, 0x00050048, 0x00000015, + 0x00000002, 0x00000023, 0x00000008, 0x00040048, 0x00000015, 0x00000003, 0x00000018, 0x00050048, 0x00000015, 0x00000003, + 0x00000023, 0x0000000c, 0x00030047, 0x00000017, 0x00000018, 0x00040047, 0x00000017, 0x00000021, 0x00000008, 0x00040047, + 0x00000017, 0x00000022, 0x00000007, 0x00040047, 0x00000038, 0x00000006, 0x00000004, 0x00030047, 0x00000039, 0x00000002, + 0x00050048, 0x00000039, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x0000003b, 0x00000021, 0x00000006, 0x00040047, + 0x0000003b, 0x00000022, 0x00000007, 0x00040047, 0x0000003f, 0x00000006, 0x00000004, 0x00030047, 0x00000040, 0x00000002, + 0x00050048, 0x00000040, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000042, 0x00000021, 0x00000007, 0x00040047, + 0x00000042, 0x00000022, 0x00000007, 0x00040047, 0x00000050, 0x00000006, 0x00000004, 0x00030047, 0x00000051, 0x00000002, + 0x00050048, 0x00000051, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000051, 0x00000001, 0x00000023, 0x00000004, + 0x00050048, 0x00000051, 0x00000002, 0x00000023, 0x00000008, 0x00040047, 0x00000053, 0x00000021, 0x00000001, 0x00040047, + 0x00000053, 0x00000022, 0x00000007, 0x00040047, 0x0000008d, 0x00000006, 0x00000004, 0x00030047, 0x0000008e, 0x00000002, + 0x00050048, 0x0000008e, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000090, 0x00000021, 0x00000005, 0x00040047, + 0x00000090, 0x00000022, 0x00000007, 0x00040015, 0x00000002, 0x00000020, 0x00000000, 0x00040017, 0x00000003, 0x00000002, + 0x00000004, 0x00020013, 0x00000004, 0x00040021, 0x00000005, 0x00000004, 0x00000003, 0x0004002b, 0x00000002, 0x0000000b, + 0x00000001, 0x0004002b, 0x00000002, 0x0000000e, 0x00000002, 0x00020014, 0x00000010, 0x00040020, 0x00000011, 0x00000007, + 0x00000010, 0x00030029, 0x00000010, 0x00000013, 0x0006001e, 0x00000015, 0x00000002, 0x00000002, 0x00000002, 0x00000002, + 0x00040020, 0x00000016, 0x0000000c, 0x00000015, 0x0004003b, 0x00000016, 0x00000017, 0x0000000c, 0x00040015, 0x00000018, + 0x00000020, 0x00000001, 0x0004002b, 0x00000018, 0x00000019, 0x00000000, 0x00040020, 0x0000001a, 0x0000000c, 0x00000002, + 0x0004002b, 0x00000018, 0x00000021, 0x00000001, 0x0004002b, 0x00000018, 0x00000025, 0x00000002, 0x0004002b, 0x00000018, + 0x0000002c, 0x00000003, 0x0003001d, 0x00000038, 0x00000002, 0x0003001e, 0x00000039, 0x00000038, 0x00040020, 0x0000003a, + 0x0000000c, 0x00000039, 0x0004003b, 0x0000003a, 0x0000003b, 0x0000000c, 0x0003001d, 0x0000003f, 0x00000002, 0x0003001e, + 0x00000040, 0x0000003f, 0x00040020, 0x00000041, 0x0000000c, 0x00000040, 0x0004003b, 0x00000041, 0x00000042, 0x0000000c, + 0x0004002b, 0x00000002, 0x00000045, 0x00000000, 0x0004002b, 0x00000002, 0x00000049, 0x00000006, 0x0003001d, 0x00000050, + 0x00000002, 0x0005001e, 0x00000051, 0x00000002, 0x00000002, 0x00000050, 0x00040020, 0x00000052, 0x0000000c, 0x00000051, + 0x0004003b, 0x00000052, 0x00000053, 0x0000000c, 0x0004002b, 0x00000002, 0x00000055, 0x00000010, 0x0004002b, 0x00000002, + 0x00000066, 0x0dead001, 0x0004002b, 0x00000002, 0x0000006c, 0x00000003, 0x0004002b, 0x00000002, 0x00000071, 0x00000004, + 0x0004002b, 0x00000002, 0x00000076, 0x00000005, 0x0004002b, 0x00000002, 0x0000007f, 0x00000009, 0x0004002b, 0x00000002, + 0x00000083, 0x0000000a, 0x0004002b, 0x00000002, 0x0000008b, 0x00000007, 0x0003001d, 0x0000008d, 0x00000002, 0x0003001e, + 0x0000008e, 0x0000008d, 0x00040020, 0x0000008f, 0x0000000c, 0x0000008e, 0x0004003b, 0x0000008f, 0x00000090, 0x0000000c, + 0x0004002b, 0x00000002, 0x00000095, 0x00000008, 0x00050036, 0x00000004, 0x00000007, 0x00000000, 0x00000005, 0x00030037, + 0x00000003, 0x00000006, 0x000200f8, 0x00000008, 0x0004003b, 0x00000011, 0x00000012, 0x00000007, 0x0004003b, 0x00000011, + 0x00000014, 0x00000007, 0x00050051, 0x00000002, 0x0000000c, 0x00000006, 0x00000001, 0x00050051, 0x00000002, 0x0000000f, + 0x00000006, 0x00000002, 0x0003003e, 0x00000012, 0x00000013, 0x0003003e, 0x00000014, 0x00000013, 0x00050041, 0x0000001a, + 0x0000001b, 0x00000017, 0x00000019, 0x0004003d, 0x00000002, 0x0000001c, 0x0000001b, 0x000500aa, 0x00000010, 0x0000001d, + 0x0000001c, 0x0000000b, 0x000300f7, 0x0000001f, 0x00000000, 0x000400fa, 0x0000001d, 0x0000001e, 0x0000001f, 0x000200f8, + 0x0000001e, 0x00050041, 0x0000001a, 0x00000022, 0x00000017, 0x00000021, 0x0004003d, 0x00000002, 0x00000023, 0x00000022, + 0x000500b0, 0x00000010, 0x00000024, 0x0000000c, 0x00000023, 0x0003003e, 0x00000012, 0x00000024, 0x000200f9, 0x0000001f, + 0x000200f8, 0x0000001f, 0x00050041, 0x0000001a, 0x00000026, 0x00000017, 0x00000025, 0x0004003d, 0x00000002, 0x00000027, + 0x00000026, 0x000500aa, 0x00000010, 0x00000028, 0x00000027, 0x0000000b, 0x000300f7, 0x0000002a, 0x00000000, 0x000400fa, + 0x00000028, 0x00000029, 0x0000002a, 0x000200f8, 0x00000029, 0x00050041, 0x0000001a, 0x0000002d, 0x00000017, 0x0000002c, + 0x0004003d, 0x00000002, 0x0000002e, 0x0000002d, 0x000500b0, 0x00000010, 0x0000002f, 0x0000000f, 0x0000002e, 0x0003003e, + 0x00000014, 0x0000002f, 0x000200f9, 0x0000002a, 0x000200f8, 0x0000002a, 0x0004003d, 0x00000010, 0x00000030, 0x00000012, + 0x000400a8, 0x00000010, 0x00000031, 0x00000030, 0x0004003d, 0x00000010, 0x00000032, 0x00000014, 0x000400a8, 0x00000010, + 0x00000033, 0x00000032, 0x000500a6, 0x00000010, 0x00000034, 0x00000031, 0x00000033, 0x000300f7, 0x00000036, 0x00000000, + 0x000400fa, 0x00000034, 0x00000035, 0x00000036, 0x000200f8, 0x00000035, 0x00060041, 0x0000001a, 0x0000003c, 0x0000003b, + 0x00000019, 0x00000019, 0x0004003d, 0x00000002, 0x0000003d, 0x0000003c, 0x00060041, 0x0000001a, 0x00000044, 0x00000042, + 0x00000019, 0x0000003d, 0x000700ea, 0x00000002, 0x00000046, 0x00000044, 0x0000000b, 0x00000045, 0x0000000b, 0x000500ae, + 0x00000010, 0x0000004a, 0x00000046, 0x00000049, 0x000300f7, 0x0000004d, 0x00000000, 0x000400fa, 0x0000004a, 0x0000004c, + 0x0000004d, 0x000200f8, 0x0000004c, 0x000100fd, 0x000200f8, 0x0000004d, 0x00050041, 0x0000001a, 0x00000054, 0x00000053, + 0x00000021, 0x000700ea, 0x00000002, 0x00000056, 0x00000054, 0x0000000b, 0x00000045, 0x00000055, 0x00050080, 0x00000002, + 0x00000059, 0x00000056, 0x00000055, 0x00050044, 0x00000002, 0x0000005a, 0x00000053, 0x00000002, 0x0004007c, 0x00000018, + 0x0000005b, 0x0000005a, 0x0004007c, 0x00000002, 0x0000005c, 0x0000005b, 0x000500b2, 0x00000010, 0x0000005d, 0x00000059, + 0x0000005c, 0x000300f7, 0x00000060, 0x00000000, 0x000400fa, 0x0000005d, 0x0000005f, 0x00000060, 0x000200f8, 0x0000005f, + 0x00060041, 0x0000001a, 0x00000063, 0x00000053, 0x00000025, 0x00000056, 0x0003003e, 0x00000063, 0x00000055, 0x00050080, + 0x00000002, 0x00000065, 0x00000056, 0x0000000b, 0x00060041, 0x0000001a, 0x00000067, 0x00000053, 0x00000025, 0x00000065, + 0x0003003e, 0x00000067, 0x00000066, 0x00050080, 0x00000002, 0x00000069, 0x00000056, 0x0000000e, 0x00060041, 0x0000001a, + 0x0000006a, 0x00000053, 0x00000025, 0x00000069, 0x0003003e, 0x0000006a, 0x00000045, 0x00050080, 0x00000002, 0x0000006d, + 0x00000056, 0x0000006c, 0x00050051, 0x00000002, 0x0000006e, 0x00000006, 0x00000000, 0x00060041, 0x0000001a, 0x0000006f, + 0x00000053, 0x00000025, 0x0000006d, 0x0003003e, 0x0000006f, 0x0000006e, 0x00050080, 0x00000002, 0x00000072, 0x00000056, + 0x00000071, 0x00050051, 0x00000002, 0x00000073, 0x00000006, 0x00000001, 0x00060041, 0x0000001a, 0x00000074, 0x00000053, + 0x00000025, 0x00000072, 0x0003003e, 0x00000074, 0x00000073, 0x00050080, 0x00000002, 0x00000077, 0x00000056, 0x00000076, + 0x00050051, 0x00000002, 0x00000078, 0x00000006, 0x00000002, 0x00060041, 0x0000001a, 0x00000079, 0x00000053, 0x00000025, + 0x00000077, 0x0003003e, 0x00000079, 0x00000078, 0x00050080, 0x00000002, 0x0000007b, 0x00000056, 0x00000049, 0x00050051, + 0x00000002, 0x0000007c, 0x00000006, 0x00000003, 0x00060041, 0x0000001a, 0x0000007d, 0x00000053, 0x00000025, 0x0000007b, + 0x0003003e, 0x0000007d, 0x0000007c, 0x00050080, 0x00000002, 0x00000080, 0x00000056, 0x0000007f, 0x00060041, 0x0000001a, + 0x00000081, 0x00000053, 0x00000025, 0x00000080, 0x0003003e, 0x00000081, 0x0000007f, 0x00050080, 0x00000002, 0x00000084, + 0x00000056, 0x00000083, 0x0004003d, 0x00000010, 0x00000085, 0x00000012, 0x000400a8, 0x00000010, 0x00000086, 0x00000085, + 0x000600a9, 0x00000018, 0x00000087, 0x00000086, 0x00000021, 0x00000025, 0x0004007c, 0x00000002, 0x00000088, 0x00000087, + 0x00060041, 0x0000001a, 0x00000089, 0x00000053, 0x00000025, 0x00000084, 0x0003003e, 0x00000089, 0x00000088, 0x00050080, + 0x00000002, 0x0000008c, 0x00000056, 0x0000008b, 0x00060041, 0x0000001a, 0x00000091, 0x00000090, 0x00000019, 0x00000019, + 0x0004003d, 0x00000002, 0x00000092, 0x00000091, 0x00060041, 0x0000001a, 0x00000093, 0x00000053, 0x00000025, 0x0000008c, + 0x0003003e, 0x00000093, 0x00000092, 0x00050080, 0x00000002, 0x00000096, 0x00000056, 0x00000095, 0x00060041, 0x0000001a, + 0x00000097, 0x0000003b, 0x00000019, 0x00000019, 0x0004003d, 0x00000002, 0x00000098, 0x00000097, 0x00060041, 0x0000001a, + 0x00000099, 0x00000053, 0x00000025, 0x00000096, 0x0003003e, 0x00000099, 0x00000098, 0x000200f9, 0x00000060, 0x000200f8, + 0x00000060, 0x000200f9, 0x00000036, 0x000200f8, 0x00000036, 0x000100fd, 0x00010038, +}; diff --git a/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.h b/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.h new file mode 100644 index 00000000000..5cd1b0fef42 --- /dev/null +++ b/layers/vulkan/generated/instrumentation_vertex_attribute_fetch_oob_vert.h @@ -0,0 +1,30 @@ +// *** THIS FILE IS GENERATED - DO NOT EDIT *** +// See generate_spirv.py for modifications + +/*************************************************************************** + * + * Copyright (c) 2021-2025 The Khronos Group Inc. + * Copyright (c) 2021-2025 Valve Corporation + * Copyright (c) 2021-2025 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#pragma once + +#include + +// To view SPIR-V, copy contents of array and paste in https://www.khronos.org/spir/visualizer/ +extern const uint32_t instrumentation_vertex_attribute_fetch_oob_vert_size; +extern const uint32_t instrumentation_vertex_attribute_fetch_oob_vert[]; diff --git a/layers/vulkan/generated/validation_cmd_trace_rays_rgen.cpp b/layers/vulkan/generated/validation_cmd_trace_rays_rgen.cpp index 8952696b52a..19dbc9b7f59 100644 --- a/layers/vulkan/generated/validation_cmd_trace_rays_rgen.cpp +++ b/layers/vulkan/generated/validation_cmd_trace_rays_rgen.cpp @@ -24,8 +24,8 @@ #include "validation_cmd_trace_rays_rgen.h" // To view SPIR-V, copy contents of array and paste in https://www.khronos.org/spir/visualizer/ -[[maybe_unused]] const uint32_t validation_cmd_trace_rays_rgen_size = 1755; -[[maybe_unused]] const uint32_t validation_cmd_trace_rays_rgen[1755] = { +[[maybe_unused]] const uint32_t validation_cmd_trace_rays_rgen_size = 1740; +[[maybe_unused]] const uint32_t validation_cmd_trace_rays_rgen[1740] = { 0x07230203, 0x00010500, 0x0008000b, 0x000000fb, 0x00000000, 0x00020011, 0x0000000b, 0x00020011, 0x0000117f, 0x00020011, 0x000014e3, 0x0006000a, 0x5f565053, 0x5f52484b, 0x5f796172, 0x63617274, 0x00676e69, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x000014e4, 0x00000001, 0x000a000f, 0x000014c1, 0x00000004, 0x6e69616d, @@ -45,161 +45,159 @@ 0x65646e49, 0x66754278, 0x00726566, 0x00070006, 0x0000001e, 0x00000000, 0x6f736572, 0x65637275, 0x646e695f, 0x00007865, 0x00030005, 0x00000020, 0x00000000, 0x00080005, 0x00000028, 0x45646d43, 0x726f7272, 0x756f4373, 0x7542746e, 0x72656666, 0x00000000, 0x00080006, 0x00000028, 0x00000000, 0x5f646d63, 0x6f727265, 0x635f7372, 0x746e756f, 0x00000000, 0x00030005, - 0x0000002a, 0x00000000, 0x00040005, 0x00000039, 0x695f6f76, 0x00007864, 0x00050005, 0x0000003b, 0x6f727245, 0x66754272, - 0x00726566, 0x00050006, 0x0000003b, 0x00000000, 0x67616c66, 0x00000073, 0x00070006, 0x0000003b, 0x00000001, 0x6f727265, - 0x635f7372, 0x746e756f, 0x00000000, 0x00070006, 0x0000003b, 0x00000002, 0x6f727265, 0x625f7372, 0x65666675, 0x00000072, - 0x00030005, 0x0000003d, 0x00000000, 0x00070005, 0x00000056, 0x69746341, 0x6e496e6f, 0x42786564, 0x65666675, 0x00000072, - 0x00070006, 0x00000056, 0x00000000, 0x69746361, 0x695f6e6f, 0x7865646e, 0x00000000, 0x00030005, 0x00000058, 0x00000000, - 0x00040005, 0x00000080, 0x61726170, 0x0000006d, 0x00040005, 0x00000082, 0x61726170, 0x0000006d, 0x00040005, 0x00000084, - 0x61726170, 0x0000006d, 0x00040005, 0x00000086, 0x61726170, 0x0000006d, 0x00040005, 0x00000088, 0x61726170, 0x0000006d, - 0x00040005, 0x00000089, 0x61726170, 0x0000006d, 0x00060005, 0x0000008c, 0x68737550, 0x736e6f43, 0x746e6174, 0x00000073, - 0x00070006, 0x0000008c, 0x00000000, 0x69646e69, 0x74636572, 0x7461645f, 0x00000061, 0x00090006, 0x0000008c, 0x00000001, - 0x63617274, 0x61725f65, 0x775f7379, 0x68746469, 0x6d696c5f, 0x00007469, 0x00090006, 0x0000008c, 0x00000002, 0x63617274, - 0x61725f65, 0x685f7379, 0x68676965, 0x696c5f74, 0x0074696d, 0x00090006, 0x0000008c, 0x00000003, 0x63617274, 0x61725f65, - 0x645f7379, 0x68747065, 0x6d696c5f, 0x00007469, 0x000c0006, 0x0000008c, 0x00000004, 0x5f78616d, 0x5f796172, 0x70736964, - 0x68637461, 0x766e695f, 0x7461636f, 0x5f6e6f69, 0x6e756f63, 0x00000074, 0x000a0005, 0x0000008d, 0x72546b56, 0x52656361, - 0x49737961, 0x7269646e, 0x43746365, 0x616d6d6f, 0x484b646e, 0x00000052, 0x00050006, 0x0000008d, 0x00000000, 0x74646977, - 0x00000068, 0x00050006, 0x0000008d, 0x00000001, 0x67696568, 0x00007468, 0x00050006, 0x0000008d, 0x00000002, 0x74706564, - 0x00000068, 0x00090005, 0x0000008e, 0x69646e49, 0x74636572, 0x6d6d6f43, 0x52646e61, 0x72656665, 0x65636e65, 0x00000000, - 0x00090006, 0x0000008e, 0x00000000, 0x63617274, 0x61725f65, 0x645f7379, 0x6e656d69, 0x6e6f6973, 0x00000073, 0x00030005, - 0x00000090, 0x00000000, 0x00040005, 0x0000009f, 0x61726170, 0x0000006d, 0x00040005, 0x000000a0, 0x61726170, 0x0000006d, - 0x00040005, 0x000000a1, 0x61726170, 0x0000006d, 0x00040005, 0x000000a4, 0x61726170, 0x0000006d, 0x00040005, 0x000000b2, - 0x61726170, 0x0000006d, 0x00040005, 0x000000b3, 0x61726170, 0x0000006d, 0x00040005, 0x000000b4, 0x61726170, 0x0000006d, - 0x00040005, 0x000000b7, 0x61726170, 0x0000006d, 0x00040005, 0x000000c6, 0x61726170, 0x0000006d, 0x00040005, 0x000000c7, - 0x61726170, 0x0000006d, 0x00040005, 0x000000c8, 0x61726170, 0x0000006d, 0x00040005, 0x000000cb, 0x61726170, 0x0000006d, - 0x00040005, 0x000000ee, 0x61726170, 0x0000006d, 0x00040005, 0x000000ef, 0x61726170, 0x0000006d, 0x00040005, 0x000000f0, - 0x61726170, 0x0000006d, 0x00040005, 0x000000f3, 0x61726170, 0x0000006d, 0x00040005, 0x000000f6, 0x61726170, 0x0000006d, - 0x00040005, 0x000000f9, 0x61726170, 0x0000006d, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00030047, 0x0000001e, - 0x00000002, 0x00040048, 0x0000001e, 0x00000000, 0x00000018, 0x00050048, 0x0000001e, 0x00000000, 0x00000023, 0x00000000, - 0x00030047, 0x00000020, 0x00000018, 0x00040047, 0x00000020, 0x00000021, 0x00000002, 0x00040047, 0x00000020, 0x00000022, - 0x00000000, 0x00040047, 0x00000027, 0x00000006, 0x00000004, 0x00030047, 0x00000028, 0x00000002, 0x00050048, 0x00000028, - 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x0000002a, 0x00000021, 0x00000003, 0x00040047, 0x0000002a, 0x00000022, - 0x00000000, 0x00040047, 0x0000003a, 0x00000006, 0x00000004, 0x00030047, 0x0000003b, 0x00000002, 0x00050048, 0x0000003b, - 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000003b, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000003b, - 0x00000002, 0x00000023, 0x00000008, 0x00040047, 0x0000003d, 0x00000021, 0x00000000, 0x00040047, 0x0000003d, 0x00000022, - 0x00000000, 0x00040047, 0x00000055, 0x00000006, 0x00000004, 0x00030047, 0x00000056, 0x00000002, 0x00040048, 0x00000056, - 0x00000000, 0x00000018, 0x00050048, 0x00000056, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000058, 0x00000018, - 0x00040047, 0x00000058, 0x00000021, 0x00000001, 0x00040047, 0x00000058, 0x00000022, 0x00000000, 0x00030047, 0x0000008c, - 0x00000002, 0x00050048, 0x0000008c, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000008c, 0x00000001, 0x00000023, - 0x00000008, 0x00050048, 0x0000008c, 0x00000002, 0x00000023, 0x0000000c, 0x00050048, 0x0000008c, 0x00000003, 0x00000023, - 0x00000010, 0x00050048, 0x0000008c, 0x00000004, 0x00000023, 0x00000014, 0x00050048, 0x0000008d, 0x00000000, 0x00000023, - 0x00000000, 0x00050048, 0x0000008d, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000008d, 0x00000002, 0x00000023, - 0x00000008, 0x00030047, 0x0000008e, 0x00000002, 0x00050048, 0x0000008e, 0x00000000, 0x00000023, 0x00000000, 0x00020013, - 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00020014, 0x00000006, 0x00030021, 0x00000007, 0x00000006, 0x00040015, - 0x0000000a, 0x00000020, 0x00000000, 0x00040020, 0x0000000b, 0x00000007, 0x0000000a, 0x00090021, 0x0000000c, 0x00000002, - 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, 0x00070021, 0x00000015, 0x00000002, 0x0000000b, - 0x0000000b, 0x0000000b, 0x0000000b, 0x0003001d, 0x0000001d, 0x0000000a, 0x0003001e, 0x0000001e, 0x0000001d, 0x00040020, - 0x0000001f, 0x0000000c, 0x0000001e, 0x0004003b, 0x0000001f, 0x00000020, 0x0000000c, 0x00040015, 0x00000021, 0x00000020, - 0x00000001, 0x0004002b, 0x00000021, 0x00000022, 0x00000000, 0x00040020, 0x00000023, 0x0000000c, 0x0000000a, 0x0003001d, - 0x00000027, 0x0000000a, 0x0003001e, 0x00000028, 0x00000027, 0x00040020, 0x00000029, 0x0000000c, 0x00000028, 0x0004003b, - 0x00000029, 0x0000002a, 0x0000000c, 0x0004002b, 0x0000000a, 0x0000002d, 0x00000001, 0x0004002b, 0x0000000a, 0x0000002e, - 0x00000000, 0x0004002b, 0x0000000a, 0x00000031, 0x00000006, 0x0003001d, 0x0000003a, 0x0000000a, 0x0005001e, 0x0000003b, - 0x0000000a, 0x0000000a, 0x0000003a, 0x00040020, 0x0000003c, 0x0000000c, 0x0000003b, 0x0004003b, 0x0000003c, 0x0000003d, - 0x0000000c, 0x0004002b, 0x00000021, 0x0000003e, 0x00000001, 0x0004002b, 0x0000000a, 0x00000040, 0x00000010, 0x0004002b, - 0x00000021, 0x0000004e, 0x00000002, 0x0004002b, 0x0000000a, 0x00000053, 0x00000007, 0x0003001d, 0x00000055, 0x0000000a, - 0x0003001e, 0x00000056, 0x00000055, 0x00040020, 0x00000057, 0x0000000c, 0x00000056, 0x0004003b, 0x00000057, 0x00000058, - 0x0000000c, 0x0004002b, 0x0000000a, 0x0000005d, 0x00000008, 0x0004002b, 0x0000000a, 0x00000063, 0x00000009, 0x0004002b, - 0x0000000a, 0x00000068, 0x0000000a, 0x0004002b, 0x0000000a, 0x0000006d, 0x0000000b, 0x0004002b, 0x0000000a, 0x00000072, - 0x0000000c, 0x0004002b, 0x0000000a, 0x00000077, 0x0000000d, 0x0004002b, 0x0000000a, 0x0000007c, 0x0000000e, 0x00030027, - 0x0000008b, 0x000014e5, 0x0007001e, 0x0000008c, 0x0000008b, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, 0x0005001e, - 0x0000008d, 0x0000000a, 0x0000000a, 0x0000000a, 0x0003001e, 0x0000008e, 0x0000008d, 0x00040020, 0x0000008b, 0x000014e5, - 0x0000008e, 0x00040020, 0x0000008f, 0x00000009, 0x0000008c, 0x0004003b, 0x0000008f, 0x00000090, 0x00000009, 0x00040020, - 0x00000091, 0x00000009, 0x0000008b, 0x00040020, 0x00000094, 0x000014e5, 0x0000000a, 0x00040020, 0x00000097, 0x00000009, - 0x0000000a, 0x0004002b, 0x0000000a, 0x000000af, 0x00000002, 0x0004002b, 0x00000021, 0x000000bd, 0x00000003, 0x0004002b, - 0x0000000a, 0x000000c3, 0x00000003, 0x00040015, 0x000000cd, 0x00000040, 0x00000000, 0x0004002b, 0x00000021, 0x000000e0, - 0x00000004, 0x0004002b, 0x0000000a, 0x000000e7, 0x00000004, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, - 0x000200f8, 0x00000005, 0x0004003b, 0x0000000b, 0x0000009f, 0x00000007, 0x0004003b, 0x0000000b, 0x000000a0, 0x00000007, - 0x0004003b, 0x0000000b, 0x000000a1, 0x00000007, 0x0004003b, 0x0000000b, 0x000000a4, 0x00000007, 0x0004003b, 0x0000000b, - 0x000000b2, 0x00000007, 0x0004003b, 0x0000000b, 0x000000b3, 0x00000007, 0x0004003b, 0x0000000b, 0x000000b4, 0x00000007, - 0x0004003b, 0x0000000b, 0x000000b7, 0x00000007, 0x0004003b, 0x0000000b, 0x000000c6, 0x00000007, 0x0004003b, 0x0000000b, - 0x000000c7, 0x00000007, 0x0004003b, 0x0000000b, 0x000000c8, 0x00000007, 0x0004003b, 0x0000000b, 0x000000cb, 0x00000007, - 0x0004003b, 0x0000000b, 0x000000ee, 0x00000007, 0x0004003b, 0x0000000b, 0x000000ef, 0x00000007, 0x0004003b, 0x0000000b, - 0x000000f0, 0x00000007, 0x0004003b, 0x0000000b, 0x000000f3, 0x00000007, 0x0004003b, 0x0000000b, 0x000000f6, 0x00000007, - 0x0004003b, 0x0000000b, 0x000000f9, 0x00000007, 0x00050041, 0x00000091, 0x00000092, 0x00000090, 0x00000022, 0x0004003d, - 0x0000008b, 0x00000093, 0x00000092, 0x00060041, 0x00000094, 0x00000095, 0x00000093, 0x00000022, 0x00000022, 0x0006003d, - 0x0000000a, 0x00000096, 0x00000095, 0x00000002, 0x00000010, 0x00050041, 0x00000097, 0x00000098, 0x00000090, 0x0000003e, - 0x0004003d, 0x0000000a, 0x00000099, 0x00000098, 0x000500ac, 0x00000006, 0x0000009a, 0x00000096, 0x00000099, 0x000300f7, - 0x0000009c, 0x00000000, 0x000400fa, 0x0000009a, 0x0000009b, 0x0000009c, 0x000200f8, 0x0000009b, 0x00050041, 0x00000091, - 0x0000009d, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x0000009e, 0x0000009d, 0x0003003e, 0x0000009f, 0x00000031, - 0x0003003e, 0x000000a0, 0x0000002d, 0x00060041, 0x00000094, 0x000000a2, 0x0000009e, 0x00000022, 0x00000022, 0x0006003d, - 0x0000000a, 0x000000a3, 0x000000a2, 0x00000002, 0x00000010, 0x0003003e, 0x000000a1, 0x000000a3, 0x0003003e, 0x000000a4, - 0x0000002e, 0x00080039, 0x00000002, 0x000000a5, 0x0000001a, 0x0000009f, 0x000000a0, 0x000000a1, 0x000000a4, 0x000200f9, - 0x0000009c, 0x000200f8, 0x0000009c, 0x00050041, 0x00000091, 0x000000a6, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, - 0x000000a7, 0x000000a6, 0x00060041, 0x00000094, 0x000000a8, 0x000000a7, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, - 0x000000a9, 0x000000a8, 0x00000002, 0x00000004, 0x00050041, 0x00000097, 0x000000aa, 0x00000090, 0x0000004e, 0x0004003d, - 0x0000000a, 0x000000ab, 0x000000aa, 0x000500ac, 0x00000006, 0x000000ac, 0x000000a9, 0x000000ab, 0x000300f7, 0x000000ae, - 0x00000000, 0x000400fa, 0x000000ac, 0x000000ad, 0x000000ae, 0x000200f8, 0x000000ad, 0x00050041, 0x00000091, 0x000000b0, - 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000b1, 0x000000b0, 0x0003003e, 0x000000b2, 0x00000031, 0x0003003e, - 0x000000b3, 0x000000af, 0x00060041, 0x00000094, 0x000000b5, 0x000000b1, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, - 0x000000b6, 0x000000b5, 0x00000002, 0x00000004, 0x0003003e, 0x000000b4, 0x000000b6, 0x0003003e, 0x000000b7, 0x0000002e, - 0x00080039, 0x00000002, 0x000000b8, 0x0000001a, 0x000000b2, 0x000000b3, 0x000000b4, 0x000000b7, 0x000200f9, 0x000000ae, - 0x000200f8, 0x000000ae, 0x00050041, 0x00000091, 0x000000b9, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000ba, - 0x000000b9, 0x00060041, 0x00000094, 0x000000bb, 0x000000ba, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000bc, - 0x000000bb, 0x00000002, 0x00000008, 0x00050041, 0x00000097, 0x000000be, 0x00000090, 0x000000bd, 0x0004003d, 0x0000000a, - 0x000000bf, 0x000000be, 0x000500ac, 0x00000006, 0x000000c0, 0x000000bc, 0x000000bf, 0x000300f7, 0x000000c2, 0x00000000, - 0x000400fa, 0x000000c0, 0x000000c1, 0x000000c2, 0x000200f8, 0x000000c1, 0x00050041, 0x00000091, 0x000000c4, 0x00000090, - 0x00000022, 0x0004003d, 0x0000008b, 0x000000c5, 0x000000c4, 0x0003003e, 0x000000c6, 0x00000031, 0x0003003e, 0x000000c7, - 0x000000c3, 0x00060041, 0x00000094, 0x000000c9, 0x000000c5, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000ca, - 0x000000c9, 0x00000002, 0x00000008, 0x0003003e, 0x000000c8, 0x000000ca, 0x0003003e, 0x000000cb, 0x0000002e, 0x00080039, - 0x00000002, 0x000000cc, 0x0000001a, 0x000000c6, 0x000000c7, 0x000000c8, 0x000000cb, 0x000200f9, 0x000000c2, 0x000200f8, - 0x000000c2, 0x00050041, 0x00000091, 0x000000d0, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000d1, 0x000000d0, - 0x00060041, 0x00000094, 0x000000d2, 0x000000d1, 0x00000022, 0x00000022, 0x0006003d, 0x0000000a, 0x000000d3, 0x000000d2, - 0x00000002, 0x00000010, 0x00050041, 0x00000091, 0x000000d4, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000d5, - 0x000000d4, 0x00060041, 0x00000094, 0x000000d6, 0x000000d5, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, 0x000000d7, - 0x000000d6, 0x00000002, 0x00000004, 0x00050084, 0x0000000a, 0x000000d8, 0x000000d3, 0x000000d7, 0x00050041, 0x00000091, - 0x000000d9, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000da, 0x000000d9, 0x00060041, 0x00000094, 0x000000db, - 0x000000da, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000dc, 0x000000db, 0x00000002, 0x00000008, 0x00050084, - 0x0000000a, 0x000000dd, 0x000000d8, 0x000000dc, 0x00040071, 0x000000cd, 0x000000de, 0x000000dd, 0x00050041, 0x00000097, - 0x000000e1, 0x00000090, 0x000000e0, 0x0004003d, 0x0000000a, 0x000000e2, 0x000000e1, 0x00040071, 0x000000cd, 0x000000e3, - 0x000000e2, 0x000500ac, 0x00000006, 0x000000e4, 0x000000de, 0x000000e3, 0x000300f7, 0x000000e6, 0x00000000, 0x000400fa, - 0x000000e4, 0x000000e5, 0x000000e6, 0x000200f8, 0x000000e5, 0x00050041, 0x00000091, 0x000000e8, 0x00000090, 0x00000022, - 0x0004003d, 0x0000008b, 0x000000e9, 0x000000e8, 0x00050041, 0x00000091, 0x000000ea, 0x00000090, 0x00000022, 0x0004003d, - 0x0000008b, 0x000000eb, 0x000000ea, 0x00050041, 0x00000091, 0x000000ec, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, - 0x000000ed, 0x000000ec, 0x0003003e, 0x000000ee, 0x00000031, 0x0003003e, 0x000000ef, 0x000000e7, 0x00060041, 0x00000094, - 0x000000f1, 0x000000e9, 0x00000022, 0x00000022, 0x0006003d, 0x0000000a, 0x000000f2, 0x000000f1, 0x00000002, 0x00000010, - 0x0003003e, 0x000000f0, 0x000000f2, 0x00060041, 0x00000094, 0x000000f4, 0x000000eb, 0x00000022, 0x0000003e, 0x0006003d, - 0x0000000a, 0x000000f5, 0x000000f4, 0x00000002, 0x00000004, 0x0003003e, 0x000000f3, 0x000000f5, 0x00060041, 0x00000094, - 0x000000f7, 0x000000ed, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000f8, 0x000000f7, 0x00000002, 0x00000008, - 0x0003003e, 0x000000f6, 0x000000f8, 0x0003003e, 0x000000f9, 0x0000002e, 0x000a0039, 0x00000002, 0x000000fa, 0x00000013, - 0x000000ee, 0x000000ef, 0x000000f0, 0x000000f3, 0x000000f6, 0x000000f9, 0x000200f9, 0x000000e6, 0x000200f8, 0x000000e6, - 0x000100fd, 0x00010038, 0x00050036, 0x00000006, 0x00000008, 0x00000000, 0x00000007, 0x000200f8, 0x00000009, 0x00060041, - 0x00000023, 0x00000024, 0x00000020, 0x00000022, 0x00000022, 0x0004003d, 0x0000000a, 0x00000025, 0x00000024, 0x00060041, - 0x00000023, 0x0000002c, 0x0000002a, 0x00000022, 0x00000025, 0x000700ea, 0x0000000a, 0x0000002f, 0x0000002c, 0x0000002d, - 0x0000002e, 0x0000002d, 0x000500ae, 0x00000006, 0x00000032, 0x0000002f, 0x00000031, 0x000200fe, 0x00000032, 0x00010038, - 0x00050036, 0x00000002, 0x00000013, 0x00000000, 0x0000000c, 0x00030037, 0x0000000b, 0x0000000d, 0x00030037, 0x0000000b, - 0x0000000e, 0x00030037, 0x0000000b, 0x0000000f, 0x00030037, 0x0000000b, 0x00000010, 0x00030037, 0x0000000b, 0x00000011, - 0x00030037, 0x0000000b, 0x00000012, 0x000200f8, 0x00000014, 0x0004003b, 0x0000000b, 0x00000039, 0x00000007, 0x00040039, - 0x00000006, 0x00000035, 0x00000008, 0x000300f7, 0x00000037, 0x00000000, 0x000400fa, 0x00000035, 0x00000036, 0x00000037, - 0x000200f8, 0x00000036, 0x000100fd, 0x000200f8, 0x00000037, 0x00050041, 0x00000023, 0x0000003f, 0x0000003d, 0x0000003e, - 0x000700ea, 0x0000000a, 0x00000041, 0x0000003f, 0x0000002d, 0x0000002e, 0x00000040, 0x0003003e, 0x00000039, 0x00000041, - 0x00050080, 0x0000000a, 0x00000045, 0x00000041, 0x00000040, 0x00050044, 0x0000000a, 0x00000046, 0x0000003d, 0x00000002, - 0x0004007c, 0x00000021, 0x00000047, 0x00000046, 0x0004007c, 0x0000000a, 0x00000048, 0x00000047, 0x000500ac, 0x00000006, - 0x00000049, 0x00000045, 0x00000048, 0x000300f7, 0x0000004c, 0x00000000, 0x000400fa, 0x00000049, 0x0000004b, 0x0000004c, - 0x000200f8, 0x0000004b, 0x000100fd, 0x000200f8, 0x0000004c, 0x0004003d, 0x0000000a, 0x0000004f, 0x00000039, 0x00060041, - 0x00000023, 0x00000051, 0x0000003d, 0x0000004e, 0x0000004f, 0x0003003e, 0x00000051, 0x00000040, 0x00050080, 0x0000000a, - 0x00000054, 0x0000004f, 0x00000053, 0x00060041, 0x00000023, 0x00000059, 0x00000058, 0x00000022, 0x00000022, 0x0004003d, - 0x0000000a, 0x0000005a, 0x00000059, 0x00060041, 0x00000023, 0x0000005b, 0x0000003d, 0x0000004e, 0x00000054, 0x0003003e, - 0x0000005b, 0x0000005a, 0x00050080, 0x0000000a, 0x0000005e, 0x0000004f, 0x0000005d, 0x00060041, 0x00000023, 0x0000005f, - 0x00000020, 0x00000022, 0x00000022, 0x0004003d, 0x0000000a, 0x00000060, 0x0000005f, 0x00060041, 0x00000023, 0x00000061, - 0x0000003d, 0x0000004e, 0x0000005e, 0x0003003e, 0x00000061, 0x00000060, 0x00050080, 0x0000000a, 0x00000064, 0x0000004f, - 0x00000063, 0x0004003d, 0x0000000a, 0x00000065, 0x0000000d, 0x00060041, 0x00000023, 0x00000066, 0x0000003d, 0x0000004e, - 0x00000064, 0x0003003e, 0x00000066, 0x00000065, 0x00050080, 0x0000000a, 0x00000069, 0x0000004f, 0x00000068, 0x0004003d, - 0x0000000a, 0x0000006a, 0x0000000e, 0x00060041, 0x00000023, 0x0000006b, 0x0000003d, 0x0000004e, 0x00000069, 0x0003003e, - 0x0000006b, 0x0000006a, 0x00050080, 0x0000000a, 0x0000006e, 0x0000004f, 0x0000006d, 0x0004003d, 0x0000000a, 0x0000006f, - 0x0000000f, 0x00060041, 0x00000023, 0x00000070, 0x0000003d, 0x0000004e, 0x0000006e, 0x0003003e, 0x00000070, 0x0000006f, - 0x00050080, 0x0000000a, 0x00000073, 0x0000004f, 0x00000072, 0x0004003d, 0x0000000a, 0x00000074, 0x00000010, 0x00060041, - 0x00000023, 0x00000075, 0x0000003d, 0x0000004e, 0x00000073, 0x0003003e, 0x00000075, 0x00000074, 0x00050080, 0x0000000a, - 0x00000078, 0x0000004f, 0x00000077, 0x0004003d, 0x0000000a, 0x00000079, 0x00000011, 0x00060041, 0x00000023, 0x0000007a, - 0x0000003d, 0x0000004e, 0x00000078, 0x0003003e, 0x0000007a, 0x00000079, 0x00050080, 0x0000000a, 0x0000007d, 0x0000004f, - 0x0000007c, 0x0004003d, 0x0000000a, 0x0000007e, 0x00000012, 0x00060041, 0x00000023, 0x0000007f, 0x0000003d, 0x0000004e, - 0x0000007d, 0x0003003e, 0x0000007f, 0x0000007e, 0x000100fd, 0x00010038, 0x00050036, 0x00000002, 0x0000001a, 0x00000000, - 0x00000015, 0x00030037, 0x0000000b, 0x00000016, 0x00030037, 0x0000000b, 0x00000017, 0x00030037, 0x0000000b, 0x00000018, - 0x00030037, 0x0000000b, 0x00000019, 0x000200f8, 0x0000001b, 0x0004003b, 0x0000000b, 0x00000080, 0x00000007, 0x0004003b, - 0x0000000b, 0x00000082, 0x00000007, 0x0004003b, 0x0000000b, 0x00000084, 0x00000007, 0x0004003b, 0x0000000b, 0x00000086, - 0x00000007, 0x0004003b, 0x0000000b, 0x00000088, 0x00000007, 0x0004003b, 0x0000000b, 0x00000089, 0x00000007, 0x0004003d, - 0x0000000a, 0x00000081, 0x00000016, 0x0003003e, 0x00000080, 0x00000081, 0x0004003d, 0x0000000a, 0x00000083, 0x00000017, - 0x0003003e, 0x00000082, 0x00000083, 0x0004003d, 0x0000000a, 0x00000085, 0x00000018, 0x0003003e, 0x00000084, 0x00000085, - 0x0004003d, 0x0000000a, 0x00000087, 0x00000019, 0x0003003e, 0x00000086, 0x00000087, 0x0003003e, 0x00000088, 0x0000002e, - 0x0003003e, 0x00000089, 0x0000002e, 0x000a0039, 0x00000002, 0x0000008a, 0x00000013, 0x00000080, 0x00000082, 0x00000084, - 0x00000086, 0x00000088, 0x00000089, 0x000100fd, 0x00010038, + 0x0000002a, 0x00000000, 0x00050005, 0x0000003b, 0x6f727245, 0x66754272, 0x00726566, 0x00050006, 0x0000003b, 0x00000000, + 0x67616c66, 0x00000073, 0x00070006, 0x0000003b, 0x00000001, 0x6f727265, 0x635f7372, 0x746e756f, 0x00000000, 0x00070006, + 0x0000003b, 0x00000002, 0x6f727265, 0x625f7372, 0x65666675, 0x00000072, 0x00030005, 0x0000003d, 0x00000000, 0x00070005, + 0x00000056, 0x69746341, 0x6e496e6f, 0x42786564, 0x65666675, 0x00000072, 0x00070006, 0x00000056, 0x00000000, 0x69746361, + 0x695f6e6f, 0x7865646e, 0x00000000, 0x00030005, 0x00000058, 0x00000000, 0x00040005, 0x00000080, 0x61726170, 0x0000006d, + 0x00040005, 0x00000082, 0x61726170, 0x0000006d, 0x00040005, 0x00000084, 0x61726170, 0x0000006d, 0x00040005, 0x00000086, + 0x61726170, 0x0000006d, 0x00040005, 0x00000088, 0x61726170, 0x0000006d, 0x00040005, 0x00000089, 0x61726170, 0x0000006d, + 0x00060005, 0x0000008c, 0x68737550, 0x736e6f43, 0x746e6174, 0x00000073, 0x00070006, 0x0000008c, 0x00000000, 0x69646e69, + 0x74636572, 0x7461645f, 0x00000061, 0x00090006, 0x0000008c, 0x00000001, 0x63617274, 0x61725f65, 0x775f7379, 0x68746469, + 0x6d696c5f, 0x00007469, 0x00090006, 0x0000008c, 0x00000002, 0x63617274, 0x61725f65, 0x685f7379, 0x68676965, 0x696c5f74, + 0x0074696d, 0x00090006, 0x0000008c, 0x00000003, 0x63617274, 0x61725f65, 0x645f7379, 0x68747065, 0x6d696c5f, 0x00007469, + 0x000c0006, 0x0000008c, 0x00000004, 0x5f78616d, 0x5f796172, 0x70736964, 0x68637461, 0x766e695f, 0x7461636f, 0x5f6e6f69, + 0x6e756f63, 0x00000074, 0x000a0005, 0x0000008d, 0x72546b56, 0x52656361, 0x49737961, 0x7269646e, 0x43746365, 0x616d6d6f, + 0x484b646e, 0x00000052, 0x00050006, 0x0000008d, 0x00000000, 0x74646977, 0x00000068, 0x00050006, 0x0000008d, 0x00000001, + 0x67696568, 0x00007468, 0x00050006, 0x0000008d, 0x00000002, 0x74706564, 0x00000068, 0x00090005, 0x0000008e, 0x69646e49, + 0x74636572, 0x6d6d6f43, 0x52646e61, 0x72656665, 0x65636e65, 0x00000000, 0x00090006, 0x0000008e, 0x00000000, 0x63617274, + 0x61725f65, 0x645f7379, 0x6e656d69, 0x6e6f6973, 0x00000073, 0x00030005, 0x00000090, 0x00000000, 0x00040005, 0x0000009f, + 0x61726170, 0x0000006d, 0x00040005, 0x000000a0, 0x61726170, 0x0000006d, 0x00040005, 0x000000a1, 0x61726170, 0x0000006d, + 0x00040005, 0x000000a4, 0x61726170, 0x0000006d, 0x00040005, 0x000000b2, 0x61726170, 0x0000006d, 0x00040005, 0x000000b3, + 0x61726170, 0x0000006d, 0x00040005, 0x000000b4, 0x61726170, 0x0000006d, 0x00040005, 0x000000b7, 0x61726170, 0x0000006d, + 0x00040005, 0x000000c6, 0x61726170, 0x0000006d, 0x00040005, 0x000000c7, 0x61726170, 0x0000006d, 0x00040005, 0x000000c8, + 0x61726170, 0x0000006d, 0x00040005, 0x000000cb, 0x61726170, 0x0000006d, 0x00040005, 0x000000ee, 0x61726170, 0x0000006d, + 0x00040005, 0x000000ef, 0x61726170, 0x0000006d, 0x00040005, 0x000000f0, 0x61726170, 0x0000006d, 0x00040005, 0x000000f3, + 0x61726170, 0x0000006d, 0x00040005, 0x000000f6, 0x61726170, 0x0000006d, 0x00040005, 0x000000f9, 0x61726170, 0x0000006d, + 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00030047, 0x0000001e, 0x00000002, 0x00040048, 0x0000001e, 0x00000000, + 0x00000018, 0x00050048, 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000018, 0x00040047, + 0x00000020, 0x00000021, 0x00000002, 0x00040047, 0x00000020, 0x00000022, 0x00000000, 0x00040047, 0x00000027, 0x00000006, + 0x00000004, 0x00030047, 0x00000028, 0x00000002, 0x00050048, 0x00000028, 0x00000000, 0x00000023, 0x00000000, 0x00040047, + 0x0000002a, 0x00000021, 0x00000003, 0x00040047, 0x0000002a, 0x00000022, 0x00000000, 0x00040047, 0x0000003a, 0x00000006, + 0x00000004, 0x00030047, 0x0000003b, 0x00000002, 0x00050048, 0x0000003b, 0x00000000, 0x00000023, 0x00000000, 0x00050048, + 0x0000003b, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x0000003b, 0x00000002, 0x00000023, 0x00000008, 0x00040047, + 0x0000003d, 0x00000021, 0x00000000, 0x00040047, 0x0000003d, 0x00000022, 0x00000000, 0x00040047, 0x00000055, 0x00000006, + 0x00000004, 0x00030047, 0x00000056, 0x00000002, 0x00040048, 0x00000056, 0x00000000, 0x00000018, 0x00050048, 0x00000056, + 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000058, 0x00000018, 0x00040047, 0x00000058, 0x00000021, 0x00000001, + 0x00040047, 0x00000058, 0x00000022, 0x00000000, 0x00030047, 0x0000008c, 0x00000002, 0x00050048, 0x0000008c, 0x00000000, + 0x00000023, 0x00000000, 0x00050048, 0x0000008c, 0x00000001, 0x00000023, 0x00000008, 0x00050048, 0x0000008c, 0x00000002, + 0x00000023, 0x0000000c, 0x00050048, 0x0000008c, 0x00000003, 0x00000023, 0x00000010, 0x00050048, 0x0000008c, 0x00000004, + 0x00000023, 0x00000014, 0x00050048, 0x0000008d, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000008d, 0x00000001, + 0x00000023, 0x00000004, 0x00050048, 0x0000008d, 0x00000002, 0x00000023, 0x00000008, 0x00030047, 0x0000008e, 0x00000002, + 0x00050048, 0x0000008e, 0x00000000, 0x00000023, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, + 0x00020014, 0x00000006, 0x00030021, 0x00000007, 0x00000006, 0x00040015, 0x0000000a, 0x00000020, 0x00000000, 0x00040020, + 0x0000000b, 0x00000007, 0x0000000a, 0x00090021, 0x0000000c, 0x00000002, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, + 0x0000000b, 0x0000000b, 0x00070021, 0x00000015, 0x00000002, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, 0x0003001d, + 0x0000001d, 0x0000000a, 0x0003001e, 0x0000001e, 0x0000001d, 0x00040020, 0x0000001f, 0x0000000c, 0x0000001e, 0x0004003b, + 0x0000001f, 0x00000020, 0x0000000c, 0x00040015, 0x00000021, 0x00000020, 0x00000001, 0x0004002b, 0x00000021, 0x00000022, + 0x00000000, 0x00040020, 0x00000023, 0x0000000c, 0x0000000a, 0x0003001d, 0x00000027, 0x0000000a, 0x0003001e, 0x00000028, + 0x00000027, 0x00040020, 0x00000029, 0x0000000c, 0x00000028, 0x0004003b, 0x00000029, 0x0000002a, 0x0000000c, 0x0004002b, + 0x0000000a, 0x0000002d, 0x00000001, 0x0004002b, 0x0000000a, 0x0000002e, 0x00000000, 0x0004002b, 0x0000000a, 0x00000031, + 0x00000006, 0x0003001d, 0x0000003a, 0x0000000a, 0x0005001e, 0x0000003b, 0x0000000a, 0x0000000a, 0x0000003a, 0x00040020, + 0x0000003c, 0x0000000c, 0x0000003b, 0x0004003b, 0x0000003c, 0x0000003d, 0x0000000c, 0x0004002b, 0x00000021, 0x0000003e, + 0x00000001, 0x0004002b, 0x0000000a, 0x00000040, 0x00000010, 0x0004002b, 0x00000021, 0x0000004e, 0x00000002, 0x0004002b, + 0x0000000a, 0x00000053, 0x00000007, 0x0003001d, 0x00000055, 0x0000000a, 0x0003001e, 0x00000056, 0x00000055, 0x00040020, + 0x00000057, 0x0000000c, 0x00000056, 0x0004003b, 0x00000057, 0x00000058, 0x0000000c, 0x0004002b, 0x0000000a, 0x0000005d, + 0x00000008, 0x0004002b, 0x0000000a, 0x00000063, 0x00000009, 0x0004002b, 0x0000000a, 0x00000068, 0x0000000a, 0x0004002b, + 0x0000000a, 0x0000006d, 0x0000000b, 0x0004002b, 0x0000000a, 0x00000072, 0x0000000c, 0x0004002b, 0x0000000a, 0x00000077, + 0x0000000d, 0x0004002b, 0x0000000a, 0x0000007c, 0x0000000e, 0x00030027, 0x0000008b, 0x000014e5, 0x0007001e, 0x0000008c, + 0x0000008b, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, 0x0005001e, 0x0000008d, 0x0000000a, 0x0000000a, 0x0000000a, + 0x0003001e, 0x0000008e, 0x0000008d, 0x00040020, 0x0000008b, 0x000014e5, 0x0000008e, 0x00040020, 0x0000008f, 0x00000009, + 0x0000008c, 0x0004003b, 0x0000008f, 0x00000090, 0x00000009, 0x00040020, 0x00000091, 0x00000009, 0x0000008b, 0x00040020, + 0x00000094, 0x000014e5, 0x0000000a, 0x00040020, 0x00000097, 0x00000009, 0x0000000a, 0x0004002b, 0x0000000a, 0x000000af, + 0x00000002, 0x0004002b, 0x00000021, 0x000000bd, 0x00000003, 0x0004002b, 0x0000000a, 0x000000c3, 0x00000003, 0x00040015, + 0x000000cd, 0x00000040, 0x00000000, 0x0004002b, 0x00000021, 0x000000e0, 0x00000004, 0x0004002b, 0x0000000a, 0x000000e7, + 0x00000004, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x0000000b, + 0x0000009f, 0x00000007, 0x0004003b, 0x0000000b, 0x000000a0, 0x00000007, 0x0004003b, 0x0000000b, 0x000000a1, 0x00000007, + 0x0004003b, 0x0000000b, 0x000000a4, 0x00000007, 0x0004003b, 0x0000000b, 0x000000b2, 0x00000007, 0x0004003b, 0x0000000b, + 0x000000b3, 0x00000007, 0x0004003b, 0x0000000b, 0x000000b4, 0x00000007, 0x0004003b, 0x0000000b, 0x000000b7, 0x00000007, + 0x0004003b, 0x0000000b, 0x000000c6, 0x00000007, 0x0004003b, 0x0000000b, 0x000000c7, 0x00000007, 0x0004003b, 0x0000000b, + 0x000000c8, 0x00000007, 0x0004003b, 0x0000000b, 0x000000cb, 0x00000007, 0x0004003b, 0x0000000b, 0x000000ee, 0x00000007, + 0x0004003b, 0x0000000b, 0x000000ef, 0x00000007, 0x0004003b, 0x0000000b, 0x000000f0, 0x00000007, 0x0004003b, 0x0000000b, + 0x000000f3, 0x00000007, 0x0004003b, 0x0000000b, 0x000000f6, 0x00000007, 0x0004003b, 0x0000000b, 0x000000f9, 0x00000007, + 0x00050041, 0x00000091, 0x00000092, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x00000093, 0x00000092, 0x00060041, + 0x00000094, 0x00000095, 0x00000093, 0x00000022, 0x00000022, 0x0006003d, 0x0000000a, 0x00000096, 0x00000095, 0x00000002, + 0x00000010, 0x00050041, 0x00000097, 0x00000098, 0x00000090, 0x0000003e, 0x0004003d, 0x0000000a, 0x00000099, 0x00000098, + 0x000500ac, 0x00000006, 0x0000009a, 0x00000096, 0x00000099, 0x000300f7, 0x0000009c, 0x00000000, 0x000400fa, 0x0000009a, + 0x0000009b, 0x0000009c, 0x000200f8, 0x0000009b, 0x00050041, 0x00000091, 0x0000009d, 0x00000090, 0x00000022, 0x0004003d, + 0x0000008b, 0x0000009e, 0x0000009d, 0x0003003e, 0x0000009f, 0x00000031, 0x0003003e, 0x000000a0, 0x0000002d, 0x00060041, + 0x00000094, 0x000000a2, 0x0000009e, 0x00000022, 0x00000022, 0x0006003d, 0x0000000a, 0x000000a3, 0x000000a2, 0x00000002, + 0x00000010, 0x0003003e, 0x000000a1, 0x000000a3, 0x0003003e, 0x000000a4, 0x0000002e, 0x00080039, 0x00000002, 0x000000a5, + 0x0000001a, 0x0000009f, 0x000000a0, 0x000000a1, 0x000000a4, 0x000200f9, 0x0000009c, 0x000200f8, 0x0000009c, 0x00050041, + 0x00000091, 0x000000a6, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000a7, 0x000000a6, 0x00060041, 0x00000094, + 0x000000a8, 0x000000a7, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, 0x000000a9, 0x000000a8, 0x00000002, 0x00000004, + 0x00050041, 0x00000097, 0x000000aa, 0x00000090, 0x0000004e, 0x0004003d, 0x0000000a, 0x000000ab, 0x000000aa, 0x000500ac, + 0x00000006, 0x000000ac, 0x000000a9, 0x000000ab, 0x000300f7, 0x000000ae, 0x00000000, 0x000400fa, 0x000000ac, 0x000000ad, + 0x000000ae, 0x000200f8, 0x000000ad, 0x00050041, 0x00000091, 0x000000b0, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, + 0x000000b1, 0x000000b0, 0x0003003e, 0x000000b2, 0x00000031, 0x0003003e, 0x000000b3, 0x000000af, 0x00060041, 0x00000094, + 0x000000b5, 0x000000b1, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, 0x000000b6, 0x000000b5, 0x00000002, 0x00000004, + 0x0003003e, 0x000000b4, 0x000000b6, 0x0003003e, 0x000000b7, 0x0000002e, 0x00080039, 0x00000002, 0x000000b8, 0x0000001a, + 0x000000b2, 0x000000b3, 0x000000b4, 0x000000b7, 0x000200f9, 0x000000ae, 0x000200f8, 0x000000ae, 0x00050041, 0x00000091, + 0x000000b9, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000ba, 0x000000b9, 0x00060041, 0x00000094, 0x000000bb, + 0x000000ba, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000bc, 0x000000bb, 0x00000002, 0x00000008, 0x00050041, + 0x00000097, 0x000000be, 0x00000090, 0x000000bd, 0x0004003d, 0x0000000a, 0x000000bf, 0x000000be, 0x000500ac, 0x00000006, + 0x000000c0, 0x000000bc, 0x000000bf, 0x000300f7, 0x000000c2, 0x00000000, 0x000400fa, 0x000000c0, 0x000000c1, 0x000000c2, + 0x000200f8, 0x000000c1, 0x00050041, 0x00000091, 0x000000c4, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000c5, + 0x000000c4, 0x0003003e, 0x000000c6, 0x00000031, 0x0003003e, 0x000000c7, 0x000000c3, 0x00060041, 0x00000094, 0x000000c9, + 0x000000c5, 0x00000022, 0x0000004e, 0x0006003d, 0x0000000a, 0x000000ca, 0x000000c9, 0x00000002, 0x00000008, 0x0003003e, + 0x000000c8, 0x000000ca, 0x0003003e, 0x000000cb, 0x0000002e, 0x00080039, 0x00000002, 0x000000cc, 0x0000001a, 0x000000c6, + 0x000000c7, 0x000000c8, 0x000000cb, 0x000200f9, 0x000000c2, 0x000200f8, 0x000000c2, 0x00050041, 0x00000091, 0x000000d0, + 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000d1, 0x000000d0, 0x00060041, 0x00000094, 0x000000d2, 0x000000d1, + 0x00000022, 0x00000022, 0x0006003d, 0x0000000a, 0x000000d3, 0x000000d2, 0x00000002, 0x00000010, 0x00050041, 0x00000091, + 0x000000d4, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000d5, 0x000000d4, 0x00060041, 0x00000094, 0x000000d6, + 0x000000d5, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, 0x000000d7, 0x000000d6, 0x00000002, 0x00000004, 0x00050084, + 0x0000000a, 0x000000d8, 0x000000d3, 0x000000d7, 0x00050041, 0x00000091, 0x000000d9, 0x00000090, 0x00000022, 0x0004003d, + 0x0000008b, 0x000000da, 0x000000d9, 0x00060041, 0x00000094, 0x000000db, 0x000000da, 0x00000022, 0x0000004e, 0x0006003d, + 0x0000000a, 0x000000dc, 0x000000db, 0x00000002, 0x00000008, 0x00050084, 0x0000000a, 0x000000dd, 0x000000d8, 0x000000dc, + 0x00040071, 0x000000cd, 0x000000de, 0x000000dd, 0x00050041, 0x00000097, 0x000000e1, 0x00000090, 0x000000e0, 0x0004003d, + 0x0000000a, 0x000000e2, 0x000000e1, 0x00040071, 0x000000cd, 0x000000e3, 0x000000e2, 0x000500ac, 0x00000006, 0x000000e4, + 0x000000de, 0x000000e3, 0x000300f7, 0x000000e6, 0x00000000, 0x000400fa, 0x000000e4, 0x000000e5, 0x000000e6, 0x000200f8, + 0x000000e5, 0x00050041, 0x00000091, 0x000000e8, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000e9, 0x000000e8, + 0x00050041, 0x00000091, 0x000000ea, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000eb, 0x000000ea, 0x00050041, + 0x00000091, 0x000000ec, 0x00000090, 0x00000022, 0x0004003d, 0x0000008b, 0x000000ed, 0x000000ec, 0x0003003e, 0x000000ee, + 0x00000031, 0x0003003e, 0x000000ef, 0x000000e7, 0x00060041, 0x00000094, 0x000000f1, 0x000000e9, 0x00000022, 0x00000022, + 0x0006003d, 0x0000000a, 0x000000f2, 0x000000f1, 0x00000002, 0x00000010, 0x0003003e, 0x000000f0, 0x000000f2, 0x00060041, + 0x00000094, 0x000000f4, 0x000000eb, 0x00000022, 0x0000003e, 0x0006003d, 0x0000000a, 0x000000f5, 0x000000f4, 0x00000002, + 0x00000004, 0x0003003e, 0x000000f3, 0x000000f5, 0x00060041, 0x00000094, 0x000000f7, 0x000000ed, 0x00000022, 0x0000004e, + 0x0006003d, 0x0000000a, 0x000000f8, 0x000000f7, 0x00000002, 0x00000008, 0x0003003e, 0x000000f6, 0x000000f8, 0x0003003e, + 0x000000f9, 0x0000002e, 0x000a0039, 0x00000002, 0x000000fa, 0x00000013, 0x000000ee, 0x000000ef, 0x000000f0, 0x000000f3, + 0x000000f6, 0x000000f9, 0x000200f9, 0x000000e6, 0x000200f8, 0x000000e6, 0x000100fd, 0x00010038, 0x00050036, 0x00000006, + 0x00000008, 0x00000000, 0x00000007, 0x000200f8, 0x00000009, 0x00060041, 0x00000023, 0x00000024, 0x00000020, 0x00000022, + 0x00000022, 0x0004003d, 0x0000000a, 0x00000025, 0x00000024, 0x00060041, 0x00000023, 0x0000002c, 0x0000002a, 0x00000022, + 0x00000025, 0x000700ea, 0x0000000a, 0x0000002f, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002d, 0x000500ae, 0x00000006, + 0x00000032, 0x0000002f, 0x00000031, 0x000200fe, 0x00000032, 0x00010038, 0x00050036, 0x00000002, 0x00000013, 0x00000000, + 0x0000000c, 0x00030037, 0x0000000b, 0x0000000d, 0x00030037, 0x0000000b, 0x0000000e, 0x00030037, 0x0000000b, 0x0000000f, + 0x00030037, 0x0000000b, 0x00000010, 0x00030037, 0x0000000b, 0x00000011, 0x00030037, 0x0000000b, 0x00000012, 0x000200f8, + 0x00000014, 0x00040039, 0x00000006, 0x00000035, 0x00000008, 0x000300f7, 0x00000037, 0x00000000, 0x000400fa, 0x00000035, + 0x00000036, 0x00000037, 0x000200f8, 0x00000036, 0x000100fd, 0x000200f8, 0x00000037, 0x00050041, 0x00000023, 0x0000003f, + 0x0000003d, 0x0000003e, 0x000700ea, 0x0000000a, 0x00000041, 0x0000003f, 0x0000002d, 0x0000002e, 0x00000040, 0x00050080, + 0x0000000a, 0x00000045, 0x00000041, 0x00000040, 0x00050044, 0x0000000a, 0x00000046, 0x0000003d, 0x00000002, 0x0004007c, + 0x00000021, 0x00000047, 0x00000046, 0x0004007c, 0x0000000a, 0x00000048, 0x00000047, 0x000500ac, 0x00000006, 0x00000049, + 0x00000045, 0x00000048, 0x000300f7, 0x0000004c, 0x00000000, 0x000400fa, 0x00000049, 0x0000004b, 0x0000004c, 0x000200f8, + 0x0000004b, 0x000100fd, 0x000200f8, 0x0000004c, 0x00060041, 0x00000023, 0x00000051, 0x0000003d, 0x0000004e, 0x00000041, + 0x0003003e, 0x00000051, 0x00000040, 0x00050080, 0x0000000a, 0x00000054, 0x00000041, 0x00000053, 0x00060041, 0x00000023, + 0x00000059, 0x00000058, 0x00000022, 0x00000022, 0x0004003d, 0x0000000a, 0x0000005a, 0x00000059, 0x00060041, 0x00000023, + 0x0000005b, 0x0000003d, 0x0000004e, 0x00000054, 0x0003003e, 0x0000005b, 0x0000005a, 0x00050080, 0x0000000a, 0x0000005e, + 0x00000041, 0x0000005d, 0x00060041, 0x00000023, 0x0000005f, 0x00000020, 0x00000022, 0x00000022, 0x0004003d, 0x0000000a, + 0x00000060, 0x0000005f, 0x00060041, 0x00000023, 0x00000061, 0x0000003d, 0x0000004e, 0x0000005e, 0x0003003e, 0x00000061, + 0x00000060, 0x00050080, 0x0000000a, 0x00000064, 0x00000041, 0x00000063, 0x0004003d, 0x0000000a, 0x00000065, 0x0000000d, + 0x00060041, 0x00000023, 0x00000066, 0x0000003d, 0x0000004e, 0x00000064, 0x0003003e, 0x00000066, 0x00000065, 0x00050080, + 0x0000000a, 0x00000069, 0x00000041, 0x00000068, 0x0004003d, 0x0000000a, 0x0000006a, 0x0000000e, 0x00060041, 0x00000023, + 0x0000006b, 0x0000003d, 0x0000004e, 0x00000069, 0x0003003e, 0x0000006b, 0x0000006a, 0x00050080, 0x0000000a, 0x0000006e, + 0x00000041, 0x0000006d, 0x0004003d, 0x0000000a, 0x0000006f, 0x0000000f, 0x00060041, 0x00000023, 0x00000070, 0x0000003d, + 0x0000004e, 0x0000006e, 0x0003003e, 0x00000070, 0x0000006f, 0x00050080, 0x0000000a, 0x00000073, 0x00000041, 0x00000072, + 0x0004003d, 0x0000000a, 0x00000074, 0x00000010, 0x00060041, 0x00000023, 0x00000075, 0x0000003d, 0x0000004e, 0x00000073, + 0x0003003e, 0x00000075, 0x00000074, 0x00050080, 0x0000000a, 0x00000078, 0x00000041, 0x00000077, 0x0004003d, 0x0000000a, + 0x00000079, 0x00000011, 0x00060041, 0x00000023, 0x0000007a, 0x0000003d, 0x0000004e, 0x00000078, 0x0003003e, 0x0000007a, + 0x00000079, 0x00050080, 0x0000000a, 0x0000007d, 0x00000041, 0x0000007c, 0x0004003d, 0x0000000a, 0x0000007e, 0x00000012, + 0x00060041, 0x00000023, 0x0000007f, 0x0000003d, 0x0000004e, 0x0000007d, 0x0003003e, 0x0000007f, 0x0000007e, 0x000100fd, + 0x00010038, 0x00050036, 0x00000002, 0x0000001a, 0x00000000, 0x00000015, 0x00030037, 0x0000000b, 0x00000016, 0x00030037, + 0x0000000b, 0x00000017, 0x00030037, 0x0000000b, 0x00000018, 0x00030037, 0x0000000b, 0x00000019, 0x000200f8, 0x0000001b, + 0x0004003b, 0x0000000b, 0x00000080, 0x00000007, 0x0004003b, 0x0000000b, 0x00000082, 0x00000007, 0x0004003b, 0x0000000b, + 0x00000084, 0x00000007, 0x0004003b, 0x0000000b, 0x00000086, 0x00000007, 0x0004003b, 0x0000000b, 0x00000088, 0x00000007, + 0x0004003b, 0x0000000b, 0x00000089, 0x00000007, 0x0004003d, 0x0000000a, 0x00000081, 0x00000016, 0x0003003e, 0x00000080, + 0x00000081, 0x0004003d, 0x0000000a, 0x00000083, 0x00000017, 0x0003003e, 0x00000082, 0x00000083, 0x0004003d, 0x0000000a, + 0x00000085, 0x00000018, 0x0003003e, 0x00000084, 0x00000085, 0x0004003d, 0x0000000a, 0x00000087, 0x00000019, 0x0003003e, + 0x00000086, 0x00000087, 0x0003003e, 0x00000088, 0x0000002e, 0x0003003e, 0x00000089, 0x0000002e, 0x000a0039, 0x00000002, + 0x0000008a, 0x00000013, 0x00000080, 0x00000082, 0x00000084, 0x00000086, 0x00000088, 0x00000089, 0x000100fd, 0x00010038, }; diff --git a/scripts/generate_source.py b/scripts/generate_source.py index 80ee2b14161..80455ae46c7 100755 --- a/scripts/generate_source.py +++ b/scripts/generate_source.py @@ -429,6 +429,8 @@ def main(argv): 'instrumentation_ray_query_comp.cpp', 'instrumentation_post_process_descriptor_index_comp.h', 'instrumentation_post_process_descriptor_index_comp.cpp', + 'instrumentation_vertex_attribute_fetch_oob_vert.cpp', + 'instrumentation_vertex_attribute_fetch_oob_vert.h', 'feature_requirements_helper.h', # https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8969 'feature_requirements_helper.cpp' ] diff --git a/tests/unit/gpu_av_index_buffer.cpp b/tests/unit/gpu_av_index_buffer.cpp index 11d2a8daf45..106bb6a633f 100644 --- a/tests/unit/gpu_av_index_buffer.cpp +++ b/tests/unit/gpu_av_index_buffer.cpp @@ -43,9 +43,8 @@ TEST_F(NegativeGpuAVIndexBuffer, IndexBufferOOB) { m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle()); - m_errorMonitor->SetDesiredErrorRegex( - "VUID-VkDrawIndexedIndirectCommand-robustBufferAccess2-08798", - "Index 4 is not within the bound index buffer. Computed from VkDrawIndexedIndirectCommand\\[0\\]"); + m_errorMonitor->SetDesiredErrorRegex("VUID-VkDrawIndexedIndirectCommand-robustBufferAccess2-08798", + "Index 4 is not within the bound index buffer."); vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32); vk::CmdDrawIndexedIndirect(m_command_buffer.handle(), draw_params_buffer.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand)); m_command_buffer.EndRenderPass(); @@ -55,7 +54,7 @@ TEST_F(NegativeGpuAVIndexBuffer, IndexBufferOOB) { m_errorMonitor->VerifyFound(); } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32) { +TEST_F(NegativeGpuAVIndexBuffer, IndirectDrawBadVertexIndex32) { TEST_DESCRIPTION("Validate illegal index buffer values - uint32_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -105,10 +104,8 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 1 \\] \\(666\\) \\+ vertexOffset \\(0\\) = Vertex index 666"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 666"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 42"); vk::CmdDrawIndexedIndirect(m_command_buffer.handle(), draw_params_buffer.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand)); m_command_buffer.EndRenderPass(); @@ -120,7 +117,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex16) { +TEST_F(NegativeGpuAVIndexBuffer, IndirectDrawBadVertexIndex16) { TEST_DESCRIPTION("Validate illegal index buffer values - uint16_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -171,10 +168,8 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex16) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 2 \\] \\(128\\) \\+ vertexOffset \\(0\\) = Vertex index 128"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 1 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 128"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 42"); vk::CmdDrawIndexedIndirect(m_command_buffer.handle(), draw_params_buffer.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand)); m_command_buffer.EndRenderPass(); @@ -186,7 +181,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex16) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex8) { +TEST_F(NegativeGpuAVIndexBuffer, IndirectDrawBadVertexIndex8) { TEST_DESCRIPTION("Validate illegal index buffer values - uint8_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); AddRequiredExtensions(VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME); @@ -239,10 +234,8 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex8) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT8_KHR); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 1 \\] \\(128\\) \\+ vertexOffset \\(0\\) = Vertex index 128"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", - "index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 128"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", "Vertex index 42"); vk::CmdDrawIndexedIndirect(m_command_buffer.handle(), draw_params_buffer.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand)); m_command_buffer.EndRenderPass(); @@ -254,7 +247,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex8) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex32) { +TEST_F(NegativeGpuAVIndexBuffer, DrawBadVertexIndex32) { TEST_DESCRIPTION("Validate illegal index buffer values - uint32_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -268,7 +261,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex32) { layout(location=0) in vec3 pos; void main() { - gl_Position = vec4(pos, 1.0); + gl_Position = vec4(pos, gl_VertexIndex); } )glsl"; VkShaderObj vs(this, vsSource, VK_SHADER_STAGE_VERTEX_BIT); @@ -296,19 +289,14 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex32) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 1 \\] \\(666\\) \\+ vertexOffset \\(0\\) = Vertex index 666"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 666"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 42"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); // vertexOffset = 3 - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 0 \\] \\(0\\) \\+ vertexOffset \\(3\\) = Vertex index 3"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 1 \\] \\(666\\) \\+ vertexOffset \\(3\\) = Vertex index 669"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(3\\) = Vertex index 45"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 3"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 669"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 45"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 3, 0); m_command_buffer.EndRenderPass(); @@ -319,7 +307,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex32) { m_errorMonitor->VerifyFound(); } -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawInSecondaryCmdBufferBadVertexIndex32) { +TEST_F(NegativeGpuAVIndexBuffer, DrawInSecondaryCmdBufferBadVertexIndex32) { TEST_DESCRIPTION("Validate illegal index buffer values - uint32_t index. Draw recorded in secondary command buffer."); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -364,7 +352,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawInSecondaryCmdBufferBadVertexIndex secondary_begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; secondary_begin_info.pInheritanceInfo = &inheritance_info; - constexpr uint32_t secondary_cmd_buffer_executes_count = 3; + constexpr uint32_t secondary_cmd_buffer_executes_count = 2; for (uint32_t i = 0; i < secondary_cmd_buffer_executes_count; ++i) { vkt::CommandBuffer &secondary_cmd_buffer = secondary_cmd_buffers.emplace_back(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); @@ -377,19 +365,14 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawInSecondaryCmdBufferBadVertexIndex vk::CmdBindIndexBuffer(secondary_cmd_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32); vk::CmdBindVertexBuffers(secondary_cmd_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[1\\] \\(666\\) \\+ vertexOffset \\(0\\) = Vertex index 666"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[2\\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 666"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 42"); vk::CmdDrawIndexed(secondary_cmd_buffer.handle(), 3, 1, 0, 0, 0); // vertexOffset = 3 - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[0\\] \\(0\\) \\+ vertexOffset \\(3\\) = Vertex index 3"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[1\\] \\(666\\) \\+ vertexOffset \\(3\\) = Vertex index 669"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[2\\] \\(42\\) \\+ vertexOffset \\(3\\) = Vertex index 45"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 3"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 669"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 45"); vk::CmdDrawIndexed(secondary_cmd_buffer.handle(), 3, 1, 0, 3, 0); secondary_cmd_buffer.End(); @@ -410,7 +393,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawInSecondaryCmdBufferBadVertexIndex } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16) { +TEST_F(NegativeGpuAVIndexBuffer, DrawBadVertexIndex16) { TEST_DESCRIPTION("Validate illegal index buffer values - uint16_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -453,10 +436,8 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 2 \\] \\(666\\) \\+ vertexOffset \\(0\\) = Vertex index 666"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 1 \\] \\(3\\) \\+ vertexOffset \\(0\\) = Vertex index 3"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 666"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 3"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); m_command_buffer.EndRenderPass(); @@ -468,7 +449,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16_2) { +TEST_F(NegativeGpuAVIndexBuffer, DrawBadVertexIndex16_2) { TEST_DESCRIPTION("Validate illegal index buffer values - uint16_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); RETURN_IF_SKIP(InitGpuAvFramework()); @@ -490,9 +471,9 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16_2) { layout(location=2) in vec3 normal; void main() { - gl_Position = vec4(pos + uv.xyx + normal, 1.0); + gl_Position = vec4(pos + uv.xyx + normal, 1.0); } - )glsl"; + )glsl"; VkShaderObj vs(this, vsSource, VK_SHADER_STAGE_VERTEX_BIT); CreatePipelineHelper pipe(*this); @@ -530,12 +511,10 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16_2) { VkDeviceSize vertex_buffer_offset = 2 * sizeof(Vertex); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - // Two OOB indices vkt::Buffer index_buffer = vkt::IndexBuffer(*m_device, {0, 1, 0}); vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 1 \\] \\(1\\) \\+ vertexOffset \\(0\\) = Vertex index 1"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 1"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); @@ -548,7 +527,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16_2) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex8) { +TEST_F(NegativeGpuAVIndexBuffer, DrawBadVertexIndex8) { TEST_DESCRIPTION("Validate illegal index buffer values - uint8_t index"); AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); AddRequiredExtensions(VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME); @@ -592,12 +571,9 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex8) { vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT8_KHR); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 0 \\] \\(12\\) \\+ vertexOffset \\(0\\) = Vertex index 12"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 1 \\] \\(66\\) \\+ vertexOffset \\(0\\) = Vertex index 66"); - m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", - "index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 12"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 66"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Vertex index 42"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); m_command_buffer.EndRenderPass(); @@ -609,7 +585,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex8) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16DebugLabel) { +TEST_F(NegativeGpuAVIndexBuffer, DrawBadVertexIndex16DebugLabel) { TEST_DESCRIPTION( "Validate illegal index buffer values - uint16_t index. Also make sure debug label regions are properly accounted for."); AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); @@ -680,13 +656,10 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16DebugLabel) { VkDeviceSize vertex_buffer_offset = 2 * sizeof(Vertex); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - // Two OOB indices vkt::Buffer index_buffer = vkt::IndexBuffer(*m_device, {0, 1, 0}); vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); - m_errorMonitor->SetDesiredErrorRegex( - "VUID-vkCmdDrawIndexed-None-02721", - "my_pipeline::my_draw([\\s\\S]*)index_buffer\\[ 1 \\] \\(1\\) \\+ vertexOffset \\(0\\) = Vertex index 1"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "my_pipeline::my_draw([\\s\\S]*)Vertex index 1"); vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); @@ -702,7 +675,7 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_DrawBadVertexIndex16DebugLabel) { } // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9163 -TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32DebugLabel) { +TEST_F(NegativeGpuAVIndexBuffer, IndirectDrawBadVertexIndex32DebugLabel) { TEST_DESCRIPTION( "Validate illegal index buffer values - uint32_t index. Also make sure debug label regions are properly accounted for."); AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); @@ -760,12 +733,10 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32DebugLabel vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32); vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); - m_errorMonitor->SetDesiredErrorRegex( - "VUID-vkCmdDrawIndexedIndirect-None-02721", - "my_pipeline::my_draw([\\s\\S]*)index_buffer\\[ 1 \\] \\(666\\) \\+ vertexOffset \\(0\\) = Vertex index 666"); - m_errorMonitor->SetDesiredErrorRegex( - "VUID-vkCmdDrawIndexedIndirect-None-02721", - "my_pipeline::my_draw([\\s\\S]*)index_buffer\\[ 2 \\] \\(42\\) \\+ vertexOffset \\(0\\) = Vertex index 42"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", + "my_pipeline::my_draw([\\s\\S]*)Vertex index 666"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexedIndirect-None-02721", + "my_pipeline::my_draw([\\s\\S]*)Vertex index 42"); vk::CmdDrawIndexedIndirect(m_command_buffer.handle(), draw_params_buffer.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand)); vk::CmdEndDebugUtilsLabelEXT(m_command_buffer); @@ -778,3 +749,92 @@ TEST_F(NegativeGpuAVIndexBuffer, DISABLED_IndirectDrawBadVertexIndex32DebugLabel m_default_queue->Wait(); m_errorMonitor->VerifyFound(); } + +TEST_F(NegativeGpuAVIndexBuffer, DrawBadInstanceIndex) { + TEST_DESCRIPTION("Validate illegal instance index values"); + AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + RETURN_IF_SKIP(InitGpuAvFramework()); + + RETURN_IF_SKIP(InitState()); + InitRenderTarget(); + + struct Vertex { + std::array position; + std::array uv; + std::array normal; + }; + + char const *vsSource = R"glsl( + #version 450 + + layout(location=0) in vec3 pos; + layout(location=1) in vec2 uv; + layout(location=2) in vec3 normal; + + layout(location=3) in float instance_float; + + void main() { + gl_Position = vec4(pos + uv.xyx + normal + instance_float, 1.0); + } + )glsl"; + VkShaderObj vs(this, vsSource, VK_SHADER_STAGE_VERTEX_BIT); + + CreatePipelineHelper pipe(*this); + // "Array of structs" style vertices + std::array input_bindings = { + {{0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX}, {1, sizeof(float), VK_VERTEX_INPUT_RATE_INSTANCE}}}; + std::array vertex_attributes = {}; + // Position + vertex_attributes[0] = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}; + // UV + vertex_attributes[1] = {1, 0, VK_FORMAT_R32G32_SFLOAT, 3 * sizeof(float)}; + // Normal + vertex_attributes[2] = {2, 0, VK_FORMAT_R32G32B32_SFLOAT, (3 + 2) * sizeof(float)}; + // Instance float + vertex_attributes[3] = {3, 1, VK_FORMAT_R32_SFLOAT, 0}; + + pipe.vi_ci_.vertexBindingDescriptionCount = size32(input_bindings); + pipe.vi_ci_.pVertexBindingDescriptions = input_bindings.data(); + pipe.vi_ci_.vertexAttributeDescriptionCount = size32(vertex_attributes); + pipe.vi_ci_.pVertexAttributeDescriptions = vertex_attributes.data(); + + pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()}; + + pipe.CreateGraphicsPipeline(); + + VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); + m_command_buffer.Begin(&begin_info); + m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); + + vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle()); + + std::vector vertices; + for (int i = 0; i < 3; ++i) { + const Vertex vertex = {{0.0f, 1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f, 7.0f}}; + vertices.emplace_back(vertex); + } + vkt::Buffer vertex_buffer = vkt::VertexBuffer(*m_device, vertices); + // Offset vertex buffer so that only first Vertex can correctly be fetched + const VkDeviceSize vertex_buffer_offset = 2 * sizeof(Vertex); + vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); + + std::vector instance_data = {42.0f}; + vkt::Buffer instance_buffer = vkt::VertexBuffer(*m_device, instance_data); + const VkDeviceSize instance_data_offset = 0; + vk::CmdBindVertexBuffers(m_command_buffer.handle(), 1, 1, &instance_buffer.handle(), &instance_data_offset); + + vkt::Buffer index_buffer = vkt::IndexBuffer(*m_device, {0, 0, 0}); + vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); + + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Instance index 1"); + m_errorMonitor->SetDesiredErrorRegex("VUID-vkCmdDrawIndexed-None-02721", "Instance index 2"); + + vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 3, 0, 0, 0); + + m_command_buffer.EndRenderPass(); + m_command_buffer.End(); + + m_default_queue->Submit(m_command_buffer); + m_default_queue->Wait(); + m_errorMonitor->VerifyFound(); +} diff --git a/tests/unit/gpu_av_index_buffer_positive.cpp b/tests/unit/gpu_av_index_buffer_positive.cpp index 695b4fb6250..d598a200f43 100644 --- a/tests/unit/gpu_av_index_buffer_positive.cpp +++ b/tests/unit/gpu_av_index_buffer_positive.cpp @@ -197,3 +197,74 @@ TEST_F(PositiveGpuAVIndexBuffer, IndexedIndirectRobustness) { m_default_queue->Submit(m_command_buffer); m_default_queue->Wait(); } + +TEST_F(PositiveGpuAVIndexBuffer, NoShaderInputsVertexIndex16) { + TEST_DESCRIPTION("Vertex shader defines no vertex attributes - no OOB vertex fetch should be detected"); + AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + RETURN_IF_SKIP(InitGpuAvFramework()); + + RETURN_IF_SKIP(InitState()); + InitRenderTarget(); + + struct Vertex { + std::array position; + std::array uv; + std::array normal; + }; + + char const *vsSource = R"glsl( + #version 450 + + void main() { + gl_Position = vec4(1.0); + } + )glsl"; + VkShaderObj vs(this, vsSource, VK_SHADER_STAGE_VERTEX_BIT); + + CreatePipelineHelper pipe(*this); + // "Array of structs" style vertices + VkVertexInputBindingDescription input_binding = {0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX}; + std::array vertex_attributes = {}; + // Position + vertex_attributes[0] = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}; + // UV + vertex_attributes[1] = {1, 0, VK_FORMAT_R32G32_SFLOAT, 3 * sizeof(float)}; + // Normal + vertex_attributes[2] = {2, 0, VK_FORMAT_R32G32B32_SFLOAT, (3 + 2) * sizeof(float)}; + + pipe.vi_ci_.pVertexBindingDescriptions = &input_binding; + pipe.vi_ci_.vertexBindingDescriptionCount = 1; + pipe.vi_ci_.pVertexAttributeDescriptions = vertex_attributes.data(); + pipe.vi_ci_.vertexAttributeDescriptionCount = size32(vertex_attributes); + pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()}; + + pipe.CreateGraphicsPipeline(); + + VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); + m_command_buffer.Begin(&begin_info); + m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); + + vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle()); + + std::vector vertices; + for (int i = 0; i < 3; ++i) { + const Vertex vertex = {{0.0f, 1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f, 7.0f}}; + vertices.emplace_back(vertex); + } + vkt::Buffer vertex_buffer = vkt::VertexBuffer(*m_device, vertices); + // Offset vertex buffer so that only first Vertex can correctly be fetched + VkDeviceSize vertex_buffer_offset = 2 * sizeof(Vertex); + vk::CmdBindVertexBuffers(m_command_buffer.handle(), 0, 1, &vertex_buffer.handle(), &vertex_buffer_offset); + + vkt::Buffer index_buffer = vkt::IndexBuffer(*m_device, {0, 1, 0}); + vk::CmdBindIndexBuffer(m_command_buffer.handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT16); + + vk::CmdDrawIndexed(m_command_buffer.handle(), 3, 1, 0, 0, 0); + + m_command_buffer.EndRenderPass(); + m_command_buffer.End(); + + m_default_queue->Submit(m_command_buffer); + m_default_queue->Wait(); + m_errorMonitor->VerifyFound(); +}