Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpu: Check index buffer contents in pre-draw validation #8374

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,12 @@ vvl_sources = [
"layers/vulkan/generated/cmd_validation_copy_buffer_to_image_comp.h",
"layers/vulkan/generated/cmd_validation_dispatch_comp.cpp",
"layers/vulkan/generated/cmd_validation_dispatch_comp.h",
"layers/vulkan/generated/cmd_validation_draw_vert.cpp",
"layers/vulkan/generated/cmd_validation_draw_vert.h",
"layers/vulkan/generated/cmd_validation_indexed_draw_vert.cpp",
"layers/vulkan/generated/cmd_validation_indexed_draw_vert.h",
"layers/vulkan/generated/cmd_validation_indirect_draw_vert.cpp",
"layers/vulkan/generated/cmd_validation_indirect_draw_vert.h",
"layers/vulkan/generated/cmd_validation_mesh_draw_vert.cpp",
"layers/vulkan/generated/cmd_validation_mesh_draw_vert.h",
"layers/vulkan/generated/cmd_validation_trace_rays_rgen.cpp",
"layers/vulkan/generated/cmd_validation_trace_rays_rgen.h",
"layers/vulkan/generated/command_validation.cpp",
Expand Down
8 changes: 6 additions & 2 deletions layers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,12 @@ target_sources(vvl PRIVATE
${API_TYPE}/generated/cmd_validation_copy_buffer_to_image_comp.cpp
${API_TYPE}/generated/cmd_validation_dispatch_comp.h
${API_TYPE}/generated/cmd_validation_dispatch_comp.cpp
${API_TYPE}/generated/cmd_validation_draw_vert.h
${API_TYPE}/generated/cmd_validation_draw_vert.cpp
${API_TYPE}/generated/cmd_validation_indexed_draw_vert.h
${API_TYPE}/generated/cmd_validation_indexed_draw_vert.cpp
${API_TYPE}/generated/cmd_validation_indirect_draw_vert.h
${API_TYPE}/generated/cmd_validation_indirect_draw_vert.cpp
${API_TYPE}/generated/cmd_validation_mesh_draw_vert.h
${API_TYPE}/generated/cmd_validation_mesh_draw_vert.cpp
${API_TYPE}/generated/cmd_validation_trace_rays_rgen.h
${API_TYPE}/generated/cmd_validation_trace_rays_rgen.cpp
gpu/core/gpu_settings.h
Expand Down
562 changes: 437 additions & 125 deletions layers/gpu/cmd_validation/gpuav_draw.cpp

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions layers/gpu/cmd_validation/gpuav_draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,12 @@ void InsertIndirectDrawValidation(Validator &gpuav, const Location &loc, Command
VkDeviceSize indirect_offset, uint32_t draw_count, VkBuffer count_buffer,
VkDeviceSize count_buffer_offset, uint32_t stride);

void InsertIndexedDrawValidation(Validator &gpuav, const Location &loc, CommandBuffer &cb_state, VkBuffer indirect_buffer,
VkDeviceSize indirect_offset, uint32_t draw_count, VkBuffer count_buffer,
VkDeviceSize count_buffer_offset, uint32_t stride, uint32_t first_index, uint32_t index_count);

void InsertMeshDrawValidation(Validator &gpuav, const Location &loc, CommandBuffer &cb_state, VkBuffer indirect_buffer,
VkDeviceSize indirect_offset, uint32_t draw_count, VkBuffer count_buffer,
VkDeviceSize count_buffer_offset, uint32_t stride);

} // namespace gpuav
20 changes: 11 additions & 9 deletions layers/gpu/core/gpuav_record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ void Validator::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint3
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndexedDrawValidation(*this, record_obj.location, *cb_state, VK_NULL_HANDLE, 0, 0, VK_NULL_HANDLE, 0, 0, firstIndex,
indexCount);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand Down Expand Up @@ -381,7 +383,7 @@ void Validator::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffe
return;
}

InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, count, VK_NULL_HANDLE, 0, stride);
InsertIndexedDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, count, VK_NULL_HANDLE, 0, stride, 0, 0);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand Down Expand Up @@ -441,8 +443,8 @@ void Validator::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer command
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer,
countBufferOffset, stride);
InsertIndexedDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer, countBufferOffset,
stride, 0, 0);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand All @@ -466,7 +468,7 @@ void Validator::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandB
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, drawCount, VK_NULL_HANDLE, 0, stride);
InsertMeshDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, drawCount, VK_NULL_HANDLE, 0, stride);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand All @@ -482,8 +484,8 @@ void Validator::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer com
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer,
countBufferOffset, stride);
InsertMeshDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer, countBufferOffset,
stride);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand All @@ -507,7 +509,7 @@ void Validator::PreCallRecordCmdDrawMeshTasksIndirectEXT(VkCommandBuffer command
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, drawCount, VK_NULL_HANDLE, 0, stride);
InsertMeshDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, drawCount, VK_NULL_HANDLE, 0, stride);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand All @@ -523,8 +525,8 @@ void Validator::PreCallRecordCmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer co
InternalError(commandBuffer, record_obj.location, "Unrecognized command buffer.");
return;
}
InsertIndirectDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer,
countBufferOffset, stride);
InsertMeshDrawValidation(*this, record_obj.location, *cb_state, buffer, offset, maxDrawCount, countBuffer, countBufferOffset,
stride);
SetupShaderInstrumentationResources(*this, *cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, record_obj.location);
}

