| // Copyright (c) 2023-2026 The Khronos Group Inc. |
| // Copyright (c) 2023-2026 Valve Corporation |
| // Copyright (c) 2023-2026 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 "gpuav_error_header.h" |
| #include "gpuav_shaders_constants.h" |
| |
| #extension GL_EXT_scalar_block_layout : require |
| |
| layout(set = kDiagCommonDescriptorSet, binding = kBindingDiagErrorBuffer, scalar) buffer ErrorBuffer { |
| uint flags; |
| uint errors_count; |
| uint errors_buffer[]; |
| }; |
| |
| layout(set = kDiagCommonDescriptorSet, binding = kBindingDiagActionIndex, scalar) readonly buffer ActionIndexBuffer { |
| uint action_index[]; |
| }; |
| |
| layout(set = kDiagCommonDescriptorSet, binding = kBindingDiagCmdResourceIndex, scalar) readonly buffer ResourceIndexBuffer { |
| uint resource_index[]; |
| }; |
| |
| layout(set = kDiagCommonDescriptorSet, binding = kBindingDiagCmdErrorsCount, scalar) buffer CmdErrorsCountBuffer { |
| uint cmd_errors_count[]; |
| }; |
| |
| bool MaxCmdErrorsCountReached() { |
| const uint cmd_id = resource_index[0]; |
| const uint cmd_errors_count = atomicAdd(cmd_errors_count[cmd_id], 1); |
| return cmd_errors_count >= kMaxErrorsPerCmd; |
| } |
| |
| void GpuavLogError5(uint error_group, uint error_sub_code, uint dword_0, uint dword_1, uint dword_2, uint dword_3, uint dword_4) { |
| if (MaxCmdErrorsCountReached()) return; |
| |
| uint vo_idx = atomicAdd(errors_count, kErrorRecordSize); |
| const bool errors_buffer_filled = (vo_idx + kErrorRecordSize) > errors_buffer.length(); |
| if (errors_buffer_filled) return; |
| |
| errors_buffer[vo_idx + kHeader_ShaderIdErrorOffset] = |
| (error_group << kErrorGroup_Shift) | (error_sub_code << kErrorSubCode_Shift); |
| errors_buffer[vo_idx + kHeader_ErrorRecordSizeOffset] = kErrorRecordSize; |
| errors_buffer[vo_idx + kHeader_ActionIdErrorLoggerIdOffset] = (action_index[0] << kActionId_Shift) | resource_index[0]; |
| |
| errors_buffer[vo_idx + kValCmd_ErrorPayloadDword_0] = dword_0; |
| errors_buffer[vo_idx + kValCmd_ErrorPayloadDword_1] = dword_1; |
| errors_buffer[vo_idx + kValCmd_ErrorPayloadDword_2] = dword_2; |
| errors_buffer[vo_idx + kValCmd_ErrorPayloadDword_3] = dword_3; |
| errors_buffer[vo_idx + kValCmd_ErrorPayloadDword_4] = dword_4; |
| } |
| |
| void GpuavLogError2(uint error_group, uint error_sub_code, uint dword_0, uint dword_1) { |
| GpuavLogError5(error_group, error_sub_code, dword_0, dword_1, 0, 0, 0); |
| } |
| |
| void GpuavLogError4(uint error_group, uint error_sub_code, uint dword_0, uint dword_1, uint dword_2, uint dword_3) { |
| GpuavLogError5(error_group, error_sub_code, dword_0, dword_1, dword_2, dword_3, 0); |
| } |