summaryrefslogtreecommitdiff
path: root/chapters/accelstructures.adoc
blob: 6ea83f140825594d0aad7e32aa218266bbda1182 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
// Copyright 2020-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[acceleration-structure]]
= Acceleration Structures


[[acceleration-structure-def]]
== Acceleration Structures

_Acceleration structures_ are data structures used by the implementation to
efficiently manage scene geometry as it is <<ray-traversal, traversed during
a ray tracing query>>.
The application is responsible for managing acceleration structure objects
(see <<resources-acceleration-structures,Acceleration Structures>>),
including allocation, destruction, executing builds or updates, and
synchronizing resources used during ray tracing queries.

There are two types of acceleration structures, _top level acceleration
structures_ and _bottom level acceleration structures_.

An acceleration structure is considered to be constructed if an
<<acceleration-structure-building,acceleration structure build command>> or
<<acceleration-structure-copying,copy command>> has been executed with the
given acceleration structure as the destination.

[[fig-accelstruct]]
image::{images}/accelstruct.svg[align="center",title="Acceleration Structure",opts="{imageopts}"]

.Caption
****
The diagram shows the relationship between top and bottom level acceleration
structures.
****


[[acceleration-structure-geometry]]
=== Geometry

_Geometries_ refer to a triangle or axis-aligned bounding box.


[[acceleration-structure-top-level]]
=== Top Level Acceleration Structures

Opaque acceleration structure for an array of instances.
The descriptor or device address referencing this is the starting point for
traversal.

The top level acceleration structure takes a reference to any bottom level
acceleration structure referenced by its instances.
Those bottom level acceleration structure objects must: be valid when the
top level acceleration structure is accessed.


[[acceleration-structure-bottom-level]]
=== Bottom Level Acceleration Structures

Opaque acceleration structure for an array of geometries.


[[acceleration-structure-update]]
=== Acceleration Structure Update Rules

The API defines two types of operations to produce acceleration structures
from geometry:

  * A _build_ operation is used to construct an acceleration structure.
  * An _update_ operation is used to modify an existing acceleration
    structure.

An update operation imposes certain constraints on the input, in exchange
for considerably faster execution.
When performing an update, the application is required to provide a full
description of the acceleration structure, but is prohibited from changing
anything other than instance definitions, transform matrices, and vertex or
AABB positions.
All other aspects of the description must: exactly match the one from the
original build.

More precisely, the application must: not use an update operation to do any
of the following:

  * Change primitives or instances from _active_ to _inactive_, or vice
    versa (as defined in <<acceleration-structure-inactive-prims>>).
  * Change the index or vertex formats of triangle geometry.
  * Change triangle geometry transform pointers from null to non-null or
    vice versa.
  * Change the number of geometries or instances in the structure.
  * Change the geometry flags for any geometry in the structure.
  * Change the number of vertices or primitives for any geometry in the
    structure.

ifdef::VK_EXT_opacity_micromap[]

If the original acceleration structure was built using opacity micromaps and
ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT
was set in pname:flags, the application must: provide the corresponding
micromap information to the update operation.
The application is prohibited from changing anything other than the specific
opacity values assigned to the triangles.

More precisely, the application must: not use an update operation to do any
of the following:

  * Remove micromaps or elink:VkOpacityMicromapSpecialIndexEXT values from a
    geometry which previously had them, or vice versa.
  * Change between use of elink:VkOpacityMicromapSpecialIndexEXT values and
    explicit micro-map triangles.
  * Change the subdivision level or format of the micromap triangle
    associated with any acceleration-structure triangle.

If the original acceleration structure was built using opacity micromaps and
ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT was
set in pname:flags, the application must: provide a micromap to the update
operation.

If the original acceleration structure was built using opacity micromaps and
neither opacity micromap update flag is set the application must: provide
the original micromap to the update operation.

endif::VK_EXT_opacity_micromap[]

ifdef::VK_NV_displacement_micromap[]
If the original acceleration structure was built using displacement
micromaps and
ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV
was set in pname:flags, the application must: provide a displacement
micromap to the update operation.

If the original acceleration structure was built using displacement
micromaps and the displacement micromap update flag is not set the
application must: provide the original micromap to the update operation.
endif::VK_NV_displacement_micromap[]

[[acceleration-structure-inactive-prims]]
=== Inactive Primitives and Instances

Acceleration structures allow the use of particular input values to signal
_inactive_ primitives or instances.

An _inactive_ triangle is one for which the first (X) component of any
vertex is NaN.
If any other vertex component is NaN, and the first is not, the behavior is
undefined:.
If the vertex format does not have a NaN representation, then all triangles
are considered active.

An _inactive_ instance is one whose acceleration structure reference is `0`.

An _inactive_ AABB is one for which the minimum X coordinate is NaN.
If any other component is NaN, and the first is not, the behavior is
undefined:.

In the above definitions, "`NaN`" refers to any type of NaN.
Signaling, non-signaling, quiet, loud, or otherwise.

An inactive object is considered invisible to all rays, and should: not be
represented in the acceleration structure.
Implementations should: ensure that the presence of inactive objects does
not seriously degrade traversal performance.

Inactive objects are counted in the auto-generated index sequences which are
provided to shaders via code:InstanceId and code:PrimitiveId SPIR-V
decorations.
This allows objects in the scene to change freely between the active and
inactive states, without affecting the layout of any arrays which are being
indexed using the ID values.

Any transition between the active and inactive states requires a full
acceleration structure rebuild.
Applications must: not perform an acceleration structure update where an
object is active in the source acceleration structure but would be inactive
in the destination, or vice versa.


[[acceleration-structure-building]]
=== Building Acceleration Structures

ifdef::VK_NV_ray_tracing[]
[open,refpage='vkCmdBuildAccelerationStructureNV',desc='Build an acceleration structure',type='protos']
--
:refpage: vkCmdBuildAccelerationStructureNV

To build an acceleration structure call:

include::{generated}/api/protos/vkCmdBuildAccelerationStructureNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:pInfo contains the shared information for the acceleration
    structure's structure.
  * pname:instanceData is the buffer containing an array of
    slink:VkAccelerationStructureInstanceKHR structures defining
    acceleration structures.
    This parameter must: be `NULL` for bottom level acceleration structures.
  * pname:instanceOffset is the offset in bytes (relative to the start of
    pname:instanceData) at which the instance data is located.
  * pname:update specifies whether to update the pname:dst acceleration
    structure with the data in pname:src.
  * pname:dst is a pointer to the target acceleration structure for the
    build.
  * pname:src is a pointer to an existing acceleration structure that is to
    be used to update the pname:dst acceleration structure.
  * pname:scratch is the slink:VkBuffer that will be used as scratch memory
    for the build.
  * pname:scratchOffset is the offset in bytes relative to the start of
    pname:scratch that will be used as a scratch memory.

Accesses to pname:dst, pname:src, and pname:scratch must: be
<<synchronization-dependencies,synchronized>> with the
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR or
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR.

.Valid Usage
****
  * [[VUID-vkCmdBuildAccelerationStructureNV-geometryCount-02241]]
    pname:geometryCount must: be less than or equal to
    slink:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxGeometryCount
  * [[VUID-vkCmdBuildAccelerationStructureNV-dst-02488]]
    pname:dst must: have been created with compatible
    slink:VkAccelerationStructureInfoNV where
    slink:VkAccelerationStructureInfoNV::pname:type and
    slink:VkAccelerationStructureInfoNV::pname:flags are identical,
    slink:VkAccelerationStructureInfoNV::pname:instanceCount and
    slink:VkAccelerationStructureInfoNV::pname:geometryCount for pname:dst
    are greater than or equal to the build size and each geometry in
    slink:VkAccelerationStructureInfoNV::pname:pGeometries for pname:dst has
    greater than or equal to the number of vertices, indices, and AABBs
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-02489]]
    If pname:update is ename:VK_TRUE, pname:src must: not be
    dlink:VK_NULL_HANDLE
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-02490]]
    If pname:update is ename:VK_TRUE, pname:src must: have previously been
    constructed with
    ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV set in
    slink:VkAccelerationStructureInfoNV::pname:flags in the original build
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-02491]]
    If pname:update is ename:VK_FALSE, the pname:size member of the
    slink:VkMemoryRequirements structure returned from a call to
    flink:vkGetAccelerationStructureMemoryRequirementsNV with
    slink:VkAccelerationStructureMemoryRequirementsInfoNV::pname:accelerationStructure
    set to pname:dst and
    slink:VkAccelerationStructureMemoryRequirementsInfoNV::pname:type set to
    ename:VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV
    must: be less than or equal to the size of pname:scratch minus
    pname:scratchOffset
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-02492]]
    If pname:update is ename:VK_TRUE, the pname:size member of the
    slink:VkMemoryRequirements structure returned from a call to
    flink:vkGetAccelerationStructureMemoryRequirementsNV with
    slink:VkAccelerationStructureMemoryRequirementsInfoNV::pname:accelerationStructure
    set to pname:dst and
    slink:VkAccelerationStructureMemoryRequirementsInfoNV::pname:type set to
    ename:VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV
    must: be less than or equal to the size of pname:scratch minus
    pname:scratchOffset
  * [[VUID-vkCmdBuildAccelerationStructureNV-scratch-03522]]
    pname:scratch must: have been created with
    ename:VK_BUFFER_USAGE_RAY_TRACING_BIT_NV usage flag
  * [[VUID-vkCmdBuildAccelerationStructureNV-instanceData-03523]]
    If pname:instanceData is not dlink:VK_NULL_HANDLE, pname:instanceData
    must: have been created with ename:VK_BUFFER_USAGE_RAY_TRACING_BIT_NV
    usage flag
  * [[VUID-vkCmdBuildAccelerationStructureNV-accelerationStructureReference-03786]]
    Each
    slink:VkAccelerationStructureInstanceKHR::pname:accelerationStructureReference
    value in pname:instanceData must: be a valid device address containing a
    value obtained from flink:vkGetAccelerationStructureHandleNV
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-03524]]
    If pname:update is ename:VK_TRUE, then objects that were previously
    active must: not be made inactive as per
    <<acceleration-structure-inactive-prims>>
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-03525]]
    If pname:update is ename:VK_TRUE, then objects that were previously
    inactive must: not be made active as per
    <<acceleration-structure-inactive-prims>>
  * [[VUID-vkCmdBuildAccelerationStructureNV-update-03526]]
    If pname:update is ename:VK_TRUE, the pname:src and pname:dst objects
    must: either be the same object or not have any
    <<resources-memory-aliasing, memory aliasing>>
  * [[VUID-vkCmdBuildAccelerationStructureNV-dst-07787]]
    pname:dst must: be bound completely and contiguously to a single
    sname:VkDeviceMemory object via
    flink:vkBindAccelerationStructureMemoryNV

****

include::{generated}/validity/protos/vkCmdBuildAccelerationStructureNV.adoc[]
--
endif::VK_NV_ray_tracing[]

ifdef::VK_KHR_acceleration_structure[]
[open,refpage='vkCmdBuildAccelerationStructuresKHR',desc='Build an acceleration structure',type='protos']
--
:refpage: vkCmdBuildAccelerationStructuresKHR

To build acceleration structures call:

include::{generated}/api/protos/vkCmdBuildAccelerationStructuresKHR.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:infoCount is the number of acceleration structures to build.
    It specifies the number of the pname:pInfos structures and
    pname:ppBuildRangeInfos pointers that must: be provided.
  * pname:pInfos is a pointer to an array of pname:infoCount
    slink:VkAccelerationStructureBuildGeometryInfoKHR structures defining
    the geometry used to build each acceleration structure.
  * pname:ppBuildRangeInfos is a pointer to an array of pname:infoCount
    pointers to arrays of slink:VkAccelerationStructureBuildRangeInfoKHR
    structures.
    Each pname:ppBuildRangeInfos[i] is a pointer to an array of
    pname:pInfos[i].pname:geometryCount
    slink:VkAccelerationStructureBuildRangeInfoKHR structures defining
    dynamic offsets to the addresses where geometry data is stored, as
    defined by pname:pInfos[i].

The fname:vkCmdBuildAccelerationStructuresKHR command provides the ability
to initiate multiple acceleration structures builds, however there is no
ordering or synchronization implied between any of the individual
acceleration structure builds.

[NOTE]
.Note
====
This means that an application cannot: build a top-level acceleration
structure in the same flink:vkCmdBuildAccelerationStructuresKHR call as the
associated bottom-level or instance acceleration structures are being built.
There also cannot: be any memory aliasing between any acceleration structure
memories or scratch memories being used by any of the builds.
====

[[acceleration-structure-scratch]]
Accesses to the acceleration structure scratch buffers as identified by the
slink:VkAccelerationStructureBuildGeometryInfoKHR::pname:scratchData buffer
device addresses must: be <<synchronization-dependencies,synchronized>> with
the ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
(ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR |
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR).
Accesses to each
slink:VkAccelerationStructureBuildGeometryInfoKHR::pname:srcAccelerationStructure
and
slink:VkAccelerationStructureBuildGeometryInfoKHR::pname:dstAccelerationStructure
must: be <<synchronization-dependencies,synchronized>> with the
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR or
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, as appropriate.

