Skip to content

Commit

Permalink
gpu: Cleanup error message constants
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Mar 1, 2024
1 parent 5add1c5 commit 4e00681
Show file tree
Hide file tree
Showing 24 changed files with 1,402 additions and 1,310 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ vvl_sources = [
"layers/external/vma/vk_mem_alloc.h",
"layers/external/vma/vma.cpp",
"layers/external/vma/vma.h",
"layers/gpu_shaders/gpu_error_constants.h",
"layers/gpu_shaders/gpu_shaders_constants.h",
"layers/gpu_validation/debug_printf.cpp",
"layers/gpu_validation/debug_printf.h",
Expand Down
1 change: 1 addition & 0 deletions layers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ target_sources(vvl PRIVATE
gpu_validation/gpu_validation.h
gpu_validation/gpu_vuids.cpp
gpu_validation/gpu_vuids.h
gpu_shaders/gpu_error_constants.h
gpu_shaders/gpu_shaders_constants.h
object_tracker/object_lifetime_validation.h
object_tracker/object_tracker_utils.cpp
Expand Down
221 changes: 221 additions & 0 deletions layers/gpu_shaders/gpu_error_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// 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_ERROR_CONSTANTS_H
#define GPU_ERROR_CONSTANTS_H

#ifdef __cplusplus
namespace gpuav {
namespace glsl {
#endif

// Common Stream Record Offsets
//
// The following are offsets to fields which are common to all records written
// to the output stream.
//
// Each record first contains the size of the record in 32-bit words, including
// the size word.
const int kInstCommonOutSize = 0;

// This is the shader id passed by the layer when the instrumentation pass is
// created.
const int kInstCommonOutShaderId = 1;

// This is the ordinal position of the instruction within the SPIR-V shader
// which generated the validation error.
const int kInstCommonOutInstructionIdx = 2;

// This is the stage which generated the validation error. This word is used
// to determine the contents of the next two words in the record.
// 0:Vert, 1:TessCtrl, 2:TessEval, 3:Geom, 4:Frag, 5:Compute
const int kInstCommonOutStageIdx = 3;
const int kInstCommonOutCnt = 4;

// Size of Common and Stage-specific Members
const int kInstStageOutCnt = kInstCommonOutCnt + 3;

// This identifies the validation error
// We use groups to more easily mangage the many int values not conflicting
const int kErrorGroup = kInstStageOutCnt;
const int kErrorSubCode = kErrorGroup + 1;

// Maximum Output Record Member Count
const int kInstMaxOutCnt = kErrorSubCode + 6;

// Stage-specific Stream Record Offsets
//
// Each stage will contain different values in the next set of words of the
// record used to identify which instantiation of the shader generated the
// validation error.
//
// Vertex Shader Output Record Offsets
const int kInstVertOutVertexIndex = kInstCommonOutCnt;
const int kInstVertOutInstanceIndex = kInstCommonOutCnt + 1;
const int kInstVertOutUnused = kInstCommonOutCnt + 2;

// Frag Shader Output Record Offsets
const int kInstFragOutFragCoordX = kInstCommonOutCnt;
const int kInstFragOutFragCoordY = kInstCommonOutCnt + 1;
const int kInstFragOutUnused = kInstCommonOutCnt + 2;

// Compute Shader Output Record Offsets
const int kInstCompOutGlobalInvocationIdX = kInstCommonOutCnt;
const int kInstCompOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
const int kInstCompOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;

// Tessellation Control Shader Output Record Offsets
const int kInstTessCtlOutInvocationId = kInstCommonOutCnt;
const int kInstTessCtlOutPrimitiveId = kInstCommonOutCnt + 1;
const int kInstTessCtlOutUnused = kInstCommonOutCnt + 2;

// Tessellation Eval Shader Output Record Offsets
const int kInstTessEvalOutPrimitiveId = kInstCommonOutCnt;
const int kInstTessEvalOutTessCoordU = kInstCommonOutCnt + 1;
const int kInstTessEvalOutTessCoordV = kInstCommonOutCnt + 2;

// Geometry Shader Output Record Offsets
const int kInstGeomOutPrimitiveId = kInstCommonOutCnt;
const int kInstGeomOutInvocationId = kInstCommonOutCnt + 1;
const int kInstGeomOutUnused = kInstCommonOutCnt + 2;

// Ray Tracing Shader Output Record Offsets
const int kInstRayTracingOutLaunchIdX = kInstCommonOutCnt;
const int kInstRayTracingOutLaunchIdY = kInstCommonOutCnt + 1;
const int kInstRayTracingOutLaunchIdZ = kInstCommonOutCnt + 2;

// Mesh Shader Output Record Offsets
const int kInstMeshOutGlobalInvocationIdX = kInstCommonOutCnt;
const int kInstMeshOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
const int kInstMeshOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;

// Task Shader Output Record Offsets
const int kInstTaskOutGlobalInvocationIdX = kInstCommonOutCnt;
const int kInstTaskOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
const int kInstTaskOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;

// Error Group
//
// These will match one-for-one with the file found in gpu_shader folder
const int kErrorGroupInstBindlessDescriptor = 1;
const int kErrorGroupInstBufferDeviceAddress = 2;
const int kErrorGroupInstRayQuery = 3;
const int kErrorGroupGpuPreDraw = 4;
const int kErrorGroupGpuPreDispatch = 5;
const int kErrorGroupGpuPreTraceRays = 6;
const int kErrorGroupGpuCopyBufferToImage = 7;

// Bindless Descriptor
//
const int kErrorSubCodeBindlessDescriptorBounds = 1;
const int kErrorSubCodeBindlessDescriptorUninit = 2;
const int kErrorSubCodeBindlessDescriptorOOB = 3;
const int kErrorSubCodeBindlessDescriptorDestroyed = 4;

// A bindless bounds error will output the index and the bound.
const int kInstBindlessBoundsOutDescSet = kErrorSubCode + 1;
const int kInstBindlessBoundsOutDescBinding = kErrorSubCode + 2;
const int kInstBindlessBoundsOutDescIndex = kErrorSubCode + 3;
const int kInstBindlessBoundsOutDescBound = kErrorSubCode + 4;
const int kInstBindlessBoundsOutUnused = kErrorSubCode + 5;
const int kInstBindlessBoundsOutCnt = kErrorSubCode + 6;

// A descriptor uninitialized error will output the index.
const int kInstBindlessUninitOutDescSet = kErrorSubCode + 1;
const int kInstBindlessUninitOutBinding = kErrorSubCode + 2;
const int kInstBindlessUninitOutDescIndex = kErrorSubCode + 3;
const int kInstBindlessUninitOutUnused = kErrorSubCode + 4;
const int kInstBindlessUninitOutUnused2 = kErrorSubCode + 5;
const int kInstBindlessUninitOutCnt = kErrorSubCode + 6;

// A buffer out-of-bounds error will output the descriptor
// index, the buffer offset and the buffer size
const int kInstBindlessBuffOOBOutDescSet = kErrorSubCode + 1;
const int kInstBindlessBuffOOBOutDescBinding = kErrorSubCode + 2;
const int kInstBindlessBuffOOBOutDescIndex = kErrorSubCode + 3;
const int kInstBindlessBuffOOBOutBuffOff = kErrorSubCode + 4;
const int kInstBindlessBuffOOBOutBuffSize = kErrorSubCode + 5;
const int kInstBindlessBuffOOBOutCnt = kErrorSubCode + 6;

// Buffer Device Address
//
const int kErrorSubCodeBufferDeviceAddressUnallocRef = 1;

// A buffer address unalloc error will output the 64-bit pointer in
// two 32-bit pieces, lower bits first.
const int kInstBuffAddrUnallocOutDescPtrLo = kErrorSubCode + 1;
const int kInstBuffAddrUnallocOutDescPtrHi = kErrorSubCode + 2;
const int kInstBuffAddrUnallocOutCnt = kErrorSubCode + 3;

// Ray Query
//
const int kErrorSubCodeRayQueryNegativeMin = 1;
const int kErrorSubCodeRayQueryNegativeMax = 2;
const int kErrorSubCodeRayQueryBothSkip = 3;
const int kErrorSubCodeRayQuerySkipCull = 4;
const int kErrorSubCodeRayQueryOpaque = 5;
const int kErrorSubCodeRayQueryMinMax = 6;
const int kErrorSubCodeRayQueryMinNaN = 7;
const int kErrorSubCodeRayQueryMaxNaN = 8;
const int kErrorSubCodeRayQueryOriginNaN = 9;
const int kErrorSubCodeRayQueryDirectionNaN = 10;
const int kErrorSubCodeRayQueryOriginFinite = 11;
const int kErrorSubCodeRayQueryDirectionFinite = 12;

const int kInstRayQueryOutParam0 = kErrorSubCode + 1;

// Used by all "Pre" shaders
const int kPreActionOutParam0 = kErrorSubCode + 1;
const int kPreActionOutParam1 = kErrorSubCode + 2;

// Pre Draw
//
const int kErrorSubCodePreDrawBufferSize = 1;
const int kErrorSubCodePreDrawCountLimit = 2;
const int kErrorSubCodePreDrawFirstInstance = 3;
const int kErrorSubCodePreDrawGroupCountX = 4;
const int kErrorSubCodePreDrawGroupCountY = 5;
const int kErrorSubCodePreDrawGroupCountZ = 6;
const int kErrorSubCodePreDrawGroupCountTotal = 7;

const int kPreDrawSelectCountBuffer = 1;
const int kPreDrawSelectDrawBuffer = 2;
const int kPreDrawSelectMeshCountBuffer = 3;
const int kPreDrawSelectMeshNoCount = 4;

// Pre Dispatch
//
const int kErrorSubCodePreDispatchCountLimitX = 1;
const int kErrorSubCodePreDispatchCountLimitY = 2;
const int kErrorSubCodePreDispatchCountLimitZ = 3;

// Pre Tracy Rays
//
const int kErrorSubCodePreTraceRaysLimitWidth = 1;
const int kErrorSubCodePreTraceRaysLimitHeight = 2;
const int kErrorSubCodePreTraceRaysLimitDepth = 3;

// Pre Copy Buffer To Image
//
const int kErrorSubCodePreCopyBufferToImageBufferTexel = 1;

#ifdef __cplusplus
} // namespace glsl
} // namespace gpuav
#endif
#endif
19 changes: 10 additions & 9 deletions layers/gpu_shaders/gpu_pre_action.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2023 The Khronos Group Inc.
// Copyright (c) 2023 Valve Corporation
// Copyright (c) 2023 LunarG, Inc.
// Copyright (c) 2023-2024 The Khronos Group Inc.
// Copyright (c) 2023-2024 Valve Corporation
// Copyright (c) 2023-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.
Expand All @@ -14,22 +14,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "gpu_error_constants.h"
#include "gpu_shaders_constants.h"

#define ERROR_RECORD_WORDS_COUNT kInstValidationOutError + 4
#define ERROR_RECORD_WORDS_COUNT kErrorGroup + 4

layout(set = 0, binding = 0) buffer OutputBuffer {
uint flags;
uint output_buffer_count;
uint output_buffer[];
};

void gpuavLogError(uint action_code, uint error, uint count, uint draw_number) {
void gpuavLogError(uint error_group, uint error_sub_code, uint param_0, uint param_1) {
uint vo_idx = atomicAdd(output_buffer_count, ERROR_RECORD_WORDS_COUNT);
if (vo_idx + ERROR_RECORD_WORDS_COUNT > output_buffer.length()) return;

output_buffer[vo_idx + kInstValidationOutError] = action_code;
output_buffer[vo_idx + kInstValidationOutError + 1] = error;
output_buffer[vo_idx + kInstValidationOutError + 2] = count;
output_buffer[vo_idx + kInstValidationOutError + 3] = draw_number;
output_buffer[vo_idx + kErrorGroup] = error_group;
output_buffer[vo_idx + kErrorSubCode] = error_sub_code;
output_buffer[vo_idx + kPreActionOutParam0] = param_0;
output_buffer[vo_idx + kPreActionOutParam1] = param_1;
}
8 changes: 4 additions & 4 deletions layers/gpu_shaders/gpu_pre_copy_buffer_to_image.comp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2022 The Khronos Group Inc.
// Copyright (c) 2022-2023 Valve Corporation
// Copyright (c) 2022-2023 LunarG, Inc.
// Copyright (c) 2022-2024 The Khronos Group Inc.
// Copyright (c) 2022-2024 Valve Corporation
// Copyright (c) 2022-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.
Expand Down Expand Up @@ -110,7 +110,7 @@ void main() {

Texel texel = SearchOobDepthValue(tid, region_i);
if (texel.value < 0 || texel.value > 1) {
gpuavLogError(kInstErrorCopyBufferToImage, pre_copy_buffer_to_image_out_of_range_value, texel.byte_offset, 0);
gpuavLogError(kErrorGroupGpuCopyBufferToImage, kErrorSubCodePreCopyBufferToImageBufferTexel, texel.byte_offset, 0);
}
}
}
12 changes: 6 additions & 6 deletions layers/gpu_shaders/gpu_pre_dispatch.comp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2022 The Khronos Group Inc.
// Copyright (c) 2022-2023 Valve Corporation
// Copyright (c) 2022-2023 LunarG, Inc.
// Copyright (c) 2022-2024 The Khronos Group Inc.
// Copyright (c) 2022-2024 Valve Corporation
// Copyright (c) 2022-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.
Expand Down Expand Up @@ -35,11 +35,11 @@ void main() {
uint indirect_z = indirect_buffer[u_info.indirect_x_offset + 2];

if (indirect_x > u_info.limit_x) {
gpuavLogError(kInstErrorPreDispatchValidate, pre_dispatch_count_exceeds_limit_x_error, indirect_x, 0);
gpuavLogError(kErrorGroupGpuPreDispatch, kErrorSubCodePreDispatchCountLimitX, indirect_x, 0);
} else if (indirect_y > u_info.limit_y) {
gpuavLogError(kInstErrorPreDispatchValidate, pre_dispatch_count_exceeds_limit_y_error, indirect_y, 0);
gpuavLogError(kErrorGroupGpuPreDispatch, kErrorSubCodePreDispatchCountLimitY, indirect_y, 0);
} else if (indirect_z > u_info.limit_z) {
gpuavLogError(kInstErrorPreDispatchValidate, pre_dispatch_count_exceeds_limit_z_error, indirect_z, 0);
gpuavLogError(kErrorGroupGpuPreDispatch, kErrorSubCodePreDispatchCountLimitZ, indirect_z, 0);
}

}
32 changes: 16 additions & 16 deletions layers/gpu_shaders/gpu_pre_draw.vert
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2021-2022 The Khronos Group Inc.
// Copyright (c) 2021-2023 Valve Corporation
// Copyright (c) 2021-2023 LunarG, Inc.
// 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.
Expand Down Expand Up @@ -61,35 +61,35 @@ layout(push_constant) uniform UniformInfo {

void main() {
if (gl_VertexIndex == 0) {
if (u_info.validation_select == pre_draw_select_count_buffer ||
u_info.validation_select == pre_draw_select_mesh_count_buffer) {
if (u_info.validation_select == kPreDrawSelectCountBuffer ||
u_info.validation_select == kPreDrawSelectMeshCountBuffer) {
// Validate count buffer
uint count_in = count_buffer[u_info.count_offset];
if (count_in > u_info.max_writes) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_count_exceeds_bufsize_error, count_in, 0);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawBufferSize, count_in, 0);
}
else if (count_in > u_info.count_limit) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_count_exceeds_limit_error, count_in, 0);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawCountLimit, count_in, 0);
}
} else if (u_info.validation_select == pre_draw_select_draw_buffer) {
} else if (u_info.validation_select == kPreDrawSelectDrawBuffer) {
// Validate firstInstances
uint fi_index = u_info.first_instance_offset;
for (uint i = 0; i < u_info.draw_count; i++) {
if (draws_buffer[fi_index] != 0) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_first_instance_error, i, i);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawFirstInstance, i, i);
break;
}
fi_index += u_info.draw_stride;
}
}