Expand Down
9 changes: 9 additions & 0 deletions layers/gpu/error_message/gpuav_vuids.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ struct GpuVuidsCmdDrawIndexed : GpuVuid {
uniform_access_oob_08612 = "VUID-vkCmdDrawIndexed-None-08612";
storage_access_oob_08613 = "VUID-vkCmdDrawIndexed-None-08613";
invalid_descriptor = "VUID-vkCmdDrawIndexed-None-08114";
// This should be detected on the host by core validation but just in case...
index_buffer_size = "VUID-vkCmdDrawIndexedEXT-robustBufferAccess2-08798";
vertex_index_oob = "VUID-vkCmdDrawIndexed-None-02721";
}
};

Expand All @@ -56,6 +59,8 @@ struct GpuVuidsCmdDrawMultiIndexedEXT : GpuVuid {
uniform_access_oob_08612 = "VUID-vkCmdDrawMultiIndexedEXT-None-08612";
storage_access_oob_08613 = "VUID-vkCmdDrawMultiIndexedEXT-None-08613";
invalid_descriptor = "VUID-vkCmdDrawMultiIndexedEXT-None-08114";
index_buffer_size = "VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798";
vertex_index_oob = "VUID-vkCmdDrawMultiIndexedEXT-None-02721";
}
};

Expand All @@ -78,6 +83,8 @@ struct GpuVuidsCmdDrawIndexedIndirect : GpuVuid {
storage_access_oob_08613 = "VUID-vkCmdDrawIndexedIndirect-None-08613";
invalid_descriptor = "VUID-vkCmdDrawIndexedIndirect-None-08114";
first_instance_not_zero = "VUID-VkDrawIndexedIndirectCommand-firstInstance-00554";
index_buffer_size = "VUID-vkCmdDrawIndexedIndirect-robustBufferAccess2-08798";
vertex_index_oob = "VUID-vkCmdDrawIndexedIndirect-None-02721";
}
};

Expand Down Expand Up @@ -128,6 +135,8 @@ struct GpuVuidsCmdDrawIndexedIndirectCount : GpuVuid {
count_exceeds_bufsize_1 = "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-03153";
count_exceeds_bufsize = "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-03154";
count_exceeds_device_limit = "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02717";
index_buffer_size = "VUID-vkCmdDrawIndexedIndirectCount-robustBufferAccess2-08798";
vertex_index_oob = "VUID-vkCmdDrawIndexedIndirectCount-None-02721";
}
};

Expand Down
2 changes: 2 additions & 0 deletions layers/gpu/error_message/gpuav_vuids.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ struct GpuVuid {
const char* trace_rays_width_exceeds_device_limit = kVUIDUndefined;
const char* trace_rays_height_exceeds_device_limit = kVUIDUndefined;
const char* trace_rays_depth_exceeds_device_limit = kVUIDUndefined;
const char* index_buffer_size = kVUIDUndefined;
const char* vertex_index_oob = kVUIDUndefined;
};

// Getter function to provide kVUIDUndefined in case an invalid function is passed in
Expand Down
123 changes: 0 additions & 123 deletions layers/gpu/shaders/cmd_validation/draw.vert

This file was deleted.

81 changes: 81 additions & 0 deletions layers/gpu/shaders/cmd_validation/draw_push_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2021-2024 The Khronos Group Inc.
// Copyright (c) 2021-2024 Valve Corporation
// Copyright (c) 2021-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.
// Values used between the GLSL shaders and the GPU-AV logic

// NOTE: This header is included by the instrumentation shaders and glslang doesn't support #pragma once
#ifndef GPU_SHADERS_DRAW_PUSH_DATA_H
#define GPU_SHADERS_DRAW_PUSH_DATA_H

#ifdef __cplusplus
namespace gpuav {
namespace glsl {
using uint = unsigned int;
#endif

// Bindings for all pre draw types
const uint kPreDrawIndirectBinding = 0;
const uint kPreDrawCountBinding = 1;
const uint kPreDrawIndexBinding = 2;

// Flag values for all pre draw types

// Set if the count buffer is bound
const uint kPreDrawSelectCountBuffer = (1 << 0);
// Set if the draw buffer is bound
const uint kPreDrawSelectDrawBuffer = (1 << 1);
// Set if firstInstance fields of draw structs must be validated
const uint kPreDrawSelectFirstInstance = (1 << 2);
// Set if the index buffer is bound
const uint kPreDrawSelectIndexBuffer = (1 << 3);

struct DrawIndirectPushData {
uint flags;
uint prop_count_limit;
uint buffer_count_limit;
uint draw_count;
uint draw_stride;
};

struct DrawIndexedPushData {
uint flags;
uint prop_count_limit;
uint buffer_count_limit;
uint draw_count;
uint draw_stride;
uint first_index;
uint index_count;
uint index_width;
uint vertex_offset;
uint vertex_buffer_size;
};

struct DrawMeshPushData {
uint flags;
uint prop_count_limit;
uint buffer_count_limit;
uint draw_count;
uint draw_stride;
uint max_workgroup_count_x;
uint max_workgroup_count_y;
uint max_workgroup_count_z;
uint max_workgroup_total_count;
};

#ifdef __cplusplus
} // namespace glsl
} // namespace gpuav
#endif
#endif
Loading