Accesses to other input buffers as identified by any used values of
ifdef::VK_NV_ray_tracing_motion_blur[]
slink:VkAccelerationStructureGeometryMotionTrianglesDataNV::pname:vertexData,
endif::VK_NV_ray_tracing_motion_blur[]
slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:vertexData,
slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:indexData,
slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:transformData,
slink:VkAccelerationStructureGeometryAabbsDataKHR::pname:data, and
slink:VkAccelerationStructureGeometryInstancesDataKHR::pname:data must: be
<<synchronization-dependencies,synchronized>> with the
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_SHADER_READ_BIT.


.Valid Usage
****
  * [[VUID-vkCmdBuildAccelerationStructuresKHR-accelerationStructure-08923]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled

:maxinstancecheck: pname:ppBuildRangeInfos[i][j].pname:primitiveCount
include::{chapters}/commonvalidity/build_acceleration_structure_common.adoc[]
include::{chapters}/commonvalidity/build_acceleration_structure_device_common.adoc[]
include::{chapters}/commonvalidity/build_acceleration_structure_nonindirect_common.adoc[]
****

include::{generated}/validity/protos/vkCmdBuildAccelerationStructuresKHR.adoc[]
--

[open,refpage='vkCmdBuildAccelerationStructuresIndirectKHR',desc='Build an acceleration structure with some parameters provided on the device',type='protos']
--
:refpage: vkCmdBuildAccelerationStructuresIndirectKHR

To build acceleration structures with some parameters sourced on the device
call:

include::{generated}/api/protos/vkCmdBuildAccelerationStructuresIndirectKHR.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:infoCount is the number of acceleration structures to build.
  * pname:pInfos is a pointer to an array of pname:infoCount
    slink:VkAccelerationStructureBuildGeometryInfoKHR structures defining
    the geometry used to build each acceleration structure.
  * pname:pIndirectDeviceAddresses is a pointer to an array of
    pname:infoCount buffer device addresses which point to
    pname:pInfos[i].pname:geometryCount
    slink:VkAccelerationStructureBuildRangeInfoKHR structures defining
    dynamic offsets to the addresses where geometry data is stored, as
    defined by pname:pInfos[i].
  * pname:pIndirectStrides is a pointer to an array of pname:infoCount byte
    strides between elements of pname:pIndirectDeviceAddresses.
  * pname:ppMaxPrimitiveCounts is a pointer to an array of pname:infoCount
    pointers to arrays of pname:pInfos[i].pname:geometryCount values
    indicating the maximum number of primitives that will be built by this
    command for each geometry.

Accesses to acceleration structures, scratch buffers, vertex buffers, index
buffers, and instance buffers must be synchronized as with
<<acceleration-structure-scratch,vkCmdBuildAccelerationStructuresKHR>>.

Accesses to any element of pname:pIndirectDeviceAddresses must: be
<<synchronization-dependencies,synchronized>> with the
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT.


.Valid Usage
****
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-accelerationStructureIndirectBuild-03650]]
    The <<features-accelerationStructureIndirectBuild,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureIndirectBuild>>
    feature must: be enabled

:maxinstancecheck: pname:ppMaxPrimitiveCounts[i][j]
include::{chapters}/commonvalidity/build_acceleration_structure_common.adoc[]
include::{chapters}/commonvalidity/build_acceleration_structure_device_common.adoc[]
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectDeviceAddresses-03645]]
    For any element of pname:pIndirectDeviceAddresses, if the buffer from
    which it was queried is non-sparse then it must: be bound completely and
    contiguously to a single slink:VkDeviceMemory object
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectDeviceAddresses-03646]]
    For any element of pname:pIndirectDeviceAddresses[i], all device
    addresses between pname:pIndirectDeviceAddresses[i] and
    [eq]#pname:pIndirectDeviceAddresses[i] {plus}
    (pname:pInfos[i].pname:geometryCount {times} pname:pIndirectStrides[i]) -
    1# must: be in the buffer device address range of the same buffer
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectDeviceAddresses-03647]]
    For any element of pname:pIndirectDeviceAddresses, the buffer from which
    it was queried must: have been created with the
    ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectDeviceAddresses-03648]]
    Each element of pname:pIndirectDeviceAddresses must: be a multiple of
    `4`
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectStrides-03787]]
    Each element of pname:pIndirectStrides must: be a multiple of `4`
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-commandBuffer-03649]]
    pname:commandBuffer must: not be a protected command buffer
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pIndirectDeviceAddresses-03651]]
    Each slink:VkAccelerationStructureBuildRangeInfoKHR structure referenced
    by any element of pname:pIndirectDeviceAddresses must: be a valid
    slink:VkAccelerationStructureBuildRangeInfoKHR structure
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-pInfos-03652]]
    pname:pInfos[i].pname:dstAccelerationStructure must: have been created
    with a value of slink:VkAccelerationStructureCreateInfoKHR::pname:size
    greater than or equal to the memory size required by the build
    operation, as returned by flink:vkGetAccelerationStructureBuildSizesKHR
    with [eq]#pname:pBuildInfo = pname:pInfos[i]# and
    [eq]#pname:pMaxPrimitiveCounts = pname:ppMaxPrimitiveCounts[i]#
  * [[VUID-vkCmdBuildAccelerationStructuresIndirectKHR-ppMaxPrimitiveCounts-03653]]
    Each pname:ppMaxPrimitiveCounts[i][j] must: be greater than or equal to
    the pname:primitiveCount value specified by the
    slink:VkAccelerationStructureBuildRangeInfoKHR structure located at
    [eq]#pname:pIndirectDeviceAddresses[i] {plus} (code:j {times}
    pname:pIndirectStrides[i])#
****

include::{generated}/validity/protos/vkCmdBuildAccelerationStructuresIndirectKHR.adoc[]
--


[open,refpage='VkAccelerationStructureBuildGeometryInfoKHR',desc='Structure specifying the geometry data used to build an acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureBuildGeometryInfoKHR

The sname:VkAccelerationStructureBuildGeometryInfoKHR structure is defined
as:

include::{generated}/api/structs/VkAccelerationStructureBuildGeometryInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:type is a elink:VkAccelerationStructureTypeKHR value specifying
    the type of acceleration structure being built.
  * pname:flags is a bitmask of
    elink:VkBuildAccelerationStructureFlagBitsKHR specifying additional
    parameters of the acceleration structure.
  * pname:mode is a elink:VkBuildAccelerationStructureModeKHR value
    specifying the type of operation to perform.
  * pname:srcAccelerationStructure is a pointer to an existing acceleration
    structure that is to be used to update the pname:dst acceleration
    structure when pname:mode is
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR.
  * pname:dstAccelerationStructure is a pointer to the target acceleration
    structure for the build.
  * pname:geometryCount specifies the number of geometries that will be
    built into pname:dstAccelerationStructure.
  * pname:pGeometries is a pointer to an array of
    slink:VkAccelerationStructureGeometryKHR structures.
  * pname:ppGeometries is a pointer to an array of pointers to
    slink:VkAccelerationStructureGeometryKHR structures.
  * pname:scratchData is the device or host address to memory that will be
    used as scratch memory for the build.

Only one of pname:pGeometries or pname:ppGeometries can: be a valid pointer,
the other must: be `NULL`.
Each element of the non-`NULL` array describes the data used to build each
acceleration structure geometry.

ifdef::VK_KHR_ray_tracing_pipeline,VK_KHR_ray_query[]
[[acceleration-structure-geometry-index]]
The index of each element of the pname:pGeometries or pname:ppGeometries
members of slink:VkAccelerationStructureBuildGeometryInfoKHR is used as the
_geometry index_ during ray traversal.
ifdef::VK_KHR_ray_tracing_pipeline[]
The geometry index is available in ray shaders via the
<<interfaces-builtin-variables-raygeometryindex,code:RayGeometryIndexKHR
built-in>>, and is <<shader-binding-table-hit-shader-indexing, used to
determine hit and intersection shaders executed during traversal>>.
endif::VK_KHR_ray_tracing_pipeline[]
ifdef::VK_KHR_ray_query[]
The geometry index is available to ray queries via the
code:OpRayQueryGetIntersectionGeometryIndexKHR instruction.
endif::VK_KHR_ray_query[]
endif::VK_KHR_ray_tracing_pipeline,VK_KHR_ray_query[]

ifdef::VK_NV_ray_tracing_motion_blur[]
[[acceleration-structure-motion-instances]]
Setting ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV in pname:flags
indicates that this build is a motion top level acceleration structure.
A motion top level uses instances of format
slink:VkAccelerationStructureMotionInstanceNV if
slink:VkAccelerationStructureGeometryInstancesDataKHR::pname:arrayOfPointers
is ename:VK_FALSE.

If
slink:VkAccelerationStructureGeometryInstancesDataKHR::pname:arrayOfPointers
is ename:VK_TRUE, the pointer for each element of the array of instance
pointers consists of 4 bits of
ename:VkAccelerationStructureMotionInstanceTypeNV in the low 4 bits of the
pointer identifying the type of structure at the pointer.
The device address accessed is the value in the array with the low 4 bits
set to zero.
The structure at the pointer is one of
slink:VkAccelerationStructureInstanceKHR,
slink:VkAccelerationStructureMatrixMotionInstanceNV or
slink:VkAccelerationStructureSRTMotionInstanceNV, depending on the type
value encoded in the low 4 bits.

A top level acceleration structure with either motion instances or vertex
motion in its instances must: set
ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV in pname:flags.
endif::VK_NV_ray_tracing_motion_blur[]

Members pname:srcAccelerationStructure and pname:dstAccelerationStructure
may: be the same or different for an update operation (when pname:mode is
ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR).
If they are the same, the update happens in-place.
Otherwise, the target acceleration structure is updated and the source is
not modified.

.Valid Usage
****
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03654]]
    pname:type must: not be ename:VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-pGeometries-03788]]
    Only one of pname:pGeometries or pname:ppGeometries can: be a valid
    pointer, the other must: be `NULL`
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03789]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, the
    pname:geometryType member of elements of either pname:pGeometries or
    pname:ppGeometries must: be ename:VK_GEOMETRY_TYPE_INSTANCES_KHR
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03790]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,
    pname:geometryCount must: be `1`
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03791]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR
    the pname:geometryType member of elements of either pname:pGeometries or
    pname:ppGeometries must: not be ename:VK_GEOMETRY_TYPE_INSTANCES_KHR
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03792]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR
    then the pname:geometryType member of each geometry in either
    pname:pGeometries or pname:ppGeometries must: be the same
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03793]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR
    then pname:geometryCount must: be less than or equal to
    slink:VkPhysicalDeviceAccelerationStructurePropertiesKHR::pname:maxGeometryCount
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03794]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR
    and the pname:geometryType member of either pname:pGeometries or
    pname:ppGeometries is ename:VK_GEOMETRY_TYPE_AABBS_KHR, the total number
    of AABBs in all geometries must: be less than or equal to
    slink:VkPhysicalDeviceAccelerationStructurePropertiesKHR::pname:maxPrimitiveCount
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03795]]
    If pname:type is ename:VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR
    and the pname:geometryType member of either pname:pGeometries or
    pname:ppGeometries is ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, the total
    number of triangles in all geometries must: be less than or equal to
    slink:VkPhysicalDeviceAccelerationStructurePropertiesKHR::pname:maxPrimitiveCount
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-03796]]
    If pname:flags has the
    ename:VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR bit set,
    then it must: not have the
    ename:VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR bit set
ifdef::VK_NV_ray_tracing_motion_blur[]
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-dstAccelerationStructure-04927]]
    If pname:dstAccelerationStructure was created with
    ename:VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV set in
    slink:VkAccelerationStructureCreateInfoKHR::pname:flags,
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV must: be set in
    pname:flags
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-04928]]
    If ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV is set in
    pname:flags, pname:dstAccelerationStructure must: have been created with
    ename:VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV set in
    slink:VkAccelerationStructureCreateInfoKHR::pname:flags
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-04929]]
    If ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV is set in
    pname:flags, pname:type must: not be
    ename:VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR
endif::VK_NV_ray_tracing_motion_blur[]
ifdef::VK_EXT_opacity_micromap[]
  * [[VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-07334]]
    If pname:flags has the
    ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT
    bit set then it must: not have the
    ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT
    bit set
endif::VK_EXT_opacity_micromap[]
****
include::{generated}/validity/structs/VkAccelerationStructureBuildGeometryInfoKHR.adoc[]
--

[open,refpage='VkBuildAccelerationStructureModeKHR',desc='Enum specifying the type of build operation to perform',type='enums']
--
:refpage: VkBuildAccelerationStructureModeKHR