if (u_info.validation_select == pre_draw_select_mesh_count_buffer ||
u_info.validation_select == pre_draw_select_mesh_no_count) {
if (u_info.validation_select == kPreDrawSelectMeshCountBuffer ||
u_info.validation_select == kPreDrawSelectMeshNoCount) {
// Validate mesh draw buffer
uint draw_buffer_index = u_info.mesh_draw_buffer_offset;
uint stride = u_info.mesh_draw_buffer_stride;
uint draw_count;
if (u_info.validation_select == pre_draw_select_mesh_count_buffer)
if (u_info.validation_select == kPreDrawSelectMeshCountBuffer)
draw_count = count_buffer[u_info.count_offset];
else
draw_count = u_info.mesh_draw_buffer_num_draws;
Expand All @@ -98,17 +98,17 @@ void main() {
uint count_y_in = draws_buffer[draw_buffer_index + 1];
uint count_z_in = draws_buffer[draw_buffer_index + 2];
if (count_x_in > u_info.max_workgroup_count_x) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_group_count_exceeds_limit_x_error, count_x_in, i);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawGroupCountX, count_x_in, i);
}
if (count_y_in > u_info.max_workgroup_count_y) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_group_count_exceeds_limit_y_error, count_y_in, i);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawGroupCountY, count_y_in, i);
}
if (count_z_in > u_info.max_workgroup_count_z) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_group_count_exceeds_limit_z_error, count_z_in, i);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawGroupCountZ, count_z_in, i);
}
uint total = count_x_in * count_y_in * count_z_in;
if (total > u_info.max_workgroup_total_count) {
gpuavLogError(kInstErrorPreDrawValidate, pre_draw_group_count_exceeds_total_error, total, i);
gpuavLogError(kErrorGroupGpuPreDraw, kErrorSubCodePreDrawGroupCountTotal, total, i);
}
draw_buffer_index += stride;
}
Expand Down
Loading

0 comments on commit 4e00681

Please sign in to comment.