File: tlas.comp

package info (click to toggle)
vulkan-validationlayers 1.4.341.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 54,356 kB
  • sloc: cpp: 675,478; python: 12,311; sh: 24; makefile: 24; xml: 14
file content (127 lines) | stat: -rw-r--r-- 5,786 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright (c) 2022-2026 The Khronos Group Inc.
// Copyright (c) 2022-2026 Valve Corporation
// Copyright (c) 2022-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.

#version 460
#extension GL_GOOGLE_include_directive : enable


#include "common.h"
#include "build_acceleration_structures.h"

layout(push_constant, scalar)
uniform PushConstants {
    TLASValidationShaderPushData pc;
};

bool RangesInclude(Range r1, Range r2) {
    return (r1.begin <= r2.begin) && (r2.end <= r1.end);
}
bool RangesOverlap(Range r1, Range r2) {
    return RangesInclude(r1, r2) || RangesInclude(r2, r1);
}

layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main() {
    uint as_instance_i = 0;
    if (pc.validation_mode == kBuildASValidationMode_invalid_AS) {
        as_instance_i = gl_GlobalInvocationID.x * (gl_NumWorkGroups.y * gl_WorkGroupSize.y) + gl_GlobalInvocationID.y;
    } else if (pc.validation_mode == kBuildASValidationMode_memory_overlaps) {
        as_instance_i = gl_GlobalInvocationID.x;
    }
    if (as_instance_i >= pc.blas_array_size) {
        return;
    }
    const uint blas_built_in_cmd_i = gl_GlobalInvocationID.y;

    // Address of BLAS to validate
    uint64_t blas_addr = 0;
    if (pc.is_array_of_pointers == 0) {
        blas_addr = pc.blas_array_start_addr.blas_array[as_instance_i].accelerationStructureReference;
    } else {
        blas_addr = pc.blas_ptr_array_start_addr.blas_ptr_array[as_instance_i].as_instance.accelerationStructureReference;
    }

    uint error_subcode = 0;

    if ((blas_addr % 16u ) != 0) {
        error_subcode = kErrorSubCode_PreBuildAccelerationStructures_BlasAddrAlignment;
    } else if (pc.validation_mode == kBuildASValidationMode_invalid_AS) {
        error_subcode = kErrorSubCode_PreBuildAccelerationStructures_InvalidAS;
        const uint as_count = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.addresses_ptr.count;
        for (uint as_i = 0; as_i < as_count; ++as_i) {
            uint64_t valid_as_addr = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.addresses_ptr.array[as_i];

            if (valid_as_addr == blas_addr) {
                const uint as_metadata = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.metadata_ptr.array[as_i];

                // found AS, first assume it is valid
                error_subcode = 0;

                if (GET_BUILD_AS_METADATA_BUFFER_STATUS(as_metadata) != BUILD_AS_METADATA_VALID_BUFFER) {
                    error_subcode = kErrorSubCode_PreBuildAccelerationStructures_DestroyedASBuffer;
                    break;
                }

                if (GET_BUILD_AS_METADATA_AS_TYPE(as_metadata) != BUILD_AS_METADATA_AS_TYPE_BLAS) {
                    error_subcode = kErrorSubCode_PreBuildAccelerationStructures_InvalidASType;
                    break;
                }

                if (GET_BUILD_AS_METADATA_BUFFER_MEMORY_STATUS(as_metadata) != BUILD_AS_METADATA_VALID_BUFFER_MEMORY) {
                    error_subcode = kErrorSubCode_PreBuildAccelerationStructures_DestroyedASMemory;
                    break;
                }

                break;
            }
        }
    } else if (pc.validation_mode == kBuildASValidationMode_memory_overlaps) {
        if (blas_built_in_cmd_i >= pc.blas_built_in_cmd_array_size) {
            return;
        }
        // Try to find buffer range associated to BLAS to validate
        Range blas_buffer_range = {0,0};
        const uint as_count = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.addresses_ptr.count;
        for (uint as_i = 0; as_i < as_count; ++as_i) {
            uint64_t valid_as_addr = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.addresses_ptr.array[as_i];

            if (valid_as_addr == blas_addr) {
                blas_buffer_range = pc.ptr_to_ptr_to_accel_structs_arrays.as_arrays_ptrs.buffer_ranges_ptr.array[as_i];
                break;
            }
        }
        // Does BLAS buffer range, referenced in a TLAS build,
        // overlaps with another BLAS buffer range referenced in the same build command?
        if (blas_buffer_range.begin != 0) {
            Range blas_built_in_cmd_buffer_range = pc.blas_built_in_cmd_array_ptr.buffer_ranges[blas_built_in_cmd_i];
            if (RangesOverlap(blas_buffer_range, blas_built_in_cmd_buffer_range)) {
                error_subcode = kErrorSubCode_PreBuildAccelerationStructures_BlasMemoryOverlap;
            }
        }
    }

    if (error_subcode != 0) {
        pc.blas_array_start_addr.blas_array[as_instance_i].instanceCustomIndex_and_mask &= 0xffffff;// Set mask to 0 (upper 8 bits), so instance cannot get hit
        pc.blas_array_start_addr.blas_array[as_instance_i].accelerationStructureReference = pc.valid_dummy_blas_addr;// Point to a valid dummy blas

        const uint error_dword_0 = uint(blas_addr);
        const uint error_dword_1 = uint(blas_addr >> 32u);
        const uint error_dword_2 = as_instance_i;
        const uint error_dword_3 = pc.blas_array_i;// #ARNO_TODO swap dwords 2 and 3
        const uint error_dword_4 = blas_built_in_cmd_i;
        GpuavLogError5(kErrorGroup_GpuPreBuildAccelerationStructures, error_subcode, error_dword_0, error_dword_1, error_dword_2, error_dword_3, error_dword_4);
    }
}