The ename:VkBuildAccelerationStructureModeKHR enumeration is defined as:

include::{generated}/api/enums/VkBuildAccelerationStructureModeKHR.adoc[]

  * ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR specifies that the
    destination acceleration structure will be built using the specified
    geometries.
  * ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR specifies that the
    destination acceleration structure will be built using data in a source
    acceleration structure, updated by the specified geometries.
--

[open,refpage='VkDeviceOrHostAddressKHR',desc='Union specifying a device or host address',type='structs']
--
:refpage: VkDeviceOrHostAddressKHR

The sname:VkDeviceOrHostAddressKHR union is defined as:

include::{generated}/api/structs/VkDeviceOrHostAddressKHR.adoc[]

  * pname:deviceAddress is a buffer device address as returned by the
    flink:vkGetBufferDeviceAddressKHR command.
  * pname:hostAddress is a host memory address.

include::{generated}/validity/structs/VkDeviceOrHostAddressKHR.adoc[]
--

[open,refpage='VkDeviceOrHostAddressConstKHR',desc='Union specifying a const device or host address',type='structs']
--
:refpage: VkDeviceOrHostAddressConstKHR

The sname:VkDeviceOrHostAddressConstKHR union is defined as:

include::{generated}/api/structs/VkDeviceOrHostAddressConstKHR.adoc[]

  * pname:deviceAddress is a buffer device address as returned by the
    flink:vkGetBufferDeviceAddressKHR command.
  * pname:hostAddress is a const host memory address.

include::{generated}/validity/structs/VkDeviceOrHostAddressConstKHR.adoc[]
--

