Skip to content

Commit

Permalink
gpu: Check index buffer contents in pre-draw validation
Browse files Browse the repository at this point in the history
This involves splitting up draw.vert into separate shaders for
non-indexed indirect, indexed (both indirect and direct) and mesh
draw calls.

Fixes KhronosGroup#2492
  • Loading branch information
jeremyg-lunarg committed Aug 9, 2024
1 parent fb1d091 commit 366871b
Show file tree
Hide file tree
Showing 28 changed files with 1,915 additions and 603 deletions.
8 changes: 6 additions & 2 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,12 @@ vvl_sources = [
"layers/gpu/cmd_validation/gpuav_copy_buffer_to_image.h",
"layers/gpu/cmd_validation/gpuav_dispatch.cpp",
"layers/gpu/cmd_validation/gpuav_dispatch.h",
"layers/gpu/cmd_validation/gpuav_draw.cpp",
"layers/gpu/cmd_validation/gpuav_draw.h",
"layers/gpu/cmd_validation/gpuav_indexed_draw.cpp",
"layers/gpu/cmd_validation/gpuav_indexed_draw.h",
"layers/gpu/cmd_validation/gpuav_indirect_draw.cpp",
"layers/gpu/cmd_validation/gpuav_indirect_draw.h",
"layers/gpu/cmd_validation/gpuav_mesh_draw.cpp",
"layers/gpu/cmd_validation/gpuav_mesh_draw.h",
"layers/gpu/cmd_validation/gpuav_trace_rays.cpp",
"layers/gpu/cmd_validation/gpuav_trace_rays.h",
"layers/gpu/core/gpu_settings.h",
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
491 changes: 367 additions & 124 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 @@ -366,6 +366,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 @@ -410,7 +412,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 @@ -470,8 +472,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 @@ -495,7 +497,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 @@ -511,8 +513,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 @@ -536,7 +538,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 @@ -552,8 +554,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

0 comments on commit 366871b

Please sign in to comment.