blob: 38f40313ecef7617c65f2ce4bd4f5d7cecadf1eb [file] [log] [blame]
// 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.
#version 450
#extension GL_GOOGLE_include_directive : enable
#include "common.h"
#include "draw_push_data.h"
layout(push_constant) uniform UniformInfo {
IndexedDrawPushData pc;
};
layout(set = kDiagPerCmdDescriptorSet, binding = kPreDrawBinding_IndexBuffer)
readonly buffer IndexBuffer32 {
uint index_buffer[];
};
uint get_vertex_index(uint i) {
if (pc.index_width == 32) {
return index_buffer[ i + pc.index_buffer_dwords_offset ];
} else if (pc.index_width == 16) {
const uint load_i = i / 2;
const uint packed_16_16 = index_buffer[ load_i + pc.index_buffer_dwords_offset ];
// if (i % 2) == 0, take first 16 bits, else last 16 bits
const uint shift = (i % 2) * 16;
return (packed_16_16 >> shift) & 0xFFFF;
} else if (pc.index_width == 8) {
const uint load_i = i / 4;
const uint packed_8_8_8_8 = index_buffer[ load_i + pc.index_buffer_dwords_offset ];
// if (i % 4) == 0, take first 8 bits, if == 1 take second set of 8 bits, etc...
const uint shift = (i % 4) * 8;
return (packed_8_8_8_8 >> shift) & 0xFF;
}
return 0;
}
void ValidateVertexIndex(uint index_buffer_offset, uint vertex_offset, uint smallest_vertex_attributes_count) {
const uint vertex_index = get_vertex_index(index_buffer_offset) + vertex_offset;
if (vertex_index >= smallest_vertex_attributes_count) {
GpuavLogError4(kErrorGroupGpuPreDraw, kErrorSubCode_OobVertexBuffer, index_buffer_offset, vertex_offset, vertex_index, 0);
}
}
// Goal is to do index (as in an indexed draw) computation manually, so that we can both retrieve the value of the faulty vertex index,
// and its offset in the index buffer
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
void main() {
if (gl_GlobalInvocationID.x >= pc.indices_to_check) return;
const uint index_buffer_offset = gl_GlobalInvocationID.x + pc.first_index;
ValidateVertexIndex(index_buffer_offset, pc.vertex_offset, pc.smallest_vertex_attributes_count);
}