[open,refpage='VkAccelerationStructureGeometryKHR',desc='Structure specifying geometries to be built into an acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureGeometryKHR

The sname:VkAccelerationStructureGeometryKHR structure is defined as:

include::{generated}/api/structs/VkAccelerationStructureGeometryKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:geometryType describes which type of geometry this
    sname:VkAccelerationStructureGeometryKHR refers to.
  * pname:geometry is a slink:VkAccelerationStructureGeometryDataKHR union
    describing the geometry data for the relevant geometry type.
  * pname:flags is a bitmask of elink:VkGeometryFlagBitsKHR values
    describing additional properties of how the geometry should be built.

include::{generated}/validity/structs/VkAccelerationStructureGeometryKHR.adoc[]
--

[open,refpage='VkAccelerationStructureGeometryDataKHR',desc='Union specifying acceleration structure geometry data',type='structs']
--
:refpage: VkAccelerationStructureGeometryDataKHR

The sname:VkAccelerationStructureGeometryDataKHR union is defined as:

include::{generated}/api/structs/VkAccelerationStructureGeometryDataKHR.adoc[]

  * pname:triangles is a
    slink:VkAccelerationStructureGeometryTrianglesDataKHR structure.
  * pname:aabbs is a slink:VkAccelerationStructureGeometryAabbsDataKHR
    structure.
  * pname:instances is a
    slink:VkAccelerationStructureGeometryInstancesDataKHR structure.

include::{generated}/validity/structs/VkAccelerationStructureGeometryDataKHR.adoc[]
--

[open,refpage='VkAccelerationStructureGeometryTrianglesDataKHR',desc='Structure specifying a triangle geometry in a bottom-level acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureGeometryTrianglesDataKHR

The sname:VkAccelerationStructureGeometryTrianglesDataKHR structure is
defined as:

include::{generated}/api/structs/VkAccelerationStructureGeometryTrianglesDataKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:vertexFormat is the elink:VkFormat of each vertex element.
  * pname:vertexData is a device or host address to memory containing vertex
    data for this geometry.
  * pname:maxVertex is the highest index of a vertex that will be addressed
    by a build command using this structure.
  * pname:vertexStride is the stride in bytes between each vertex.
  * pname:indexType is the elink:VkIndexType of each index element.
  * pname:indexData is a device or host address to memory containing index
    data for this geometry.
  * pname:transformData is a device or host address to memory containing an
    optional reference to a slink:VkTransformMatrixKHR structure describing
    a transformation from the space in which the vertices in this geometry
    are described to the space in which the acceleration structure is
    defined.

[NOTE]
.Note
====
Unlike the stride for vertex buffers in
slink:VkVertexInputBindingDescription for graphics pipelines which must not
exceed pname:maxVertexInputBindingStride, pname:vertexStride for
acceleration structure geometry is instead restricted to being a 32-bit
value.
====

.Valid Usage
****
  * [[VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexStride-03735]]
    pname:vertexStride must: be a multiple of the size in bytes of the
    smallest component of pname:vertexFormat
  * [[VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexStride-03819]]
    pname:vertexStride must: be less than or equal to [eq]#2^32^-1#
  * [[VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexFormat-03797]]
    The <<resources-buffer-view-format-features,format features>> of
    pname:vertexFormat must: contain
    ename:VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR
  * [[VUID-VkAccelerationStructureGeometryTrianglesDataKHR-indexType-03798]]
    pname:indexType must: be ename:VK_INDEX_TYPE_UINT16,
    ename:VK_INDEX_TYPE_UINT32, or ename:VK_INDEX_TYPE_NONE_KHR
****

include::{generated}/validity/structs/VkAccelerationStructureGeometryTrianglesDataKHR.adoc[]
--

ifdef::VK_NV_ray_tracing_motion_blur[]
[open,refpage='VkAccelerationStructureGeometryMotionTrianglesDataNV',desc='Structure specifying vertex motion in a bottom-level acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureGeometryMotionTrianglesDataNV

The sname:VkAccelerationStructureGeometryMotionTrianglesDataNV structure is
defined as:

include::{generated}/api/structs/VkAccelerationStructureGeometryMotionTrianglesDataNV.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:vertexData is a pointer to vertex data for this geometry at time
    1.0

If sname:VkAccelerationStructureGeometryMotionTrianglesDataNV is included in
the pname:pNext chain of a
slink:VkAccelerationStructureGeometryTrianglesDataKHR structure, the basic
vertex positions are used for the position of the triangles in the geometry
at time 0.0 and the pname:vertexData in
sname:VkAccelerationStructureGeometryMotionTrianglesDataNV is used for the
vertex positions at time 1.0, with positions linearly interpolated at
intermediate times.

Indexing for sname:VkAccelerationStructureGeometryMotionTrianglesDataNV
pname:vertexData is equivalent to the basic vertex position data.

include::{generated}/validity/structs/VkAccelerationStructureGeometryMotionTrianglesDataNV.adoc[]
--
endif::VK_NV_ray_tracing_motion_blur[]

ifdef::VK_EXT_opacity_micromap[]
[open,refpage='VkAccelerationStructureTrianglesOpacityMicromapEXT',desc='Structure specifying an opacity micromap in a bottom-level acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureTrianglesOpacityMicromapEXT

The sname:VkAccelerationStructureTrianglesOpacityMicromapEXT structure is
defined as:

include::{generated}/api/structs/VkAccelerationStructureTrianglesOpacityMicromapEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:indexType is the type of triangle indices used when indexing this
    micromap
  * pname:indexBuffer is the address containing the triangle indices
  * pname:indexStride is the byte stride between triangle indices
  * pname:baseTriangle is the base value added to the non-negative triangle
    indices
  * pname:usageCountsCount specifies the number of usage counts structures
    that will be used to determine the size of this micromap.
  * pname:pUsageCounts is a pointer to an array of slink:VkMicromapUsageEXT
    structures.
  * pname:ppUsageCounts is a pointer to an array of pointers to
    slink:VkMicromapUsageEXT structures.
  * pname:micromap is the handle to the micromap object to include in this
    geometry

If sname:VkAccelerationStructureTrianglesOpacityMicromapEXT is included in
the pname:pNext chain of a
slink:VkAccelerationStructureGeometryTrianglesDataKHR structure, that
geometry will reference that micromap.

For each triangle in the geometry, the acceleration structure build fetches
an index from pname:indexBuffer using pname:indexType and pname:indexStride.
If that value is the unsigned cast of one of the values from
elink:VkOpacityMicromapSpecialIndexEXT then that triangle behaves as
described for that special value in <<ray-opacity-micromap,Ray Opacity
Micromap>>.
Otherwise that triangle uses the opacity micromap information from
pname:micromap at that index plus pname:baseTriangle.

Only one of pname:pUsageCounts or pname:ppUsageCounts can: be a valid
pointer, the other must: be `NULL`.
The elements of the non-`NULL` array describe the total count used to build
this geometry.
For a given pname:format and pname:subdivisionLevel the number of triangles
in this geometry matching those values after indirection and special index
handling must: be equal to the sum of matching pname:count provided.

If pname:micromap is dlink:VK_NULL_HANDLE, then every value read from
pname:indexBuffer must: be one of the values in
ename:VkOpacityMicromapSpecialIndexEXT.

.Valid Usage
****
  * [[VUID-VkAccelerationStructureTrianglesOpacityMicromapEXT-pUsageCounts-07335]]
    Only one of pname:pUsageCounts or pname:ppUsageCounts can: be a valid
    pointer, the other must: be `NULL`
****

include::{generated}/validity/structs/VkAccelerationStructureTrianglesOpacityMicromapEXT.adoc[]
--

[open,refpage='VkOpacityMicromapSpecialIndexEXT',desc='Enum for special indices in the opacity micromap',type='enums']
--
:refpage: VkOpacityMicromapSpecialIndexEXT

The ename:VkOpacityMicromapSpecialIndexEXT enumeration is defined as:

include::{generated}/api/enums/VkOpacityMicromapSpecialIndexEXT.adoc[]

  * ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT specifies
    that the entire triangle is fully transparent.
  * ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT specifies that
    the entire triangle is fully opaque.
  * ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT
    specifies that the entire triangle is unknown-transparent.
  * ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT
    specifies that the entire triangle is unknown-opaque.
--

endif::VK_EXT_opacity_micromap[]

ifdef::VK_NV_displacement_micromap[]
[open,refpage='VkAccelerationStructureTrianglesDisplacementMicromapNV',desc='Structure specifying a displacement micromap in a bottom-level acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureTrianglesDisplacementMicromapNV

The sname:VkAccelerationStructureTrianglesDisplacementMicromapNV structure
is defined as:

include::{generated}/api/structs/VkAccelerationStructureTrianglesDisplacementMicromapNV.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:displacementBiasAndScaleFormat is the format of displacement bias
    and scale used in this displacement micromap reference.
  * pname:displacementVectorFormat is the format of displacement vector used
    in this displacement micromap reference.
  * pname:displacementBiasAndScaleBuffer is the address containing the bias
    and scale.
  * pname:displacementBiasAndScaleStride is the byte stride between bias and
    scale values.
  * pname:displacementVectorBuffer is the address containing the
    displacement vector values.
  * pname:displacementVectorStride is the byte stride between displacement
    vector values.
  * pname:displacedMicromapPrimitiveFlags is the address containing the
    primitive flags.
  * pname:displacedMicromapPrimitiveFlagsStride is the byte stride between
    primitive flag values.
  * pname:indexType is the type of triangle indices used when indexing this
    micromap.
  * pname:indexBuffer is the address containing the triangle indices.
  * pname:indexStride is the byte stride between triangle indices.
  * pname:baseTriangle is the base value added to the non-negative triangle
    indices.
  * pname:usageCountsCount specifies the number of usage counts structures
    that will be used to determine the size of this micromap.
  * pname:pUsageCounts is a pointer to an array of slink:VkMicromapUsageEXT
    structures.
  * pname:ppUsageCounts is a pointer to an array of pointers to
    slink:VkMicromapUsageEXT structures.
  * pname:micromap is the handle to the micromap object to include in this
    geometry.

If sname:VkAccelerationStructureTrianglesDisplacementMicromapNV is included
in the pname:pNext chain of a
slink:VkAccelerationStructureGeometryTrianglesDataKHR structure, that
geometry will reference that micromap.

For each triangle in the geometry, the acceleration structure build fetches
an index from pname:indexBuffer using pname:indexType and pname:indexStride.
That triangle uses the displacement micromap information from pname:micromap
at that index plus pname:baseTriangle.

Only one of pname:pUsageCounts or pname:ppUsageCounts can: be a valid
pointer, the other must: be `NULL`.
The elements of the non-`NULL` array describe the total count used to build
this geometry.
For a given pname:format and pname:subdivisionLevel the number of triangles
in this geometry matching those values after indirection must: be equal to
the sum of matching pname:count provided.

.Valid Usage
****
  * [[VUID-VkAccelerationStructureTrianglesDisplacementMicromapNV-pUsageCounts-07992]]
    Only one of pname:pUsageCounts or pname:ppUsageCounts can: be a valid
    pointer, the other must: be `NULL`
****

include::{generated}/validity/structs/VkAccelerationStructureTrianglesDisplacementMicromapNV.adoc[]
--
endif::VK_NV_displacement_micromap[]
endif::VK_KHR_acceleration_structure[]

[open,refpage='VkTransformMatrixKHR',desc='Structure specifying a 3x4 affine transformation matrix',type='structs',alias='VkTransformMatrixNV']
--
:refpage: VkTransformMatrixKHR

The sname:VkTransformMatrixKHR structure is defined as:

include::{generated}/api/structs/VkTransformMatrixKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/structs/VkTransformMatrixNV.adoc[]
endif::VK_NV_ray_tracing[]

  * pname:matrix is a 3x4 row-major affine transformation matrix.

include::{generated}/validity/structs/VkTransformMatrixKHR.adoc[]

.Valid Usage
****
  * [[VUID-VkTransformMatrixKHR-matrix-03799]]
    The first three columns of pname:matrix must: define an invertible 3x3
    matrix
****
--

ifdef::VK_KHR_acceleration_structure[]
[open,refpage='VkAccelerationStructureGeometryAabbsDataKHR',desc='Structure specifying axis-aligned bounding box geometry in a bottom-level acceleration structure',type='structs']
--
:refpage: VkAccelerationStructureGeometryAabbsDataKHR

The sname:VkAccelerationStructureGeometryAabbsDataKHR structure is defined
as:

include::{generated}/api/structs/VkAccelerationStructureGeometryAabbsDataKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:data is a device or host address to memory containing
    slink:VkAabbPositionsKHR structures containing position data for each
    axis-aligned bounding box in the geometry.
  * pname:stride is the stride in bytes between each entry in pname:data.
    The stride must: be a multiple of `8`.

.Valid Usage
****
  * [[VUID-VkAccelerationStructureGeometryAabbsDataKHR-stride-03545]]
    pname:stride must: be a multiple of `8`
  * [[VUID-VkAccelerationStructureGeometryAabbsDataKHR-stride-03820]]
    pname:stride must: be less than or equal to [eq]#2^32^-1#
****

include::{generated}/validity/structs/VkAccelerationStructureGeometryAabbsDataKHR.adoc[]
--
endif::VK_KHR_acceleration_structure[]

[open,refpage='VkAabbPositionsKHR',desc='Structure specifying two opposing corners of an axis-aligned bounding box',type='structs',alias='VkAabbPositionsNV']
--
:refpage: VkAabbPositionsKHR

The sname:VkAabbPositionsKHR structure is defined as:

include::{generated}/api/structs/VkAabbPositionsKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/structs/VkAabbPositionsNV.adoc[]
endif::VK_NV_ray_tracing[]

  * pname:minX is the x position of one opposing corner of a bounding box.
  * pname:minY is the y position of one opposing corner of a bounding box.
  * pname:minZ is the z position of one opposing corner of a bounding box.
  * pname:maxX is the x position of the other opposing corner of a bounding
    box.
  * pname:maxY is the y position of the other opposing corner of a bounding
    box.
  * pname:maxZ is the z position of the other opposing corner of a bounding
    box.

.Valid Usage
****
  * [[VUID-VkAabbPositionsKHR-minX-03546]]
    pname:minX must: be less than or equal to pname:maxX
  * [[VUID-VkAabbPositionsKHR-minY-03547]]
    pname:minY must: be less than or equal to pname:maxY
  * [[VUID-VkAabbPositionsKHR-minZ-03548]]
    pname:minZ must: be less than or equal to pname:maxZ
****

include::{generated}/validity/structs/VkAabbPositionsKHR.adoc[]
--

ifdef::VK_KHR_acceleration_structure[]
[open,refpage='VkAccelerationStructureGeometryInstancesDataKHR',desc='Structure specifying a geometry consisting of instances of other acceleration structures',type='structs']
--
:refpage: VkAccelerationStructureGeometryInstancesDataKHR

The sname:VkAccelerationStructureGeometryInstancesDataKHR structure is
defined as:

include::{generated}/api/structs/VkAccelerationStructureGeometryInstancesDataKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:arrayOfPointers specifies whether pname:data is used as an array
    of addresses or just an array.
  * pname:data is either the address of an array of device or host addresses
    referencing individual slink:VkAccelerationStructureInstanceKHR
    structures
ifdef::VK_NV_ray_tracing_motion_blur[]
    or packed motion instance information as described in
    <<acceleration-structure-motion-instances, motion instances>>
endif::VK_NV_ray_tracing_motion_blur[]
    if pname:arrayOfPointers is ename:VK_TRUE, or the address of an array of
    slink:VkAccelerationStructureInstanceKHR
ifdef::VK_NV_ray_tracing_motion_blur[]
    or slink:VkAccelerationStructureMotionInstanceNV
endif::VK_NV_ray_tracing_motion_blur[]
    structures.
    Addresses and slink:VkAccelerationStructureInstanceKHR structures are
    tightly packed.
ifdef::VK_NV_ray_tracing_motion_blur[]
    slink:VkAccelerationStructureMotionInstanceNV structures have a stride
    of 160 bytes.
endif::VK_NV_ray_tracing_motion_blur[]

include::{generated}/validity/structs/VkAccelerationStructureGeometryInstancesDataKHR.adoc[]
--
endif::VK_KHR_acceleration_structure[]

[open,refpage='VkAccelerationStructureInstanceKHR',desc='Structure specifying a single acceleration structure instance for building into an acceleration structure geometry',type='structs',alias='VkAccelerationStructureInstanceNV']
--
:refpage: VkAccelerationStructureInstanceKHR

_Acceleration structure instances_ can: be built into top-level acceleration
structures.
Each acceleration structure instance is a separate entry in the top-level
acceleration structure which includes all the geometry of a bottom-level
acceleration structure at a transformed location.
Multiple instances can: point to the same bottom level acceleration
structure.

An acceleration structure instance is defined by the structure:

include::{generated}/api/structs/VkAccelerationStructureInstanceKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/structs/VkAccelerationStructureInstanceNV.adoc[]
endif::VK_NV_ray_tracing[]

  * pname:transform is a slink:VkTransformMatrixKHR structure describing a
    transformation to be applied to the acceleration structure.
  * pname:instanceCustomIndex is a 24-bit user-specified index value
    accessible to ray shaders in the code:InstanceCustomIndexKHR built-in.
  * pname:mask is an 8-bit visibility mask for the geometry.
    The instance may: only be hit if `Cull Mask & instance.mask != 0`
  * pname:instanceShaderBindingTableRecordOffset is a 24-bit offset used in
    calculating the hit shader binding table index.
  * pname:flags is an 8-bit mask of elink:VkGeometryInstanceFlagBitsKHR
    values to apply to this instance.
  * pname:accelerationStructureReference is either:
  ** a device address containing the value obtained from
ifdef::VK_KHR_acceleration_structure[flink:vkGetAccelerationStructureDeviceAddressKHR]
ifdef::VK_KHR_acceleration_structure+VK_NV_ray_tracing[or]
ifdef::VK_NV_ray_tracing[flink:vkGetAccelerationStructureHandleNV]
     (used by device operations which reference acceleration structures) or,
  ** a slink:VkAccelerationStructureKHR object (used by host operations
     which reference acceleration structures).

The C language specification does not define the ordering of bit-fields, but
in practice, this struct produces the correct layout with existing
compilers.
The intended bit pattern is for the following:

  * pname:instanceCustomIndex and pname:mask occupy the same memory as if a
    single code:uint32_t was specified in their place
  ** pname:instanceCustomIndex occupies the 24 least significant bits of
     that memory
  ** pname:mask occupies the 8 most significant bits of that memory
  * pname:instanceShaderBindingTableRecordOffset and pname:flags occupy the
    same memory as if a single code:uint32_t was specified in their place
  ** pname:instanceShaderBindingTableRecordOffset occupies the 24 least
     significant bits of that memory
  ** pname:flags occupies the 8 most significant bits of that memory

If a compiler produces code that diverges from that pattern, applications
must: employ another method to set values according to the correct bit
pattern.

include::{generated}/validity/structs/VkAccelerationStructureInstanceKHR.adoc[]
--

[open,refpage='VkGeometryInstanceFlagBitsKHR',desc='Instance flag bits',type='enums',alias='VkGeometryInstanceFlagBitsNV']
--
:refpage: VkGeometryInstanceFlagBitsKHR

Possible values of pname:flags in the instance modifying the behavior of
that instance are:

include::{generated}/api/enums/VkGeometryInstanceFlagBitsKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/enums/VkGeometryInstanceFlagBitsNV.adoc[]
endif::VK_NV_ray_tracing[]

  * ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR disables
    face culling for this instance.
  * ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR indicates that
    the <<ray-traversal-culling-face, facing determination>> for geometry in
    this instance is inverted.
    Because the facing is determined in object space, an instance transform
    does not change the winding, but a geometry transform does.
  * ename:VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR causes this instance to
    act as though ename:VK_GEOMETRY_OPAQUE_BIT_KHR were specified on all
    geometries referenced by this instance.
    This behavior can: be overridden by the SPIR-V code:NoOpaqueKHR ray
    flag.
  * ename:VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR causes this instance
    to act as though ename:VK_GEOMETRY_OPAQUE_BIT_KHR were not specified on
    all geometries referenced by this instance.
    This behavior can: be overridden by the SPIR-V code:OpaqueKHR ray flag.

ename:VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR and
ename:VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR must: not be used in the
same flag.
--

[open,refpage='VkGeometryInstanceFlagsKHR',desc='Bitmask of VkGeometryInstanceFlagBitsKHR',type='flags',alias='VkGeometryInstanceFlagsNV']
--
:refpage: VkGeometryInstanceFlagsKHR

include::{generated}/api/flags/VkGeometryInstanceFlagsKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/flags/VkGeometryInstanceFlagsNV.adoc[]
endif::VK_NV_ray_tracing[]

tname:VkGeometryInstanceFlagsKHR is a bitmask type for setting a mask of
zero or more elink:VkGeometryInstanceFlagBitsKHR.
--

ifdef::VK_NV_ray_tracing_motion_blur[]
[open,refpage='VkAccelerationStructureMotionInstanceNV',desc='Structure specifying a single acceleration structure motion instance for building into an acceleration structure geometry',type='structs']
--
:refpage: VkAccelerationStructureMotionInstanceNV

_Acceleration structure motion instances_ can: be built into top-level
acceleration structures.
Each acceleration structure instance is a separate entry in the top-level
acceleration structure which includes all the geometry of a bottom-level
acceleration structure at a transformed location including a type of motion
and parameters to determine the motion of the instance over time.

An acceleration structure motion instance is defined by the structure:

include::{generated}/api/structs/VkAccelerationStructureMotionInstanceNV.adoc[]

  * pname:type is a elink:VkAccelerationStructureMotionInstanceTypeNV
    enumerant identifying which type of motion instance this is and which
    type of the union is valid.
  * pname:flags is currently unused, but is required to keep natural
    alignment of pname:data.
  * pname:data is a slink:VkAccelerationStructureMotionInstanceDataNV
    containing motion instance data for this instance.

[NOTE]
.Note
====
If writing this other than with a standard C compiler, note that the final
structure should be 152 bytes in size.
====

include::{generated}/validity/structs/VkAccelerationStructureMotionInstanceNV.adoc[]
--

[open,refpage='VkAccelerationStructureMotionInstanceDataNV',desc='Union specifying a acceleration structure motion instance data for building into an acceleration structure geometry',type='structs']
--
:refpage: VkAccelerationStructureMotionInstanceDataNV

Acceleration structure motion instance is defined by the union:

include::{generated}/api/structs/VkAccelerationStructureMotionInstanceDataNV.adoc[]

  * pname:staticInstance is a slink:VkAccelerationStructureInstanceKHR
    structure containing data for a static instance.
  * pname:matrixMotionInstance is a
    slink:VkAccelerationStructureMatrixMotionInstanceNV structure containing
    data for a matrix motion instance.
  * pname:srtMotionInstance is a
    slink:VkAccelerationStructureSRTMotionInstanceNV structure containing
    data for an SRT motion instance.

include::{generated}/validity/structs/VkAccelerationStructureMotionInstanceDataNV.adoc[]
--

[open,refpage='VkAccelerationStructureMotionInstanceFlagsNV',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkAccelerationStructureMotionInstanceFlagsNV.adoc[]

tname:VkAccelerationStructureMotionInstanceFlagsNV is a bitmask type for
setting a mask, but is currently reserved for future use.
--

[open,refpage='VkAccelerationStructureMotionInstanceTypeNV',desc='Enum specifying a type of acceleration structure motion instance data for building into an acceleration structure geometry',type='enums']
--
:refpage: VkAccelerationStructureMotionInstanceTypeNV

The ename:VkAccelerationStructureMotionInstanceTypeNV enumeration is defined
as:

include::{generated}/api/enums/VkAccelerationStructureMotionInstanceTypeNV.adoc[]

  * ename:VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV specifies
    that the instance is a static instance with no instance motion.
  * ename:VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MATRIX_MOTION_NV
    specifies that the instance is a motion instance with motion specified
    by interpolation between two matrices.
  * ename:VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_SRT_MOTION_NV
    specifies that the instance is a motion instance with motion specified
    by interpolation in the SRT decomposition.
--

[open,refpage='VkAccelerationStructureMatrixMotionInstanceNV',desc='Structure specifying a single acceleration structure matrix motion instance for building into an acceleration structure geometry',type='structs']
--
:refpage: VkAccelerationStructureMatrixMotionInstanceNV

An acceleration structure matrix motion instance is defined by the
structure:

include::{generated}/api/structs/VkAccelerationStructureMatrixMotionInstanceNV.adoc[]

  * pname:transformT0 is a slink:VkTransformMatrixKHR structure describing a
    transformation to be applied to the acceleration structure at time 0.
  * pname:transformT1 is a slink:VkTransformMatrixKHR structure describing a
    transformation to be applied to the acceleration structure at time 1.
  * pname:instanceCustomIndex is a 24-bit user-specified index value
    accessible to ray shaders in the code:InstanceCustomIndexKHR built-in.
  * pname:mask is an 8-bit visibility mask for the geometry.
    The instance may: only be hit if `Cull Mask & instance.mask != 0`
  * pname:instanceShaderBindingTableRecordOffset is a 24-bit offset used in
    calculating the hit shader binding table index.
  * pname:flags is an 8-bit mask of elink:VkGeometryInstanceFlagBitsKHR
    values to apply to this instance.
  * pname:accelerationStructureReference is either:
  ** a device address containing the value obtained from
ifdef::VK_KHR_acceleration_structure[flink:vkGetAccelerationStructureDeviceAddressKHR]
ifdef::VK_KHR_acceleration_structure+VK_NV_ray_tracing[or]
ifdef::VK_NV_ray_tracing[flink:vkGetAccelerationStructureHandleNV]
     (used by device operations which reference acceleration structures) or,
  ** a slink:VkAccelerationStructureKHR object (used by host operations
     which reference acceleration structures).

The C language specification does not define the ordering of bit-fields, but
in practice, this struct produces the correct layout with existing
compilers.
The intended bit pattern is for the following:

  * pname:instanceCustomIndex and pname:mask occupy the same memory as if a
    single code:uint32_t was specified in their place
  ** pname:instanceCustomIndex occupies the 24 least significant bits of
     that memory
  ** pname:mask occupies the 8 most significant bits of that memory
  * pname:instanceShaderBindingTableRecordOffset and pname:flags occupy the
    same memory as if a single code:uint32_t was specified in their place
  ** pname:instanceShaderBindingTableRecordOffset occupies the 24 least
     significant bits of that memory
  ** pname:flags occupies the 8 most significant bits of that memory

If a compiler produces code that diverges from that pattern, applications
must: employ another method to set values according to the correct bit
pattern.

The transform for a matrix motion instance at a point in time is derived by
component-wise linear interpolation of the two transforms.
That is, for a code:time in [0,1] the resulting transform is

  {empty}:: [eq]#pname:transformT0 {times} (1 - code:time) {plus}
            pname:transformT1 {times} code:time#

include::{generated}/validity/structs/VkAccelerationStructureMatrixMotionInstanceNV.adoc[]
--

[open,refpage='VkAccelerationStructureSRTMotionInstanceNV',desc='Structure specifying a single acceleration structure SRT motion instance for building into an acceleration structure geometry',type='structs']
--
:refpage: VkAccelerationStructureSRTMotionInstanceNV

An acceleration structure SRT motion instance is defined by the structure:

include::{generated}/api/structs/VkAccelerationStructureSRTMotionInstanceNV.adoc[]

  * pname:transformT0 is a slink:VkSRTDataNV structure describing a
    transformation to be applied to the acceleration structure at time 0.
  * pname:transformT1 is a slink:VkSRTDataNV structure describing a
    transformation to be applied to the acceleration structure at time 1.
  * pname:instanceCustomIndex is a 24-bit user-specified index value
    accessible to ray shaders in the code:InstanceCustomIndexKHR built-in.
  * pname:mask is an 8-bit visibility mask for the geometry.
    The instance may: only be hit if `Cull Mask & instance.mask != 0`
  * pname:instanceShaderBindingTableRecordOffset is a 24-bit offset used in
    calculating the hit shader binding table index.
  * pname:flags is an 8-bit mask of elink:VkGeometryInstanceFlagBitsKHR
    values to apply to this instance.
  * pname:accelerationStructureReference is either:
  ** a device address containing the value obtained from
ifdef::VK_KHR_acceleration_structure[flink:vkGetAccelerationStructureDeviceAddressKHR]
ifdef::VK_KHR_acceleration_structure+VK_NV_ray_tracing[or]
ifdef::VK_NV_ray_tracing[flink:vkGetAccelerationStructureHandleNV]
     (used by device operations which reference acceleration structures) or,
  ** a slink:VkAccelerationStructureKHR object (used by host operations
     which reference acceleration structures).

The C language specification does not define the ordering of bit-fields, but
in practice, this struct produces the correct layout with existing
compilers.
The intended bit pattern is for the following:

  * pname:instanceCustomIndex and pname:mask occupy the same memory as if a
    single code:uint32_t was specified in their place
  ** pname:instanceCustomIndex occupies the 24 least significant bits of
     that memory
  ** pname:mask occupies the 8 most significant bits of that memory
  * pname:instanceShaderBindingTableRecordOffset and pname:flags occupy the
    same memory as if a single code:uint32_t was specified in their place
  ** pname:instanceShaderBindingTableRecordOffset occupies the 24 least
     significant bits of that memory
  ** pname:flags occupies the 8 most significant bits of that memory

If a compiler produces code that diverges from that pattern, applications
must: employ another method to set values according to the correct bit
pattern.

The transform for a SRT motion instance at a point in time is derived from
component-wise linear interpolation of the two SRT transforms.
That is, for a code:time in [0,1] the resulting transform is

  {empty}:: [eq]#pname:transformT0 {times} (1 - code:time) {plus}
            pname:transformT1 {times} code:time#

include::{generated}/validity/structs/VkAccelerationStructureSRTMotionInstanceNV.adoc[]
--

[open,refpage='VkSRTDataNV',desc='Structure specifying a transform in SRT decomposition',type='structs']
--
:refpage: VkSRTDataNV

An acceleration structure SRT transform is defined by the structure:

include::{generated}/api/structs/VkSRTDataNV.adoc[]

  * pname:sx is the x component of the scale of the transform
  * pname:a is one component of the shear for the transform
  * pname:b is one component of the shear for the transform
  * pname:pvx is the x component of the pivot point of the transform
  * pname:sy is the y component of the scale of the transform
  * pname:c is one component of the shear for the transform
  * pname:pvy is the y component of the pivot point of the transform
  * pname:sz is the z component of the scale of the transform
  * pname:pvz is the z component of the pivot point of the transform
  * pname:qx is the x component of the rotation quaternion
  * pname:qy is the y component of the rotation quaternion
  * pname:qz is the z component of the rotation quaternion
  * pname:qw is the w component of the rotation quaternion
  * pname:tx is the x component of the post-rotation translation
  * pname:ty is the y component of the post-rotation translation
  * pname:tz is the z component of the post-rotation translation

This transform decomposition consists of three elements.
The first is a matrix S, consisting of a scale, shear, and translation,
usually used to define the pivot point of the following rotation.
This matrix is constructed from the parameters above by:

[latexmath]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
S =
\left(
    \begin{matrix}
        sx & a  & b  & pvx \\
        0  & sy & c  & pvy \\
        0  & 0  & sz & pvz
    \end{matrix}
\right)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The rotation quaternion is defined as:

  {empty}:: [eq]#code:R = [ pname:qx, pname:qy, pname:qz, pname:qw ]#

This is a rotation around a conceptual normalized axis [eq]#[ ax, ay, az ]#
of amount code:theta such that:

  {empty}:: [eq]#[ pname:qx, pname:qy, pname:qz ] = sin(code:theta/2)
            {times} [ code:ax, code:ay, code:az ]#

and

  {empty}:: [eq]#pname:qw = cos(code:theta/2)#

Finally, the transform has a translation T constructed from the parameters
above by:

[latexmath]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
T =
\left(
    \begin{matrix}
        1 & 0 & 0 & tx \\
        0 & 1 & 0 & ty \\
        0 & 0 & 1 & tz
    \end{matrix}
\right)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The effective derived transform is then given by

  {empty}:: [eq]#code:T {times} code:R {times} code:S#

include::{generated}/validity/structs/VkSRTDataNV.adoc[]
--
endif::VK_NV_ray_tracing_motion_blur[]

ifdef::VK_KHR_acceleration_structure[]
[open,refpage='VkAccelerationStructureBuildRangeInfoKHR',desc='Structure specifying build offsets and counts for acceleration structure builds',type='structs']
--
:refpage: VkAccelerationStructureBuildOffsetInfoKHR

sname:VkAccelerationStructureBuildRangeInfoKHR is defined as:

include::{generated}/api/structs/VkAccelerationStructureBuildRangeInfoKHR.adoc[]

  * pname:primitiveCount defines the number of primitives for a
    corresponding acceleration structure geometry.
  * pname:primitiveOffset defines an offset in bytes into the memory where
    primitive data is defined.
  * pname:firstVertex is the index of the first vertex to build from for
    triangle geometry.
  * pname:transformOffset defines an offset in bytes into the memory where a
    transform matrix is defined.

The primitive count and primitive offset are interpreted differently
depending on the elink:VkGeometryTypeKHR used:

  * For geometries of type ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR,
    pname:primitiveCount is the number of triangles to be built, where each
    triangle is treated as 3 vertices.
  ** If the geometry uses indices, [eq]#pname:primitiveCount {times} 3#
     indices are consumed from
     slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:indexData,
     starting at an offset of pname:primitiveOffset.
     The value of pname:firstVertex is added to the index values before
     fetching vertices.
  ** If the geometry does not use indices, [eq]#pname:primitiveCount {times}
     3# vertices are consumed from
     slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:vertexData,
     starting at an offset of [eq]#pname:primitiveOffset {plus}
     slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:vertexStride
     {times} pname:firstVertex#.
  ** If
     slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:transformData
     is not `NULL`, a single slink:VkTransformMatrixKHR structure is
     consumed from
     slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:transformData,
     at an offset of pname:transformOffset.
     This matrix describes a transformation from the space in which the
     vertices for all triangles in this geometry are described to the space
     in which the acceleration structure is defined.
  * For geometries of type ename:VK_GEOMETRY_TYPE_AABBS_KHR,
    pname:primitiveCount is the number of axis-aligned bounding boxes.
    pname:primitiveCount slink:VkAabbPositionsKHR structures are consumed
    from slink:VkAccelerationStructureGeometryAabbsDataKHR::pname:data,
    starting at an offset of pname:primitiveOffset.
  * For geometries of type ename:VK_GEOMETRY_TYPE_INSTANCES_KHR,
    pname:primitiveCount is the number of acceleration structures.
    pname:primitiveCount slink:VkAccelerationStructureInstanceKHR
ifdef::VK_NV_ray_tracing_motion_blur[]
    or slink:VkAccelerationStructureMotionInstanceNV
endif::VK_NV_ray_tracing_motion_blur[]
    structures are consumed from
    slink:VkAccelerationStructureGeometryInstancesDataKHR::pname:data,
    starting at an offset of pname:primitiveOffset.

.Valid Usage
****
  * [[VUID-VkAccelerationStructureBuildRangeInfoKHR-primitiveOffset-03656]]
    For geometries of type ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, if the
    geometry uses indices, the offset pname:primitiveOffset from
    slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:indexData
    must: be a multiple of the element size of
    slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:indexType
  * [[VUID-VkAccelerationStructureBuildRangeInfoKHR-primitiveOffset-03657]]
    For geometries of type ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, if the
    geometry does not use indices, the offset pname:primitiveOffset from
    slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:vertexData
    must: be a multiple of the component size of
    slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:vertexFormat
  * [[VUID-VkAccelerationStructureBuildRangeInfoKHR-transformOffset-03658]]
    For geometries of type ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, the offset
    pname:transformOffset from
    slink:VkAccelerationStructureGeometryTrianglesDataKHR::pname:transformData
    must: be a multiple of 16
  * [[VUID-VkAccelerationStructureBuildRangeInfoKHR-primitiveOffset-03659]]
    For geometries of type ename:VK_GEOMETRY_TYPE_AABBS_KHR, the offset
    pname:primitiveOffset from
    slink:VkAccelerationStructureGeometryAabbsDataKHR::pname:data must: be a
    multiple of 8
  * [[VUID-VkAccelerationStructureBuildRangeInfoKHR-primitiveOffset-03660]]
    For geometries of type ename:VK_GEOMETRY_TYPE_INSTANCES_KHR, the offset
    pname:primitiveOffset from
    slink:VkAccelerationStructureGeometryInstancesDataKHR::pname:data must:
    be a multiple of 16
****

include::{generated}/validity/structs/VkAccelerationStructureBuildRangeInfoKHR.adoc[]
--
endif::VK_KHR_acceleration_structure[]


[[acceleration-structure-copying]]
=== Copying Acceleration Structures

An additional command exists for copying acceleration structures without
updating their contents.
The acceleration structure object can: be compacted in order to improve
performance.
Before copying, an application must: query the size of the resulting
acceleration structure.

[open,refpage='vkCmdWriteAccelerationStructuresPropertiesKHR',desc='Write acceleration structure result parameters to query results.',type='protos']
--
:refpage: vkCmdWriteAccelerationStructuresPropertiesKHR

To query acceleration structure size parameters call:

ifdef::VK_KHR_acceleration_structure[]
include::{generated}/api/protos/vkCmdWriteAccelerationStructuresPropertiesKHR.adoc[]
endif::VK_KHR_acceleration_structure[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:accelerationStructureCount is the count of acceleration structures
    for which to query the property.
  * pname:pAccelerationStructures is a pointer to an array of existing
    previously built acceleration structures.
  * pname:queryType is a elink:VkQueryType value specifying the type of
    queries managed by the pool.
  * pname:queryPool is the query pool that will manage the results of the
    query.
  * pname:firstQuery is the first query index within the query pool that
    will contain the pname:accelerationStructureCount number of results.

Accesses to any of the acceleration structures listed in
pname:pAccelerationStructures must: be <<synchronization-dependencies,
synchronized>> with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR.

  * If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, then the
    value written out is the number of bytes required by a compacted
    acceleration structure.
  * If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, then
    the value written out is the number of bytes required by a serialized
    acceleration structure.

.Valid Usage
****
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesKHR-accelerationStructure-08924]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesKHR-queryPool-02493]]
    pname:queryPool must: have been created with a pname:queryType matching
    pname:queryType
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesKHR-queryPool-02494]]
    The queries identified by pname:queryPool and pname:firstQuery must: be
    _unavailable_
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesKHR-buffer-03736]]
    The pname:buffer used to create each acceleration structure in
    pname:pAccelerationStructures must: be bound to device memory
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesKHR-query-04880]]
    The sum of pname:query plus pname:accelerationStructureCount must: be
    less than or equal to the number of queries in pname:queryPool
include::{chapters}/commonvalidity/write_acceleration_structure_properties_common.adoc[]
****

include::{generated}/validity/protos/vkCmdWriteAccelerationStructuresPropertiesKHR.adoc[]
--

ifdef::VK_NV_ray_tracing[]
[open,refpage='vkCmdWriteAccelerationStructuresPropertiesNV',desc='Write acceleration structure result parameters to query results.',type='protos']
--
:refpage: vkCmdWriteAccelerationStructuresPropertiesNV

To query acceleration structure size parameters call:

include::{generated}/api/protos/vkCmdWriteAccelerationStructuresPropertiesNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:accelerationStructureCount is the count of acceleration structures
    for which to query the property.
  * pname:pAccelerationStructures is a pointer to an array of existing
    previously built acceleration structures.
  * pname:queryType is a elink:VkQueryType value specifying the type of
    queries managed by the pool.
  * pname:queryPool is the query pool that will manage the results of the
    query.
  * pname:firstQuery is the first query index within the query pool that
    will contain the pname:accelerationStructureCount number of results.

Accesses to any of the acceleration structures listed in
pname:pAccelerationStructures must: be <<synchronization-dependencies,
synchronized>> with the
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR.

.Valid Usage
****
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-queryPool-03755]]
    pname:queryPool must: have been created with a pname:queryType matching
    pname:queryType
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-queryPool-03756]]
    The queries identified by pname:queryPool and pname:firstQuery must: be
    _unavailable_
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-accelerationStructure-03757]]
    pname:accelerationStructure must: be bound completely and contiguously
    to a single sname:VkDeviceMemory object via
    flink:vkBindAccelerationStructureMemoryNV
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-pAccelerationStructures-04958]]
    All acceleration structures in pname:pAccelerationStructures must: have
    been built prior to the execution of this command
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-pAccelerationStructures-06215]]
    All acceleration structures in pname:pAccelerationStructures must: have
    been built with
    ename:VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR if
    pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV
  * [[VUID-vkCmdWriteAccelerationStructuresPropertiesNV-queryType-06216]]
    pname:queryType must: be
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV
****

include::{generated}/validity/protos/vkCmdWriteAccelerationStructuresPropertiesNV.adoc[]
--

[open,refpage='vkCmdCopyAccelerationStructureNV',desc='Copy an acceleration structure',type='protos']
--
:refpage: vkCmdCopyAccelerationStructureNV

To copy an acceleration structure call:

include::{generated}/api/protos/vkCmdCopyAccelerationStructureNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:dst is the target acceleration structure for the copy.
  * pname:src is the source acceleration structure for the copy.
  * pname:mode is a elink:VkCopyAccelerationStructureModeKHR value
    specifying additional operations to perform during the copy.

Accesses to pname:src and pname:dst must: be <<synchronization-dependencies,
synchronized>> with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR or
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR as appropriate.

.Valid Usage
****
include::{chapters}/commonvalidity/copy_acceleration_structure_common.adoc[]
****

include::{generated}/validity/protos/vkCmdCopyAccelerationStructureNV.adoc[]
--
endif::VK_NV_ray_tracing[]

ifdef::VK_KHR_acceleration_structure[]
[open,refpage='vkCmdCopyAccelerationStructureKHR',desc='Copy an acceleration structure',type='protos']
--
:refpage: vkCmdCopyAccelerationStructureKHR

To copy an acceleration structure call:

include::{generated}/api/protos/vkCmdCopyAccelerationStructureKHR.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:pInfo is a pointer to a slink:VkCopyAccelerationStructureInfoKHR
    structure defining the copy operation.

This command copies the pname:pInfo->src acceleration structure to the
pname:pInfo->dst acceleration structure in the manner specified by
pname:pInfo->mode.

Accesses to pname:pInfo->src and pname:pInfo->dst must: be
<<synchronization-dependencies, synchronized>> with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR or
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR as appropriate.

.Valid Usage
****
  * [[VUID-vkCmdCopyAccelerationStructureKHR-accelerationStructure-08925]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled
  * [[VUID-vkCmdCopyAccelerationStructureKHR-buffer-03737]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    device memory
  * [[VUID-vkCmdCopyAccelerationStructureKHR-buffer-03738]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    device memory
****

include::{generated}/validity/protos/vkCmdCopyAccelerationStructureKHR.adoc[]
--

[open,refpage='VkCopyAccelerationStructureInfoKHR',desc='Parameters for copying an acceleration structure',type='structs']
--
:refpage: VkCopyAccelerationStructureInfoKHR

The sname:VkCopyAccelerationStructureInfoKHR structure is defined as:

include::{generated}/api/structs/VkCopyAccelerationStructureInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:src is the source acceleration structure for the copy.
  * pname:dst is the target acceleration structure for the copy.
  * pname:mode is a elink:VkCopyAccelerationStructureModeKHR value
    specifying additional operations to perform during the copy.

.Valid Usage
****
include::{chapters}/commonvalidity/copy_acceleration_structure_common.adoc[]
****

include::{generated}/validity/structs/VkCopyAccelerationStructureInfoKHR.adoc[]
--
endif::VK_KHR_acceleration_structure[]

[open,refpage='VkCopyAccelerationStructureModeKHR',desc='Acceleration structure copy mode',type='enums',alias='VkCopyAccelerationStructureModeNV']
--
:refpage: VkCopyAccelerationStructureModeKHR

Possible values of pname:mode specifying additional operations to perform
during the copy, are:

include::{generated}/api/enums/VkCopyAccelerationStructureModeKHR.adoc[]

ifdef::VK_NV_ray_tracing[]
or the equivalent

include::{generated}/api/enums/VkCopyAccelerationStructureModeNV.adoc[]
endif::VK_NV_ray_tracing[]

  * ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR creates a direct
    copy of the acceleration structure specified in pname:src into the one
    specified by pname:dst.
    The pname:dst acceleration structure must: have been created with the
    same parameters as pname:src.
    If pname:src contains references to other acceleration structures,
    pname:dst will reference the same acceleration structures.
  * ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR creates a more
    compact version of an acceleration structure pname:src into pname:dst.
    The acceleration structure pname:dst must: have been created with a size
    at least as large as that returned by
    flink:vkCmdWriteAccelerationStructuresPropertiesKHR
ifdef::VK_KHR_acceleration_structure[]
    or flink:vkWriteAccelerationStructuresPropertiesKHR
endif::VK_KHR_acceleration_structure[]
    after the build of the acceleration structure specified by pname:src.
    If pname:src contains references to other acceleration structures,
    pname:dst will reference the same acceleration structures.
  * ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR serializes the
    acceleration structure to a semi-opaque format which can be reloaded on
    a compatible implementation.
  * ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR deserializes
    the semi-opaque serialization format in the buffer to the acceleration
    structure.
--

[open,refpage='vkCmdCopyAccelerationStructureToMemoryKHR',desc='Copy an acceleration structure to device memory',type='protos']
--
:refpage: vkCmdCopyAccelerationStructureToMemoryKHR

To copy an acceleration structure to device memory call:

include::{generated}/api/protos/vkCmdCopyAccelerationStructureToMemoryKHR.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:pInfo is an a pointer to a
    slink:VkCopyAccelerationStructureToMemoryInfoKHR structure defining the
    copy operation.

Accesses to pname:pInfo->src must: be <<synchronization-dependencies,
synchronized>> with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR.
Accesses to the buffer indicated by pname:pInfo->dst.deviceAddress must: be
synchronized with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an and an access
type of ename:VK_ACCESS_TRANSFER_WRITE_BIT.

This command produces the same results as
flink:vkCopyAccelerationStructureToMemoryKHR, but writes its result to a
device address, and is executed on the device rather than the host.
The output may: not necessarily be bit-for-bit identical, but it can be
equally used by either flink:vkCmdCopyMemoryToAccelerationStructureKHR or
flink:vkCopyMemoryToAccelerationStructureKHR.

[[serialized-as-header]]
The defined header structure for the serialized data consists of:

  * ename:VK_UUID_SIZE bytes of data matching
    sname:VkPhysicalDeviceIDProperties::pname:driverUUID
  * ename:VK_UUID_SIZE bytes of data identifying the compatibility for
    comparison using flink:vkGetDeviceAccelerationStructureCompatibilityKHR
  * A 64-bit integer of the total size matching the value queried using
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR
  * A 64-bit integer of the deserialized size to be passed in to
    sname:VkAccelerationStructureCreateInfoKHR::pname:size
  * A 64-bit integer of the count of the number of acceleration structure
    handles following.
ifdef::VK_KHR_ray_tracing_maintenance1[]
    This value matches the value queried using
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR.
endif::VK_KHR_ray_tracing_maintenance1[]
    This will be zero for a bottom-level acceleration structure.
    For top-level acceleration structures this number is
    implementation-dependent; the number of and ordering of the handles may
    not match the instance descriptions which were used to build the
    acceleration structure.

The corresponding handles matching the values returned by
ifdef::VK_KHR_acceleration_structure[flink:vkGetAccelerationStructureDeviceAddressKHR]
ifdef::VK_KHR_acceleration_structure+VK_NV_ray_tracing[or]
ifdef::VK_NV_ray_tracing[flink:vkGetAccelerationStructureHandleNV]
are tightly packed in the buffer following the count.
The application is expected to store a mapping between those handles and the
original application-generated bottom-level acceleration structures to
provide when deserializing.
The serialized data is written to the buffer (or read from the buffer)
according to the host endianness.

.Valid Usage
****
  * [[VUID-vkCmdCopyAccelerationStructureToMemoryKHR-accelerationStructure-08926]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled
  * [[VUID-vkCmdCopyAccelerationStructureToMemoryKHR-pInfo-03739]]
    pname:pInfo->dst.deviceAddress must: be a valid device address for a
    buffer bound to device memory
  * [[VUID-vkCmdCopyAccelerationStructureToMemoryKHR-pInfo-03740]]
    pname:pInfo->dst.deviceAddress must: be aligned to `256` bytes
  * [[VUID-vkCmdCopyAccelerationStructureToMemoryKHR-pInfo-03741]]
    If the buffer pointed to by pname:pInfo->dst.deviceAddress is non-sparse
    then it must: be bound completely and contiguously to a single
    slink:VkDeviceMemory object
  * [[VUID-vkCmdCopyAccelerationStructureToMemoryKHR-None-03559]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    device memory
****

include::{generated}/validity/protos/vkCmdCopyAccelerationStructureToMemoryKHR.adoc[]
--

[open,refpage='VkCopyAccelerationStructureToMemoryInfoKHR',desc='Parameters for serializing an acceleration structure',type='structs']
--
:refpage: VkCopyAccelerationStructureToMemoryInfoKHR

include::{generated}/api/structs/VkCopyAccelerationStructureToMemoryInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:src is the source acceleration structure for the copy
  * pname:dst is the device or host address to memory which is the target
    for the copy
  * pname:mode is a elink:VkCopyAccelerationStructureModeKHR value
    specifying additional operations to perform during the copy.

.Valid Usage
****
  * [[VUID-VkCopyAccelerationStructureToMemoryInfoKHR-src-04959]]
    The source acceleration structure pname:src must: have been constructed
    prior to the execution of this command
  * [[VUID-VkCopyAccelerationStructureToMemoryInfoKHR-dst-03561]]
    The memory pointed to by pname:dst must: be at least as large as the
    serialization size of pname:src, as reported by
    flink:vkWriteAccelerationStructuresPropertiesKHR or
    flink:vkCmdWriteAccelerationStructuresPropertiesKHR with a query type of
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR
  * [[VUID-VkCopyAccelerationStructureToMemoryInfoKHR-mode-03412]]
    pname:mode must: be
    ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR
****

include::{generated}/validity/structs/VkCopyAccelerationStructureToMemoryInfoKHR.adoc[]
--

[open,refpage='vkCmdCopyMemoryToAccelerationStructureKHR',desc='Copy device memory to an acceleration structure',type='protos']
--
:refpage: vkCmdCopyMemoryToAccelerationStructureKHR

To copy device memory to an acceleration structure call:

include::{generated}/api/protos/vkCmdCopyMemoryToAccelerationStructureKHR.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:pInfo is a pointer to a
    slink:VkCopyMemoryToAccelerationStructureInfoKHR structure defining the
    copy operation.

Accesses to pname:pInfo->dst must: be <<synchronization-dependencies,
synchronized>> with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an
<<synchronization-access-types, access type>> of
ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR.
Accesses to the buffer indicated by pname:pInfo->src.deviceAddress must: be
synchronized with the
ifdef::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>> or the
endif::VK_KHR_synchronization2[]
ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
<<synchronization-pipeline-stages, pipeline stage>>, and an access type of
ename:VK_ACCESS_TRANSFER_READ_BIT.

This command can accept acceleration structures produced by either
flink:vkCmdCopyAccelerationStructureToMemoryKHR or
flink:vkCopyAccelerationStructureToMemoryKHR.

The structure provided as input to deserialize is as described in
flink:vkCmdCopyAccelerationStructureToMemoryKHR, with any acceleration
structure handles filled in with the newly-queried handles to bottom level
acceleration structures created before deserialization.
These do not need to be built at deserialize time, but must: be created.

.Valid Usage
****
  * [[VUID-vkCmdCopyMemoryToAccelerationStructureKHR-accelerationStructure-08927]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled
  * [[VUID-vkCmdCopyMemoryToAccelerationStructureKHR-pInfo-03742]]
    pname:pInfo->src.deviceAddress must: be a valid device address for a
    buffer bound to device memory
  * [[VUID-vkCmdCopyMemoryToAccelerationStructureKHR-pInfo-03743]]
    pname:pInfo->src.deviceAddress must: be aligned to `256` bytes
  * [[VUID-vkCmdCopyMemoryToAccelerationStructureKHR-pInfo-03744]]
    If the buffer pointed to by pname:pInfo->src.deviceAddress is non-sparse
    then it must: be bound completely and contiguously to a single
    slink:VkDeviceMemory object
  * [[VUID-vkCmdCopyMemoryToAccelerationStructureKHR-buffer-03745]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    device memory
****

include::{generated}/validity/protos/vkCmdCopyMemoryToAccelerationStructureKHR.adoc[]
--

[open,refpage='VkCopyMemoryToAccelerationStructureInfoKHR',desc='Parameters for deserializing an acceleration structure',type='structs']
--
:refpage: VkCopyMemoryToAccelerationStructureInfoKHR

The sname:VkCopyMemoryToAccelerationStructureInfoKHR structure is defined
as:

include::{generated}/api/structs/VkCopyMemoryToAccelerationStructureInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:src is the device or host address to memory containing the source
    data for the copy.
  * pname:dst is the target acceleration structure for the copy.
  * pname:mode is a elink:VkCopyAccelerationStructureModeKHR value
    specifying additional operations to perform during the copy.

.Valid Usage
****
  * [[VUID-VkCopyMemoryToAccelerationStructureInfoKHR-src-04960]]
    The source memory pointed to by pname:src must: contain data previously
    serialized using flink:vkCmdCopyAccelerationStructureToMemoryKHR,
    potentially modified to relocate acceleration structure references as
    described in that command
  * [[VUID-VkCopyMemoryToAccelerationStructureInfoKHR-mode-03413]]
    pname:mode must: be
    ename:VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR
  * [[VUID-VkCopyMemoryToAccelerationStructureInfoKHR-pInfo-03414]]
    The data in pname:src must: have a format compatible with the
    destination physical device as returned by
    flink:vkGetDeviceAccelerationStructureCompatibilityKHR
  * [[VUID-VkCopyMemoryToAccelerationStructureInfoKHR-dst-03746]]
    pname:dst must: have been created with a pname:size greater than or
    equal to that used to serialize the data in pname:src
****

include::{generated}/validity/structs/VkCopyMemoryToAccelerationStructureInfoKHR.adoc[]
--

[open,refpage='vkGetDeviceAccelerationStructureCompatibilityKHR',desc='Check if a serialized acceleration structure is compatible with the current device',type='protos']
--
:refpage: vkGetDeviceAccelerationStructureCompatibilityKHR

To check if a serialized acceleration structure is compatible with the
current device call:

include::{generated}/api/protos/vkGetDeviceAccelerationStructureCompatibilityKHR.adoc[]

  * pname:device is the device to check the version against.
  * pname:pVersionInfo is a pointer to a
    slink:VkAccelerationStructureVersionInfoKHR structure specifying version
    information to check against the device.
  * pname:pCompatibility is a pointer to a
    elink:VkAccelerationStructureCompatibilityKHR value in which
    compatibility information is returned.

.Valid Usage
****
  * [[VUID-vkGetDeviceAccelerationStructureCompatibilityKHR-accelerationStructure-08928]]
    The <<features-accelerationStructure,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructure>>
    feature must: be enabled
****

include::{generated}/validity/protos/vkGetDeviceAccelerationStructureCompatibilityKHR.adoc[]
--

[open,refpage='VkAccelerationStructureVersionInfoKHR',desc='Acceleration structure version information',type='structs']
--
:refpage: VkAccelerationStructureVersionKHR

The sname:VkAccelerationStructureVersionInfoKHR structure is defined as:

include::{generated}/api/structs/VkAccelerationStructureVersionInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:pVersionData is a pointer to the version header of an acceleration
    structure as defined in flink:vkCmdCopyAccelerationStructureToMemoryKHR

[NOTE]
.Note
====
pname:pVersionData is a _pointer_ to an array of 2{times}ename:VK_UUID_SIZE
code:uint8_t values instead of two ename:VK_UUID_SIZE arrays as the expected
use case for this member is to be pointed at the header of a previously
serialized acceleration structure (via
flink:vkCmdCopyAccelerationStructureToMemoryKHR or
flink:vkCopyAccelerationStructureToMemoryKHR) that is loaded in memory.
Using arrays would necessitate extra memory copies of the UUIDs.
====

include::{generated}/validity/structs/VkAccelerationStructureVersionInfoKHR.adoc[]
--

[open,refpage='VkAccelerationStructureCompatibilityKHR',desc='Acceleration structure compatibility',type='enums']
--
Possible values of pname:pCompatibility returned by
flink:vkGetDeviceAccelerationStructureCompatibilityKHR are:

include::{generated}/api/enums/VkAccelerationStructureCompatibilityKHR.adoc[]

  * ename:VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR if the
    pname:pVersionData version acceleration structure is compatible with
    pname:device.
  * ename:VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR if the
    pname:pVersionData version acceleration structure is not compatible with
    pname:device.
--


[[host-acceleration-structure]]
== Host Acceleration Structure Operations

Implementations are also required to provide host implementations of the
acceleration structure operations if the
<<features-accelerationStructureHostCommands,
pname:accelerationStructureHostCommands>> feature is enabled:

  * flink:vkBuildAccelerationStructuresKHR corresponding to
    flink:vkCmdBuildAccelerationStructuresKHR
  * flink:vkCopyAccelerationStructureKHR corresponding to
    flink:vkCmdCopyAccelerationStructureKHR
  * flink:vkCopyAccelerationStructureToMemoryKHR corresponding to
    flink:vkCmdCopyAccelerationStructureToMemoryKHR
  * flink:vkCopyMemoryToAccelerationStructureKHR corresponding to
    flink:vkCmdCopyMemoryToAccelerationStructureKHR
  * flink:vkWriteAccelerationStructuresPropertiesKHR corresponding to
    flink:vkCmdWriteAccelerationStructuresPropertiesKHR

These commands are functionally equivalent to their device counterparts,
except that they are executed on the host timeline, rather than being
enqueued into command buffers.

All acceleration structures used by the host commands must: be bound to
host-visible memory, and all input data for acceleration structure builds
must: be referenced using host addresses instead of device addresses.
Applications are not required to map acceleration structure memory when
using the host commands.


[NOTE]
.Note
====
The flink:vkBuildAccelerationStructuresKHR and
flink:vkCmdBuildAccelerationStructuresKHR may: use different algorithms, and
thus are not required to produce identical structures.
The structures produced by these two commands may: exhibit different memory
footprints or traversal performance, but should strive to be similar where
possible.

Apart from these details, the host and device operations are
interchangeable.
For example, an application can: use flink:vkBuildAccelerationStructuresKHR
to build a structure, compact it on the device using
flink:vkCmdCopyAccelerationStructureKHR, and serialize the result using
flink:vkCopyAccelerationStructureToMemoryKHR.
====

[NOTE]
.Note
====
For efficient execution, acceleration structures manipulated using these
commands should always be bound to host cached memory, as the implementation
may need to repeatedly read and write this memory during the execution of
the command.
====

[open,refpage='vkBuildAccelerationStructuresKHR',desc='Build an acceleration structure on the host',type='protos']
--
:refpage: vkBuildAccelerationStructuresKHR

To build acceleration structures on the host, call:

include::{generated}/api/protos/vkBuildAccelerationStructuresKHR.adoc[]

  * pname:device is the sname:VkDevice for which the acceleration structures
    are being built.
  * pname:deferredOperation is an optional slink:VkDeferredOperationKHR to
    <<deferred-host-operations-requesting, request deferral>> for this
    command.
  * pname:infoCount is the number of acceleration structures to build.
    It specifies the number of the pname:pInfos structures and
    pname:ppBuildRangeInfos pointers that must: be provided.
  * pname:pInfos is a pointer to an array of pname:infoCount
    slink:VkAccelerationStructureBuildGeometryInfoKHR structures defining
    the geometry used to build each acceleration structure.
  * pname:ppBuildRangeInfos is a pointer to an array of pname:infoCount
    pointers to arrays of slink:VkAccelerationStructureBuildRangeInfoKHR
    structures.
    Each pname:ppBuildRangeInfos[i] is a pointer to an array of
    pname:pInfos[i].pname:geometryCount
    slink:VkAccelerationStructureBuildRangeInfoKHR structures defining
    dynamic offsets to the addresses where geometry data is stored, as
    defined by pname:pInfos[i].

This command fulfills the same task as
flink:vkCmdBuildAccelerationStructuresKHR but is executed by the host.

The fname:vkBuildAccelerationStructuresKHR command provides the ability to
initiate multiple acceleration structures builds, however there is no
ordering or synchronization implied between any of the individual
acceleration structure builds.

[NOTE]
.Note
====
This means that an application cannot: build a top-level acceleration
structure in the same flink:vkBuildAccelerationStructuresKHR call as the
associated bottom-level or instance acceleration structures are being built.
There also cannot: be any memory aliasing between any acceleration structure
memories or scratch memories being used by any of the builds.
====

.Valid Usage
****
  * [[VUID-vkBuildAccelerationStructuresKHR-accelerationStructureHostCommands-03581]]
    The <<features-accelerationStructureHostCommands,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureHostCommands>>
    feature must: be enabled

:maxinstancecheck: pname:ppBuildRangeInfos[i][j].pname:primitiveCount
include::{chapters}/commonvalidity/build_acceleration_structure_common.adoc[]
include::{chapters}/commonvalidity/build_acceleration_structure_nonindirect_common.adoc[]
include::{chapters}/commonvalidity/deferred_operations_common.adoc[]
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03722]]
    For each element of pname:pInfos, the pname:buffer used to create its
    pname:dstAccelerationStructure member must: be bound to host-visible
    device memory
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03723]]
    For each element of pname:pInfos, if its pname:mode member is
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR the pname:buffer
    used to create its pname:srcAccelerationStructure member must: be bound
    to host-visible device memory
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03724]]
    For each element of pname:pInfos, the pname:buffer used to create each
    acceleration structure referenced by the pname:geometry.instances.data
    member of any element of pname:pGeometries or pname:ppGeometries with a
    pname:geometryType of ename:VK_GEOMETRY_TYPE_INSTANCES_KHR must: be
    bound to host-visible device memory
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03725]]
    If pname:pInfos[i].pname:mode is
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, all addresses
    between pname:pInfos[i].pname:scratchData.hostAddress and
    pname:pInfos[i].pname:scratchData.hostAddress + N - 1 must: be valid
    host memory, where N is given by the pname:buildScratchSize member of
    the slink:VkAccelerationStructureBuildSizesInfoKHR structure returned
    from a call to flink:vkGetAccelerationStructureBuildSizesKHR with an
    identical slink:VkAccelerationStructureBuildGeometryInfoKHR structure
    and primitive count
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03726]]
    If pname:pInfos[i].pname:mode is
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR, all addresses
    between pname:pInfos[i].pname:scratchData.hostAddress and
    pname:pInfos[i].pname:scratchData.hostAddress + N - 1 must: be valid
    host memory, where N is given by the pname:updateScratchSize member of
    the slink:VkAccelerationStructureBuildSizesInfoKHR structure returned
    from a call to flink:vkGetAccelerationStructureBuildSizesKHR with an
    identical slink:VkAccelerationStructureBuildGeometryInfoKHR structure
    and primitive count
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03771]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR,
    pname:geometry.triangles.vertexData.hostAddress must: be a valid host
    address
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03772]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, if
    pname:geometry.triangles.indexType is not ename:VK_INDEX_TYPE_NONE_KHR,
    pname:geometry.triangles.indexData.hostAddress must: be a valid host
    address
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03773]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR, if
    pname:geometry.triangles.transformData.hostAddress is not `0`, it must:
    be a valid host address
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03774]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_AABBS_KHR, pname:geometry.aabbs.data.hostAddress
    must: be a valid host address
ifdef::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03775]]
    For each element of pname:pInfos, the pname:buffer used to create its
    pname:dstAccelerationStructure member must: be bound to memory that was
    not allocated with multiple instances
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03776]]
    For each element of pname:pInfos, if its pname:mode member is
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR the pname:buffer
    used to create its pname:srcAccelerationStructure member must: be bound
    to memory that was not allocated with multiple instances
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03777]]
    For each element of pname:pInfos, the pname:buffer used to create each
    acceleration structure referenced by the pname:geometry.instances.data
    member of any element of pname:pGeometries or pname:ppGeometries with a
    pname:geometryType of ename:VK_GEOMETRY_TYPE_INSTANCES_KHR must: be
    bound to memory that was not allocated with multiple instances
endif::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03778]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_INSTANCES_KHR,
    pname:geometry.instances.data.hostAddress must: be a valid host address
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-03779]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_INSTANCES_KHR, each
    slink:VkAccelerationStructureInstanceKHR::pname:accelerationStructureReference
    value in pname:geometry.instances.data.hostAddress must: be a valid
    slink:VkAccelerationStructureKHR object
ifdef::VK_NV_ray_tracing_motion_blur[]
  * [[VUID-vkBuildAccelerationStructuresKHR-pInfos-04930]]
    For any element of pname:pInfos[i].pname:pGeometries or
    pname:pInfos[i].pname:ppGeometries with a pname:geometryType of
    ename:VK_GEOMETRY_TYPE_INSTANCES_KHR with
    ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV set, each
    pname:accelerationStructureReference in any structure in
    slink:VkAccelerationStructureMotionInstanceNV value in
    pname:geometry.instances.data.hostAddress must: be a valid
    slink:VkAccelerationStructureKHR object
endif::VK_NV_ray_tracing_motion_blur[]
****

include::{generated}/validity/protos/vkBuildAccelerationStructuresKHR.adoc[]
--

[open,refpage='vkCopyAccelerationStructureKHR',desc='Copy an acceleration structure on the host',type='protos']
--
:refpage: vkCopyAccelerationStructureKHR

To copy or compact an acceleration structure on the host, call:

include::{generated}/api/protos/vkCopyAccelerationStructureKHR.adoc[]

  * pname:device is the device which owns the acceleration structures.
  * pname:deferredOperation is an optional slink:VkDeferredOperationKHR to
    <<deferred-host-operations-requesting, request deferral>> for this
    command.
  * pname:pInfo is a pointer to a slink:VkCopyAccelerationStructureInfoKHR
    structure defining the copy operation.

This command fulfills the same task as
flink:vkCmdCopyAccelerationStructureKHR but is executed by the host.

.Valid Usage
****
  * [[VUID-vkCopyAccelerationStructureKHR-accelerationStructureHostCommands-03582]]
    The <<features-accelerationStructureHostCommands,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureHostCommands>>
include::{chapters}/commonvalidity/deferred_operations_common.adoc[]
  * [[VUID-vkCopyAccelerationStructureKHR-buffer-03727]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    host-visible device memory
  * [[VUID-vkCopyAccelerationStructureKHR-buffer-03728]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    host-visible device memory feature must: be enabled
ifdef::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkCopyAccelerationStructureKHR-buffer-03780]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    memory that was not allocated with multiple instances
  * [[VUID-vkCopyAccelerationStructureKHR-buffer-03781]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    memory that was not allocated with multiple instances
endif::VK_KHR_device_group,VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkCopyAccelerationStructureKHR.adoc[]
--

[open,refpage='vkCopyMemoryToAccelerationStructureKHR',desc='Deserialize an acceleration structure on the host',type='protos']
--
:refpage: vkCopyMemoryToAccelerationStructureKHR

To copy host accessible memory to an acceleration structure, call:

include::{generated}/api/protos/vkCopyMemoryToAccelerationStructureKHR.adoc[]

  * pname:device is the device which owns pname:pInfo->dst.
  * pname:deferredOperation is an optional slink:VkDeferredOperationKHR to
    <<deferred-host-operations-requesting, request deferral>> for this
    command.
  * pname:pInfo is a pointer to a
    slink:VkCopyMemoryToAccelerationStructureInfoKHR structure defining the
    copy operation.

This command fulfills the same task as
flink:vkCmdCopyMemoryToAccelerationStructureKHR but is executed by the host.

This command can accept acceleration structures produced by either
flink:vkCmdCopyAccelerationStructureToMemoryKHR or
flink:vkCopyAccelerationStructureToMemoryKHR.

.Valid Usage
****
  * [[VUID-vkCopyMemoryToAccelerationStructureKHR-accelerationStructureHostCommands-03583]]
    The <<features-accelerationStructureHostCommands,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureHostCommands>>
    feature must: be enabled
include::{chapters}/commonvalidity/deferred_operations_common.adoc[]
  * [[VUID-vkCopyMemoryToAccelerationStructureKHR-pInfo-03729]]
    pname:pInfo->src.hostAddress must: be a valid host pointer
  * [[VUID-vkCopyMemoryToAccelerationStructureKHR-pInfo-03750]]
    pname:pInfo->src.hostAddress must: be aligned to 16 bytes
  * [[VUID-vkCopyMemoryToAccelerationStructureKHR-buffer-03730]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    host-visible device memory
ifdef::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkCopyMemoryToAccelerationStructureKHR-buffer-03782]]
    The pname:buffer used to create pname:pInfo->dst must: be bound to
    memory that was not allocated with multiple instances
endif::VK_KHR_device_group,VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkCopyMemoryToAccelerationStructureKHR.adoc[]
--

[open,refpage='vkCopyAccelerationStructureToMemoryKHR',desc='Serialize an acceleration structure on the host',type='protos']
--
:refpage: vkCopyAccelerationStructureToMemoryKHR

To copy an acceleration structure to host accessible memory, call:

include::{generated}/api/protos/vkCopyAccelerationStructureToMemoryKHR.adoc[]

  * pname:device is the device which owns pname:pInfo->src.
  * pname:deferredOperation is an optional slink:VkDeferredOperationKHR to
    <<deferred-host-operations-requesting, request deferral>> for this
    command.
  * pname:pInfo is a pointer to a
    slink:VkCopyAccelerationStructureToMemoryInfoKHR structure defining the
    copy operation.

This command fulfills the same task as
flink:vkCmdCopyAccelerationStructureToMemoryKHR but is executed by the host.

This command produces the same results as
flink:vkCmdCopyAccelerationStructureToMemoryKHR, but writes its result
directly to a host pointer, and is executed on the host rather than the
device.
The output may: not necessarily be bit-for-bit identical, but it can be
equally used by either flink:vkCmdCopyMemoryToAccelerationStructureKHR or
flink:vkCopyMemoryToAccelerationStructureKHR.

.Valid Usage
****
  * [[VUID-vkCopyAccelerationStructureToMemoryKHR-accelerationStructureHostCommands-03584]]
    The <<features-accelerationStructureHostCommands,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureHostCommands>>
    feature must: be enabled
include::{chapters}/commonvalidity/deferred_operations_common.adoc[]
  * [[VUID-vkCopyAccelerationStructureToMemoryKHR-buffer-03731]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    host-visible device memory
  * [[VUID-vkCopyAccelerationStructureToMemoryKHR-pInfo-03732]]
    pname:pInfo->dst.hostAddress must: be a valid host pointer
  * [[VUID-vkCopyAccelerationStructureToMemoryKHR-pInfo-03751]]
    pname:pInfo->dst.hostAddress must: be aligned to 16 bytes
ifdef::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkCopyAccelerationStructureToMemoryKHR-buffer-03783]]
    The pname:buffer used to create pname:pInfo->src must: be bound to
    memory that was not allocated with multiple instances
endif::VK_KHR_device_group,VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkCopyAccelerationStructureToMemoryKHR.adoc[]
--

[open,refpage='vkWriteAccelerationStructuresPropertiesKHR',desc='Query acceleration structure meta-data on the host',type='protos']
--
:refpage: vkWriteAccelerationStructuresPropertiesKHR

To query acceleration structure size parameters on the host, call:

include::{generated}/api/protos/vkWriteAccelerationStructuresPropertiesKHR.adoc[]

  * pname:device is the device which owns the acceleration structures in
    pname:pAccelerationStructures.
  * pname:accelerationStructureCount is the count of acceleration structures
    for which to query the property.
  * pname:pAccelerationStructures is a pointer to an array of existing
    previously built acceleration structures.
  * pname:queryType is a elink:VkQueryType value specifying the property to
    be queried.
  * pname:dataSize is the size in bytes of the buffer pointed to by
    pname:pData.
  * pname:pData is a pointer to a user-allocated buffer where the results
    will be written.
  * pname:stride is the stride in bytes between results for individual
    queries within pname:pData.

This command fulfills the same task as
flink:vkCmdWriteAccelerationStructuresPropertiesKHR but is executed by the
host.

.Valid Usage
****
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-accelerationStructureHostCommands-03585]]
    The <<features-accelerationStructureHostCommands,
    sname:VkPhysicalDeviceAccelerationStructureFeaturesKHR::pname:accelerationStructureHostCommands>>
    feature must: be enabled
include::{chapters}/commonvalidity/write_acceleration_structure_properties_common.adoc[]
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-03448]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, then
    pname:stride must: be a multiple of the size of basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-03449]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, then
    pname:pData must: point to a basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-03450]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, then
    pname:stride must: be a multiple of the size of basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-03451]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, then
    pname:pData must: point to a basetype:VkDeviceSize
ifdef::VK_KHR_ray_tracing_maintenance1[]
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-06731]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR, then pname:stride
    must: be a multiple of the size of basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-06732]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR, then pname:pData
    must: point to a basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-06733]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR,
    then pname:stride must: be a multiple of the size of
    basetype:VkDeviceSize
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-queryType-06734]]
    If pname:queryType is
    ename:VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR,
    then pname:pData must: point to a basetype:VkDeviceSize
endif::VK_KHR_ray_tracing_maintenance1[]
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-dataSize-03452]]
    pname:dataSize must: be greater than or equal to
    [eq]#pname:accelerationStructureCount*pname:stride#
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-buffer-03733]]
    The pname:buffer used to create each acceleration structure in
    pname:pAccelerationStructures must: be bound to host-visible device
    memory
ifdef::VK_KHR_device_group,VK_VERSION_1_1[]
  * [[VUID-vkWriteAccelerationStructuresPropertiesKHR-buffer-03784]]
    The pname:buffer used to create each acceleration structure in
    pname:pAccelerationStructures must: be bound to memory that was not
    allocated with multiple instances
endif::VK_KHR_device_group,VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkWriteAccelerationStructuresPropertiesKHR.adoc[]
--