summaryrefslogtreecommitdiff
path: root/chapters/sparsemem.adoc
blob: 7ebe0f40f469d6c15fbf1a20a87bd0037b349796 (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
// Copyright 2015-2023 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[sparsememory]]
= Sparse Resources

As documented in <<resources-association,Resource Memory Association>>,
sname:VkBuffer and sname:VkImage resources in Vulkan must: be bound
completely and contiguously to a single sname:VkDeviceMemory object.
This binding must: be done before the resource is used, and the binding is
immutable for the lifetime of the resource.

_Sparse resources_ relax these restrictions and provide these additional
features:

  * Sparse resources can: be bound non-contiguously to one or more
    sname:VkDeviceMemory allocations.
  * Sparse resources can: be re-bound to different memory allocations over
    the lifetime of the resource.
  * Sparse resources can: have descriptors generated and used orthogonally
    with memory binding commands.

ifdef::VKSC_VERSION_1_0[]
Sparse resources are not supported in Vulkan SC, due to complexity and the
necessity of being able to update page table mappings at runtime <<SCID-8>>.
However, the sparse resource features, properties, resource creation flags,
and definitions have been retained for completeness and compatibility.

All sparse resource <<sparsememory-physicalfeatures,physical device
features>> must: not be advertised as supported, and the related
<<sparsememory-physicalprops,physical device sparse properties>> and
<<limits,physical device limits>> must: be reported accordingly.

ifdef::hidden[]
// tag::scremoved[]
  * elink:VkStructureType
  ** ename:VK_STRUCTURE_TYPE_BIND_SPARSE_INFO <<SCID-8>>
  ** ename:VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO <<SCID-8>>
  ** ename:VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2
     <<SCID-8>>
  ** ename:VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2
     <<SCID-8>>
  ** ename:VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 <<SCID-8>>
  ** ename:VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 <<SCID-8>>
  * sname:VkSparseImageFormatProperties <<SCID-8>>
  * ename:VkSparseImageFormatFlagBits <<SCID-8>>
  * tname:VkSparseImageFormatFlags <<SCID-8>>
  * fname:vkGetPhysicalDeviceSparseImageFormatProperties <<SCID-8>>
  * fname:vkGetPhysicalDeviceSparseImageFormatProperties2 <<SCID-8>>
  * sname:VkPhysicalDeviceSparseImageFormatInfo2 <<SCID-8>>
  * sname:VkSparseImageFormatProperties2 <<SCID-8>>
  * sname:VkSparseImageMemoryRequirements <<SCID-8>>
  * fname:vkGetImageSparseMemoryRequirements <<SCID-8>>
  * fname:vkGetImageSparseMemoryRequirements2 <<SCID-8>>
  * sname:VkImageSparseMemoryRequirementsInfo2 <<SCID-8>>
  * sname:VkSparseImageMemoryRequirements2 <<SCID-8>>
  * sname:VkSparseMemoryBind <<SCID-8>>
  * ename:VkSparseMemoryBindFlagBits <<SCID-8>>
  * tname:VkSparseMemoryBindFlags <<SCID-8>>
  * sname:VkSparseBufferMemoryBindInfo <<SCID-8>>
  * sname:VkSparseImageOpaqueMemoryBindInfo <<SCID-8>>
  * sname:VkSparseImageMemoryBindInfo <<SCID-8>>
  * sname:VkSparseImageMemoryBind <<SCID-8>>
  * fname:vkQueueBindSparse <<SCID-8>>
  * sname:VkBindSparseInfo <<SCID-8>>
  * sname:VkDeviceGroupBindSparseInfo <<SCID-8>>
// end::scremoved[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

[[sparsememory-sparseresourcefeatures]]
== Sparse Resource Features

Sparse resources have several features that must: be enabled explicitly at
resource creation time.
The features are enabled by including bits in the pname:flags parameter of
slink:VkImageCreateInfo or slink:VkBufferCreateInfo.
Each feature also has one or more corresponding feature enables specified in
slink:VkPhysicalDeviceFeatures.

  * The <<features-sparseBinding, pname:sparseBinding>> feature is the base,
    and provides the following capabilities:

  ** Resources can: be bound at some defined (sparse block) granularity.
  ** The entire resource must: be bound to memory before use regardless of
     regions actually accessed.
  ** No specific mapping of image region to memory offset is defined, i.e.
     the location that each texel corresponds to in memory is
     implementation-dependent.
  ** Sparse buffers have a well-defined mapping of buffer range to memory
     range, where an offset into a range of the buffer that is bound to a
     single contiguous range of memory corresponds to an identical offset
     within that range of memory.
  ** Requested via the ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT and
     ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT bits.
  ** A sparse image created using ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT
     (but not ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) supports all
     formats that non-sparse usage supports, and supports both
     ename:VK_IMAGE_TILING_OPTIMAL and ename:VK_IMAGE_TILING_LINEAR tiling.

  * _Sparse Residency_ builds on (and requires) the pname:sparseBinding
    feature.
    It includes the following capabilities:

  ** Resources do not have to be completely bound to memory before use on
     the device.
  ** Images have a prescribed sparse image block layout, allowing specific
     rectangular regions of the image to be bound to specific offsets in
     memory allocations.
  ** Consistency of access to unbound regions of the resource is defined by
     the absence or presence of
     sname:VkPhysicalDeviceSparseProperties::pname:residencyNonResidentStrict.
     If this property is present, accesses to unbound regions of the
     resource are well defined and behave as if the data bound is populated
     with all zeros; writes are discarded.
     When this property is absent, accesses are considered safe, but reads
     will return undefined: values.
  ** Requested via the ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT and
     ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT bits.
  ** [[features-sparseResidency]] Sparse residency support is advertised on
     a finer grain via the following features:
+
  *** The <<features-sparseResidencyBuffer, pname:sparseResidencyBuffer>>
      feature provides support for creating sname:VkBuffer objects with the
      ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidencyImage2D, pname:sparseResidencyImage2D>>
      feature provides support for creating 2D single-sampled sname:VkImage
      objects with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidencyImage3D, pname:sparseResidencyImage3D>>
      feature provides support for creating 3D sname:VkImage objects with
      ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidency2Samples,
      pname:sparseResidency2Samples>> feature provides support for creating
      2D sname:VkImage objects with 2 samples and
      ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidency4Samples,
      pname:sparseResidency4Samples>> feature provides support for creating
      2D sname:VkImage objects with 4 samples and
      ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidency8Samples,
      pname:sparseResidency8Samples>> feature provides support for creating
      2D sname:VkImage objects with 8 samples and
      ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  *** The <<features-sparseResidency16Samples,
      pname:sparseResidency16Samples>> feature provides support for creating
      2D sname:VkImage objects with 16 samples and
      ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
+
Implementations supporting pname:sparseResidencyImage2D are only required:
to support sparse 2D, single-sampled images.
Support for sparse 3D and MSAA images is optional: and can: be enabled via
pname:sparseResidencyImage3D, pname:sparseResidency2Samples,
pname:sparseResidency4Samples, pname:sparseResidency8Samples, and
pname:sparseResidency16Samples.

  ** A sparse image created using ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
     supports all non-compressed color formats with power-of-two element
     size that non-sparse usage supports.
     Additional formats may: also be supported and can: be queried via
     flink:vkGetPhysicalDeviceSparseImageFormatProperties.
     ename:VK_IMAGE_TILING_LINEAR tiling is not supported.

  * The <<features-sparseResidencyAliased, pname:sparseResidencyAliased>>
    feature provides the following capability that can: be enabled per
    resource:
+
Allows physical memory ranges to be shared between multiple locations in the
same sparse resource or between multiple sparse resources, with each binding
of a memory location observing a consistent interpretation of the memory
contents.
+
--
ifndef::VKSC_VERSION_1_0[]
See <<sparsememory-sparse-memory-aliasing,Sparse Memory Aliasing>> for more
information.
endif::VKSC_VERSION_1_0[]
--


ifndef::VKSC_VERSION_1_0[]
[[sparsememory-fully-resident]]
== Sparse Buffers and Fully-Resident Images

Both sname:VkBuffer and sname:VkImage objects created with the
ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT or
ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT bits can: be thought of as a
linear region of address space.
In the sname:VkImage case if ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is
not used, this linear region is entirely opaque, meaning that there is no
application-visible mapping between texel location and memory offset.

Unless ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or
ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT are also used, the entire
resource must: be bound to one or more sname:VkDeviceMemory objects before
use.


=== Sparse Buffer and Fully-Resident Image Block Size

The sparse block size in bytes for sparse buffers and fully-resident images
is reported as sname:VkMemoryRequirements::pname:alignment.
pname:alignment represents both the memory alignment requirement and the
binding granularity (in bytes) for sparse resources.


[[sparsememory-partially-resident-buffers]]
== Sparse Partially-Resident Buffers

sname:VkBuffer objects created with the
ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT bit allow the buffer to be made
only partially resident.
Partially resident sname:VkBuffer objects are allocated and bound
identically to sname:VkBuffer objects using only the
ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT feature.
The only difference is the ability for some regions of the buffer to be
unbound during device use.


[[sparsememory-partially-resident-images]]
== Sparse Partially-Resident Images

sname:VkImage objects created with the
ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT bit allow specific rectangular
regions of the image called sparse image blocks to be bound to specific
ranges of memory.
This allows the application to manage residency at either image subresource
or sparse image block granularity.
Each image subresource (outside of the <<sparsememory-miptail,mip tail>>)
starts on a sparse block boundary and has dimensions that are integer
multiples of the corresponding dimensions of the sparse image block.

[NOTE]
.Note
====
Applications can: use these types of images to control LOD based on total
memory consumption.
If memory pressure becomes an issue the application can: unbind and disable
specific mipmap levels of images without having to recreate resources or
modify texel data of unaffected levels.

The application can: also use this functionality to access subregions of the
image in a "`megatexture`" fashion.
The application can: create a large image and only populate the region of
the image that is currently being used in the scene.
====


[[sparsememory-accessing-unbound]]
=== Accessing Unbound Regions

The following member of sname:VkPhysicalDeviceSparseProperties affects how
data in unbound regions of sparse resources are handled by the
implementation:

  * pname:residencyNonResidentStrict

If this property is not present, reads of unbound regions of the image will
return undefined: values.
Both reads and writes are still considered _safe_ and will not affect other
resources or populated regions of the image.

If this property is present, all reads of unbound regions of the image will
behave as if the region was bound to memory populated with all zeros; writes
will be discarded.

<<textures,Image operations>> performed on unbound memory may: still alter
some component values in the natural way for those accesses, e.g.
substituting a value of one for alpha in formats that do not have an alpha
component.

====
Example: Reading the alpha component of an unbacked ename:VK_FORMAT_R8_UNORM
image will return a value of [eq]#1.0f#.
====

See <<devsandqueues-physical-device-enumeration,Physical Device
Enumeration>> for instructions for retrieving physical device properties.

ifdef::implementation-guide[]
.Implementor's Note
****
For implementations that cannot: natively handle access to unbound regions
of a resource, the implementation may: allocate and bind memory to the
unbound regions.
Reads and writes to unbound regions will access the implementation-managed
memory instead.

Given that the values resulting from reads of unbound regions are undefined:
in this scenario, implementations may: use the same physical memory for all
unbound regions of multiple resources within the same process.
****
endif::implementation-guide[]


[[sparsememory-miptail]]
=== Mip Tail Regions

Sparse images created using ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT
(without also using ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) have no
specific mapping of image region or image subresource to memory offset
defined, so the entire image can: be thought of as a linear opaque address
region.
However, images created with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT do
have a prescribed sparse image block layout, and hence each image
subresource must: start on a sparse block boundary.
Within each array layer, the set of mip levels that have a smaller size than
the sparse block size in bytes are grouped together into a _mip tail
region_.

If the ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT flag is present in
the pname:flags member of sname:VkSparseImageFormatProperties, for the
image's pname:format, then any mip level which has dimensions that are not
integer multiples of the corresponding dimensions of the sparse image block,
and all subsequent mip levels, are also included in the mip tail region.

The following member of sname:VkPhysicalDeviceSparseProperties may: affect
how the implementation places mip levels in the mip tail region:

  * pname:residencyAlignedMipSize

Each mip tail region is bound to memory as an opaque region (i.e. must: be
bound using a slink:VkSparseImageOpaqueMemoryBindInfo structure) and may: be
of a size greater than or equal to the sparse block size in bytes.
This size is guaranteed to be an integer multiple of the sparse block size
in bytes.

An implementation may: choose to allow each array-layer's mip tail region to
be bound to memory independently or require that all array-layer's mip tail
regions be treated as one.
This is dictated by ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT in
sname:VkSparseImageMemoryRequirements::pname:flags.

The following diagrams depict how
ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT alter memory usage and
requirements.

image::{images}/sparseimage.svg[align="center",title="Sparse Image",opts="{imageopts}"]

In the absence of ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, each array layer contains a
mip tail region containing texel data for all mip levels smaller than the
sparse image block in any dimension.

Mip levels that are as large or larger than a sparse image block in all
dimensions can: be bound individually.
Right-edges and bottom-edges of each level are allowed to have partially
used sparse blocks.
Any bound partially-used-sparse-blocks must: still have their full sparse
block size in bytes allocated in memory.

image::{images}/sparseimage_singlemiptail.svg[align="center",title="Sparse Image with Single Mip Tail",opts="{imageopts}"]

When ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is present all array
layers will share a single mip tail region.

image::{images}/sparseimage_alignedmipsize.svg[align="center",title="Sparse Image with Aligned Mip Size",opts="{imageopts}"]

[NOTE]
.Note
====
The mip tail regions are presented here in 2D arrays simply for figure size
reasons.
Each mip tail is logically a single array of sparse blocks with an
implementation-dependent mapping of texels or compressed texel blocks to
sparse blocks.
====

When ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT is present the first
mip level that would contain partially used sparse blocks begins the mip
tail region.
This level and all subsequent levels are placed in the mip tail.
Only the first [eq]#N# mip levels whose dimensions are an exact multiple of
the sparse image block dimensions can: be bound and unbound on a sparse
block basis.

image::{images}/sparseimage_alignedmipsize_singlemiptail.svg[align="center",title="Sparse Image with Aligned Mip Size and Single Mip Tail",opts="{imageopts}"]

[NOTE]
.Note
====
The mip tail region is presented here in a 2D array simply for figure size
reasons.
It is logically a single array of sparse blocks with an
implementation-dependent mapping of texels or compressed texel blocks to
sparse blocks.
====

When both ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT are present the constraints
from each of these flags are in effect.


[[sparsememory-standard-shapes]]
=== Standard Sparse Image Block Shapes

Standard sparse image block shapes define a standard set of dimensions for
sparse image blocks that depend on the format of the image.
Layout of texels or compressed texel blocks within a sparse image block is
implementation-dependent.
All currently defined standard sparse image block shapes are 64 KB in size.

For block-compressed formats (e.g. ename:VK_FORMAT_BC5_UNORM_BLOCK), the
texel size is the size of the compressed texel block (e.g. 128-bit for
etext:BC5) thus the dimensions of the standard sparse image block shapes
apply in terms of compressed texel blocks.

[NOTE]
.Note
====
For block-compressed formats, the dimensions of a sparse image block in
terms of texels can: be calculated by multiplying the sparse image block
dimensions by the compressed texel block dimensions.
====

<<<

[[sparsememory-sparseblockshapessingle]]
.Standard Sparse Image Block Shapes (Single Sample)
[options="header"]
|====
| TEXEL SIZE (bits) | Block Shape (2D)              | Block Shape (3D)
| *8-Bit*           | 256 {times} 256 {times} 1     | 64 {times} 32 {times} 32
| *16-Bit*          | 256 {times} 128 {times} 1     | 32 {times} 32 {times} 32
| *32-Bit*          | 128 {times} 128 {times} 1     | 32 {times} 32 {times} 16
| *64-Bit*          | 128 {times} 64 {times} 1      | 32 {times} 16 {times} 16
| *128-Bit*         | 64 {times} 64 {times} 1       | 16 {times} 16 {times} 16
|====

[[sparsememory-sparseblockshapesmsaa]]
.Standard Sparse Image Block Shapes (MSAA)
[options="header"]
|====
| TEXEL SIZE (bits)| Block Shape (2X)            | Block Shape (4X)             | Block Shape (8X)             | Block Shape (16X)
| *8-Bit*          | 128 {times} 256 {times} 1   | 128 {times} 128 {times} 1    | 64 {times} 128 {times} 1     | 64 {times} 64 {times} 1
| *16-Bit*         | 128 {times} 128 {times} 1   | 128 {times} 64 {times} 1     | 64 {times} 64 {times} 1      | 64 {times} 32 {times} 1
| *32-Bit*         | 64 {times} 128 {times} 1    | 64 {times} 64 {times} 1      | 32 {times} 64 {times} 1      | 32 {times} 32 {times} 1
| *64-Bit*         | 64 {times} 64 {times} 1     | 64 {times} 32 {times} 1      | 32 {times} 32 {times} 1      | 32 {times} 16 {times} 1
| *128-Bit*        | 32 {times} 64 {times} 1     | 32 {times} 32 {times} 1      | 16 {times} 32 {times} 1      | 16 {times} 16 {times} 1
|====


Implementations that support the standard sparse image block shape for all
formats listed in the <<sparsememory-sparseblockshapessingle>> and
<<sparsememory-sparseblockshapesmsaa>> tables may: advertise the following
sname:VkPhysicalDeviceSparseProperties:

  * pname:residencyStandard2DBlockShape
  * pname:residencyStandard2DMultisampleBlockShape
  * pname:residencyStandard3DBlockShape

Reporting each of these features does _not_ imply that all possible image
types are supported as sparse.
Instead, this indicates that no supported sparse image of the corresponding
type will use custom sparse image block dimensions for any formats that have
a corresponding standard sparse image block shape.


[[sparsememory-custom-shapes]]
=== Custom Sparse Image Block Shapes

An implementation that does not support a standard image block shape for a
particular sparse partially-resident image may: choose to support a custom
sparse image block shape for it instead.
The dimensions of such a custom sparse image block shape are reported in
sname:VkSparseImageFormatProperties::pname:imageGranularity.
As with standard sparse image block shapes, the size in bytes of the custom
sparse image block shape will be reported in
sname:VkMemoryRequirements::pname:alignment.

Custom sparse image block dimensions are reported through
fname:vkGetPhysicalDeviceSparseImageFormatProperties and
fname:vkGetImageSparseMemoryRequirements.

An implementation must: not support both the standard sparse image block
shape and a custom sparse image block shape for the same image.
The standard sparse image block shape must: be used if it is supported.


[[sparsememory-multiaspect]]
=== Multiple Aspects

Partially resident images are allowed to report separate sparse properties
for different aspects of the image.
One example is for depth/stencil images where the implementation separates
the depth and stencil data into separate planes.
Another reason for multiple aspects is to allow the application to manage
memory allocation for implementation-private _metadata_ associated with the
image.
See the figure below:

image::{images}/sparseimage_multiaspect.svg[align="center",title="Multiple Aspect Sparse Image",opts="{imageopts}"]

[NOTE]
.Note
====
The mip tail regions are presented here in 2D arrays simply for figure size
reasons.
Each mip tail is logically a single array of sparse blocks with an
implementation-dependent mapping of texels or compressed texel blocks to
sparse blocks.
====

In the figure above the depth, stencil, and metadata aspects all have unique
sparse properties.
The per-texel stencil data is [eq]#{onequarter}# the size of the depth data,
hence the stencil sparse blocks include [eq]#4 {times}# the number of
texels.
The sparse block size in bytes for all of the aspects is identical and
defined by sname:VkMemoryRequirements::pname:alignment.


==== Metadata

The metadata aspect of an image has the following constraints:

  * All metadata is reported in the mip tail region of the metadata aspect.
  * All metadata must: be bound prior to device use of the sparse image.


[[sparsememory-sparse-memory-aliasing]]
== Sparse Memory Aliasing

By default sparse resources have the same aliasing rules as non-sparse
resources.
See <<resources-memory-aliasing,Memory Aliasing>> for more information.

sname:VkDevice objects that have the <<features-sparseResidencyAliased,
pname:sparseResidencyAliased>> feature enabled are able to use the
ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT and
ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags for resource creation.
These flags allow resources to access physical memory bound into multiple
locations within one or more sparse resources in a _data consistent_
fashion.
This means that reading physical memory from multiple aliased locations will
return the same value.

Care must: be taken when performing a write operation to aliased physical
memory.
Memory dependencies must: be used to separate writes to one alias from reads
or writes to another alias.
Writes to aliased memory that are not properly guarded against accesses to
different aliases will have undefined: results for all accesses to the
aliased memory.

Applications that wish to make use of data consistent sparse memory aliasing
must: abide by the following guidelines:

  * All sparse resources that are bound to aliased physical memory must: be
    created with the ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT /
    ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flag.
  * All resources that access aliased physical memory must: interpret the
    memory in the same way.
    This implies the following:
  ** Buffers and images cannot: alias the same physical memory in a data
     consistent fashion.
     The physical memory ranges must: be used exclusively by buffers or used
     exclusively by images for data consistency to be guaranteed.
  ** Memory in sparse image mip tail regions cannot: access aliased memory
     in a data consistent fashion.
  ** Sparse images that alias the same physical memory must: have compatible
     formats and be using the same sparse image block shape in order to
     access aliased memory in a data consistent fashion.

Failure to follow any of the above guidelines will require the application
to abide by the normal, non-sparse resource <<resources-memory-aliasing,
aliasing rules>>.
In this case memory cannot: be accessed in a data consistent fashion.

[NOTE]
.Note
====
Enabling sparse resource memory aliasing can: be a way to lower physical
memory use, but it may: reduce performance on some implementations.
An application developer can: test on their target HW and balance the memory
/ performance trade-offs measured.
====


ifdef::implementation-guide[]
== Sparse Resource Implementation Guidelines (Informative)

****
This section is Informative.
It is included to aid in implementors`' understanding of sparse resources.

.Device Virtual Address

The basic pname:sparseBinding feature allows the resource to reserve its own
device virtual address range at resource creation time rather than relying
on a bind operation to set this.
Without any other creation flags, no other constraints are relaxed compared
to normal resources.
All pages must: be bound to physical memory before the device accesses the
resource.

The <<features-sparseResidency, pname:sparseResidency>> features allow
sparse resources to be used even when not all pages are bound to memory.
Implementations that support access to unbound pages without causing a fault
may: support pname:residencyNonResidentStrict.

Not faulting on access to unbound pages is not enough to support
pname:residencyNonResidentStrict.
An implementation must: also guarantee that reads after writes to unbound
regions of the resource always return data for the read as if the memory
contains zeros.
Depending on any caching hierarchy of the implementation this may: not
always be possible.

Any implementation that does not fault, but does not guarantee correct read
values must: not support pname:residencyNonResidentStrict.

Any implementation that cannot: access unbound pages without causing a fault
will require the implementation to bind the entire device virtual address
range to physical memory.
Any pages that the application does not bind to memory may: be bound to one
(or more) "`placeholder" physical page(s) allocated by the implementation.
Given the following properties:

  * A process must: not access memory from another process
  * Reads return undefined: values

It is sufficient for each host process to allocate these placeholder pages
and use them for all resources in that process.
Implementations may: allocate more often (per instance, per device, or per
resource).


.Binding Memory

The byte size reported in sname:VkMemoryRequirements::pname:size must: be
greater than or equal to the amount of physical memory required: to fully
populate the resource.
Some implementations require "`holes`" in the device virtual address range
that are never accessed.
These holes may: be included in the pname:size reported for the resource.

Including or not including the device virtual address holes in the resource
size will alter how the implementation provides support for
sname:VkSparseImageOpaqueMemoryBindInfo.
This operation must: be supported for all sparse images, even ones created
with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

ifdef::editing-notes[]
[NOTE]
.editing-note
====
@ntrevett suggested expanding the NOTE tag below to encompass everything
from "`The cost is...`" in the first bullet point through the current note.
TBD.
====
endif::editing-notes[]

  * If the holes are included in the size, this bind function becomes very
    easy.
    In most cases the pname:resourceOffset is simply a device virtual
    address offset and the implementation can easily determine what device
    virtual address to bind.
    The cost is that the application may: allocate more physical memory for
    the resource than it needs.
  * If the holes are not included in the size, the application can: allocate
    less physical memory than otherwise for the resource.
    However, in this case the implementation must: account for the holes
    when mapping pname:resourceOffset to the actual device virtual address
    intended to be mapped.

[NOTE]
.Note
====
If the application always uses sname:VkSparseImageMemoryBindInfo to bind
memory for the non-tail mip levels, any holes that are present in the
resource size may: never be bound.

Since sname:VkSparseImageMemoryBindInfo uses texel locations to determine
which device virtual addresses to bind, it is impossible to bind device
virtual address holes with this operation.
====

.Binding Metadata Memory

All metadata for sparse images have their own sparse properties and are
embedded in the mip tail region for said properties.
See the <<sparsememory-multiaspect,Multiaspect>> section for details.

Given that metadata is in a mip tail region, and the mip tail region must:
be reported as contiguous (either globally or per-array-layer), some
implementations will have to resort to complicated offset -> device virtual
address mapping for handling sname:VkSparseImageOpaqueMemoryBindInfo.

To make this easier on the implementation, the
ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT explicitly specifies when metadata
is bound with sname:VkSparseImageOpaqueMemoryBindInfo.
When this flag is not present, the pname:resourceOffset may: be treated as a
strict device virtual address offset.

When ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT is present, the
pname:resourceOffset must: have been derived explicitly from the
pname:imageMipTailOffset in the sparse resource properties returned for the
metadata aspect.
By manipulating the value returned for pname:imageMipTailOffset, the
pname:resourceOffset does not have to correlate directly to a device virtual
address offset, and may: instead be whatever value makes it easiest for the
implementation to derive the correct device virtual address.

****
endif::implementation-guide[]
endif::VKSC_VERSION_1_0[]

[[sparsememory-resourceapi]]
== Sparse Resource API

The APIs related to sparse resources are grouped into the following
categories:

  * <<sparsememory-physicalfeatures,Physical Device Features>>
  * <<sparsememory-physicalprops,Physical Device Sparse Properties>>
ifndef::VKSC_VERSION_1_0[]
  * <<sparsememory-format-props,Sparse Image Format Properties>>
  * <<sparsememory-resource-creation,Sparse Resource Creation>>
  * <<sparsememory-memory-requirements,Sparse Resource Memory Requirements>>
  * <<sparsememory-resource-binding,Binding Resource Memory>>
endif::VKSC_VERSION_1_0[]


[[sparsememory-physicalfeatures]]
=== Physical Device Features

Some sparse-resource related features are reported and enabled in
sname:VkPhysicalDeviceFeatures.
These features must: be supported and enabled on the sname:VkDevice object
before applications can: use them.
See <<features, Physical Device Features>> for information on how to get and
set enabled device features, and for more detailed explanations of these
features.


==== Sparse Physical Device Features

  * pname:sparseBinding: Support for creating slink:VkBuffer and
    sname:VkImage objects with the ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT
    and ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT flags, respectively.
  * pname:sparseResidencyBuffer: Support for creating slink:VkBuffer objects
    with the ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT flag.
  * pname:sparseResidencyImage2D: Support for creating 2D single-sampled
    sname:VkImage objects with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidencyImage3D: Support for creating 3D slink:VkImage
    objects with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidency2Samples: Support for creating 2D slink:VkImage
    objects with 2 samples and ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidency4Samples: Support for creating 2D slink:VkImage
    objects with 4 samples and ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidency8Samples: Support for creating 2D slink:VkImage
    objects with 8 samples and ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidency16Samples: Support for creating 2D slink:VkImage
    objects with 16 samples and ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.
  * pname:sparseResidencyAliased: Support for creating slink:VkBuffer and
    sname:VkImage objects with the ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
    and ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags, respectively.


[[sparsememory-physicalprops]]
=== Physical Device Sparse Properties

Some features of the implementation are not possible to disable, and are
reported to allow applications to alter their sparse resource usage
accordingly.
These read-only capabilities are reported in the
slink:VkPhysicalDeviceProperties::pname:sparseProperties member, which is a
sname:VkPhysicalDeviceSparseProperties structure.

[open,refpage='VkPhysicalDeviceSparseProperties',desc='Structure specifying physical device sparse memory properties',type='structs']
--
The sname:VkPhysicalDeviceSparseProperties structure is defined as:

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

  * pname:residencyStandard2DBlockShape
ifndef::VKSC_VERSION_1_0[]
    is ename:VK_TRUE if the physical device will access all single-sample 2D
    sparse resources using the standard sparse image block shapes (based on
    image format), as described in the
    <<sparsememory-sparseblockshapessingle, Standard Sparse Image Block
    Shapes (Single Sample)>> table.
    If this property is not supported the value returned in the
    pname:imageGranularity member of the sname:VkSparseImageFormatProperties
    structure for single-sample 2D images is not required: to match the
    standard sparse image block dimensions listed in the table.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[must: be ename:VK_FALSE in Vulkan SC <<SCID-8>>.]
  * pname:residencyStandard2DMultisampleBlockShape
ifndef::VKSC_VERSION_1_0[]
    is ename:VK_TRUE if the physical device will access all multisample 2D
    sparse resources using the standard sparse image block shapes (based on
    image format), as described in the
    <<sparsememory-sparseblockshapesmsaa,Standard Sparse Image Block Shapes
    (MSAA)>> table.
    If this property is not supported, the value returned in the
    pname:imageGranularity member of the sname:VkSparseImageFormatProperties
    structure for multisample 2D images is not required: to match the
    standard sparse image block dimensions listed in the table.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[must: be ename:VK_FALSE in Vulkan SC <<SCID-8>>.]
  * pname:residencyStandard3DBlockShape
ifndef::VKSC_VERSION_1_0[]
    is ename:VK_TRUE if the physical device will access all 3D sparse
    resources using the standard sparse image block shapes (based on image
    format), as described in the
    <<sparsememory-sparseblockshapessingle,Standard Sparse Image Block
    Shapes (Single Sample)>> table.
    If this property is not supported, the value returned in the
    pname:imageGranularity member of the sname:VkSparseImageFormatProperties
    structure for 3D images is not required: to match the standard sparse
    image block dimensions listed in the table.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[must: be ename:VK_FALSE in Vulkan SC <<SCID-8>>.]
  * pname:residencyAlignedMipSize
ifndef::VKSC_VERSION_1_0[]
    is ename:VK_TRUE if images with mip level dimensions that are not
    integer multiples of the corresponding dimensions of the sparse image
    block may: be placed in the mip tail.
    If this property is not reported, only mip levels with dimensions
    smaller than the pname:imageGranularity member of the
    sname:VkSparseImageFormatProperties structure will be placed in the mip
    tail.
    If this property is reported the implementation is allowed to return
    ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT in the pname:flags
    member of sname:VkSparseImageFormatProperties, indicating that mip level
    dimensions that are not integer multiples of the corresponding
    dimensions of the sparse image block will be placed in the mip tail.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[must: be ename:VK_FALSE in Vulkan SC <<SCID-8>>.]
  * pname:residencyNonResidentStrict
ifndef::VKSC_VERSION_1_0[]
    specifies whether the physical device can: consistently access
    non-resident regions of a resource.
    If this property is ename:VK_TRUE, access to non-resident regions of
    resources will be guaranteed to return values as if the resource was
    populated with 0; writes to non-resident regions will be discarded.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[]
    must: be ename:VK_FALSE in Vulkan SC <<SCID-8>>.
ifdef::hidden[]
// tag::scdeviation[]
  * slink:VkPhysicalDeviceSparseProperties::pname:residencyStandard2DBlockShape
    must: be reported as ename:VK_FALSE <<SCID-8>>.
  * slink:VkPhysicalDeviceSparseProperties::pname:residencyStandard2DMultisampleBlockShape
    must: be reported as ename:VK_FALSE <<SCID-8>>.
  * slink:VkPhysicalDeviceSparseProperties::pname:residencyStandard3DBlockShape
    must: be reported as ename:VK_FALSE <<SCID-8>>.
  * slink:VkPhysicalDeviceSparseProperties::pname:residencyAlignedMipSize
    must: be reported as ename:VK_FALSE <<SCID-8>>.
  * slink:VkPhysicalDeviceSparseProperties::pname:residencyNonResidentStrict
    must: be reported as ename:VK_FALSE <<SCID-8>>.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]


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

ifndef::VKSC_VERSION_1_0[]

[[sparsememory-format-props]]
=== Sparse Image Format Properties

Given that certain aspects of sparse image support, including the sparse
image block dimensions, may: be implementation-dependent,
flink:vkGetPhysicalDeviceSparseImageFormatProperties can: be used to query
for sparse image format properties prior to resource creation.
This command is used to check whether a given set of sparse image parameters
is supported and what the sparse image block shape will be.


==== Sparse Image Format Properties API

[open,refpage='VkSparseImageFormatProperties',desc='Structure specifying sparse image format properties',type='structs']
--
The sname:VkSparseImageFormatProperties structure is defined as:

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

  * pname:aspectMask is a bitmask elink:VkImageAspectFlagBits specifying
    which aspects of the image the properties apply to.
  * pname:imageGranularity is the width, height, and depth of the sparse
    image block in texels or compressed texel blocks.
  * pname:flags is a bitmask of elink:VkSparseImageFormatFlagBits specifying
    additional information about the sparse resource.

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

[open,refpage='VkSparseImageFormatFlagBits',desc='Bitmask specifying additional information about a sparse image resource',type='enums']
--
Bits which may: be set in slink:VkSparseImageFormatProperties::pname:flags,
specifying additional information about the sparse resource, are:

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

  * ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT specifies that the image
    uses a single mip tail region for all array layers.
  * ename:VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT specifies that the
    first mip level whose dimensions are not integer multiples of the
    corresponding dimensions of the sparse image block begins the mip tail
    region.
  * ename:VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT specifies that
    the image uses non-standard sparse image block dimensions, and the
    pname:imageGranularity values do not match the standard sparse image
    block dimensions for the given format.
--

[open,refpage='VkSparseImageFormatFlags',desc='Bitmask of VkSparseImageFormatFlagBits',type='flags']
--
include::{generated}/api/flags/VkSparseImageFormatFlags.adoc[]

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

[open,refpage='vkGetPhysicalDeviceSparseImageFormatProperties',desc='Retrieve properties of an image format applied to sparse images',type='protos']
--
fname:vkGetPhysicalDeviceSparseImageFormatProperties returns an array of
slink:VkSparseImageFormatProperties.
Each element will describe properties for one set of image aspects that are
bound simultaneously in the image.
This is usually one element for each aspect in the image, but for
interleaved depth/stencil images there is only one element describing the
combined aspects.

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

  * pname:physicalDevice is the physical device from which to query the
    sparse image format properties.
  * pname:format is the image format.
  * pname:type is the dimensionality of image.
  * pname:samples is a elink:VkSampleCountFlagBits value specifying the
    number of samples per texel.
  * pname:usage is a bitmask describing the intended usage of the image.
  * pname:tiling is the tiling arrangement of the texel blocks in memory.
  * pname:pPropertyCount is a pointer to an integer related to the number of
    sparse format properties available or queried, as described below.
  * pname:pProperties is either `NULL` or a pointer to an array of
    slink:VkSparseImageFormatProperties structures.

If pname:pProperties is `NULL`, then the number of sparse format properties
available is returned in pname:pPropertyCount.
Otherwise, pname:pPropertyCount must: point to a variable set by the user to
the number of elements in the pname:pProperties array, and on return the
variable is overwritten with the number of structures actually written to
pname:pProperties.
If pname:pPropertyCount is less than the number of sparse format properties
available, at most pname:pPropertyCount structures will be written.

If ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given
arguments, pname:pPropertyCount will be set to zero upon return, and no data
will be written to pname:pProperties.

Multiple aspects are returned for depth/stencil images that are implemented
as separate planes by the implementation.
The depth and stencil data planes each have unique
sname:VkSparseImageFormatProperties data.

Depth/stencil images with depth and stencil data interleaved into a single
plane will return a single sname:VkSparseImageFormatProperties structure
with the pname:aspectMask set to ename:VK_IMAGE_ASPECT_DEPTH_BIT |
ename:VK_IMAGE_ASPECT_STENCIL_BIT.

.Valid Usage
****
  * [[VUID-vkGetPhysicalDeviceSparseImageFormatProperties-samples-01094]]
    pname:samples must: be a bit value that is set in
    sname:VkImageFormatProperties::pname:sampleCounts returned by
    fname:vkGetPhysicalDeviceImageFormatProperties with pname:format,
    pname:type, pname:tiling, and pname:usage equal to those in this command
    and pname:flags equal to the value that is set in
    slink:VkImageCreateInfo::pname:flags when the image is created
****

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

ifdef::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]
[open,refpage='vkGetPhysicalDeviceSparseImageFormatProperties2',desc='Retrieve properties of an image format applied to sparse images',type='protos']
--
fname:vkGetPhysicalDeviceSparseImageFormatProperties2 returns an array of
slink:VkSparseImageFormatProperties2.
Each element will describe properties for one set of image aspects that are
bound simultaneously in the image.
This is usually one element for each aspect in the image, but for
interleaved depth/stencil images there is only one element describing the
combined aspects.

ifdef::VK_VERSION_1_1[]
include::{generated}/api/protos/vkGetPhysicalDeviceSparseImageFormatProperties2.adoc[]
endif::VK_VERSION_1_1[]

ifdef::VK_VERSION_1_1+VK_KHR_get_physical_device_properties2[or the equivalent command]

ifdef::VK_KHR_get_physical_device_properties2[]
include::{generated}/api/protos/vkGetPhysicalDeviceSparseImageFormatProperties2KHR.adoc[]
endif::VK_KHR_get_physical_device_properties2[]

  * pname:physicalDevice is the physical device from which to query the
    sparse image format properties.
  * pname:pFormatInfo is a pointer to a
    slink:VkPhysicalDeviceSparseImageFormatInfo2 structure containing input
    parameters to the command.
  * pname:pPropertyCount is a pointer to an integer related to the number of
    sparse format properties available or queried, as described below.
  * pname:pProperties is either `NULL` or a pointer to an array of
    slink:VkSparseImageFormatProperties2 structures.

fname:vkGetPhysicalDeviceSparseImageFormatProperties2 behaves identically to
flink:vkGetPhysicalDeviceSparseImageFormatProperties, with the ability to
return extended information by adding extending structures to the
pname:pNext chain of its pname:pProperties parameter.

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

[open,refpage='VkPhysicalDeviceSparseImageFormatInfo2',desc='Structure specifying sparse image format inputs',type='structs']
--
The sname:VkPhysicalDeviceSparseImageFormatInfo2 structure is defined as:

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

ifdef::VK_KHR_get_physical_device_properties2[]
or the equivalent

include::{generated}/api/structs/VkPhysicalDeviceSparseImageFormatInfo2KHR.adoc[]
endif::VK_KHR_get_physical_device_properties2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:format is the image format.
  * pname:type is the dimensionality of image.
  * pname:samples is a elink:VkSampleCountFlagBits value specifying the
    number of samples per texel.
  * pname:usage is a bitmask describing the intended usage of the image.
  * pname:tiling is the tiling arrangement of the texel blocks in memory.

.Valid Usage
****
  * [[VUID-VkPhysicalDeviceSparseImageFormatInfo2-samples-01095]]
    pname:samples must: be a bit value that is set in
    sname:VkImageFormatProperties::pname:sampleCounts returned by
    fname:vkGetPhysicalDeviceImageFormatProperties with pname:format,
    pname:type, pname:tiling, and pname:usage equal to those in this command
    and pname:flags equal to the value that is set in
    slink:VkImageCreateInfo::pname:flags when the image is created
****

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

[open,refpage='VkSparseImageFormatProperties2',desc='Structure specifying sparse image format properties',type='structs']
--
The sname:VkSparseImageFormatProperties2 structure is defined as:

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

ifdef::VK_KHR_get_physical_device_properties2[]
or the equivalent

include::{generated}/api/structs/VkSparseImageFormatProperties2KHR.adoc[]
endif::VK_KHR_get_physical_device_properties2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:properties is a slink:VkSparseImageFormatProperties structure
    which is populated with the same values as in
    flink:vkGetPhysicalDeviceSparseImageFormatProperties.

include::{generated}/validity/structs/VkSparseImageFormatProperties2.adoc[]
--
endif::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]


[[sparsememory-resource-creation]]
=== Sparse Resource Creation

Sparse resources require that one or more sparse feature flags be specified
(as part of the sname:VkPhysicalDeviceFeatures structure described
previously in the <<sparsememory-physicalfeatures,Physical Device Features>>
section) when calling flink:vkCreateDevice.
When the appropriate device features are enabled, the
etext:VK_BUFFER_CREATE_SPARSE_* and etext:VK_IMAGE_CREATE_SPARSE_* flags
can: be used.
See flink:vkCreateBuffer and flink:vkCreateImage for details of the resource
creation APIs.

[NOTE]
.Note
====
Specifying ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or
ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT requires specifying
ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT or
ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT, respectively, as well.
This means that resources must: be created with the appropriate
etext:*_SPARSE_BINDING_BIT to be used with the sparse binding command
(fname:vkQueueBindSparse).
====


[[sparsememory-memory-requirements]]
=== Sparse Resource Memory Requirements

Sparse resources have specific memory requirements related to binding sparse
memory.
These memory requirements are reported differently for sname:VkBuffer
objects and sname:VkImage objects.


[[sparsememory-memory-buffer-fully-resident]]
==== Buffer and Fully-Resident Images

Buffers (both fully and partially resident) and fully-resident images can:
be bound to memory using only the data from sname:VkMemoryRequirements.
For all sparse resources the sname:VkMemoryRequirements::pname:alignment
member specifies both the bindable sparse block size in bytes and required:
alignment of sname:VkDeviceMemory.


[[sparsememory-memory-partially-resident]]
==== Partially Resident Images

Partially resident images have a different method for binding memory.
As with buffers and fully resident images, the
sname:VkMemoryRequirements::pname:alignment field specifies the bindable
sparse block size in bytes for the image.

Requesting sparse memory requirements for sname:VkImage objects using
fname:vkGetImageSparseMemoryRequirements will return an array of one or more
sname:VkSparseImageMemoryRequirements structures.
Each structure describes the sparse memory requirements for a group of
aspects of the image.

The sparse image must: have been created using the
ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag to retrieve valid sparse
image memory requirements.


==== Sparse Image Memory Requirements

[open,refpage='VkSparseImageMemoryRequirements',desc='Structure specifying sparse image memory requirements',type='structs']
--
The sname:VkSparseImageMemoryRequirements structure is defined as:

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

  * pname:formatProperties is a slink:VkSparseImageFormatProperties
    structure specifying properties of the image format.
  * pname:imageMipTailFirstLod is the first mip level at which image
    subresources are included in the mip tail region.
  * pname:imageMipTailSize is the memory size (in bytes) of the mip tail
    region.
    If pname:formatProperties.flags contains
    ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, this is the size of the
    whole mip tail, otherwise this is the size of the mip tail of a single
    array layer.
    This value is guaranteed to be a multiple of the sparse block size in
    bytes.
  * pname:imageMipTailOffset is the opaque memory offset used with
    slink:VkSparseImageOpaqueMemoryBindInfo to bind the mip tail region(s).
  * pname:imageMipTailStride is the offset stride between each array-layer's
    mip tail, if pname:formatProperties.flags does not contain
    ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT (otherwise the value is
    undefined:).

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

[open,refpage='vkGetImageSparseMemoryRequirements',desc='Query the memory requirements for a sparse image',type='protos']
--
To query sparse memory requirements for an image, call:

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

  * pname:device is the logical device that owns the image.
  * pname:image is the slink:VkImage object to get the memory requirements
    for.
  * pname:pSparseMemoryRequirementCount is a pointer to an integer related
    to the number of sparse memory requirements available or queried, as
    described below.
  * pname:pSparseMemoryRequirements is either `NULL` or a pointer to an
    array of sname:VkSparseImageMemoryRequirements structures.

If pname:pSparseMemoryRequirements is `NULL`, then the number of sparse
memory requirements available is returned in
pname:pSparseMemoryRequirementCount.
Otherwise, pname:pSparseMemoryRequirementCount must: point to a variable set
by the user to the number of elements in the pname:pSparseMemoryRequirements
array, and on return the variable is overwritten with the number of
structures actually written to pname:pSparseMemoryRequirements.
If pname:pSparseMemoryRequirementCount is less than the number of sparse
memory requirements available, at most pname:pSparseMemoryRequirementCount
structures will be written.

If the image was not created with ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
then pname:pSparseMemoryRequirementCount will be set to zero and
pname:pSparseMemoryRequirements will not be written to.

[NOTE]
.Note
====
It is legal for an implementation to report a larger value in
sname:VkMemoryRequirements::pname:size than would be obtained by adding
together memory sizes for all sname:VkSparseImageMemoryRequirements returned
by fname:vkGetImageSparseMemoryRequirements.
This may: occur when the implementation requires unused padding in the
address range describing the resource.
====

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

ifdef::VK_VERSION_1_1,VK_KHR_get_memory_requirements2[]
[open,refpage='vkGetImageSparseMemoryRequirements2',desc='Query the memory requirements for a sparse image',type='protos']
--
To query sparse memory requirements for an image, call:

ifdef::VK_VERSION_1_1[]
include::{generated}/api/protos/vkGetImageSparseMemoryRequirements2.adoc[]
endif::VK_VERSION_1_1[]

ifdef::VK_VERSION_1_1+VK_KHR_get_memory_requirements2[or the equivalent command]

ifdef::VK_KHR_get_memory_requirements2[]
include::{generated}/api/protos/vkGetImageSparseMemoryRequirements2KHR.adoc[]
endif::VK_KHR_get_memory_requirements2[]

  * pname:device is the logical device that owns the image.
  * pname:pInfo is a pointer to a sname:VkImageSparseMemoryRequirementsInfo2
    structure containing parameters required for the memory requirements
    query.
  * pname:pSparseMemoryRequirementCount is a pointer to an integer related
    to the number of sparse memory requirements available or queried, as
    described below.
  * pname:pSparseMemoryRequirements is either `NULL` or a pointer to an
    array of sname:VkSparseImageMemoryRequirements2 structures.

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

ifdef::VK_VERSION_1_3,VK_KHR_maintenance4[]
[open,refpage='vkGetDeviceImageSparseMemoryRequirements',desc='Query the memory requirements for a sparse image',type='protos',alias='vkGetDeviceImageSparseMemoryRequirementsKHR']
--
To determine the sparse memory requirements for an image resource without
creating an object, call:

ifdef::VK_VERSION_1_3[]
include::{generated}/api/protos/vkGetDeviceImageSparseMemoryRequirements.adoc[]
endif::VK_VERSION_1_3[]

ifdef::VK_VERSION_1_3+VK_KHR_maintenance4[or the equivalent command]

ifdef::VK_KHR_maintenance4[]
include::{generated}/api/protos/vkGetDeviceImageSparseMemoryRequirementsKHR.adoc[]
endif::VK_KHR_maintenance4[]

  * pname:device is the logical device intended to own the image.
  * pname:pInfo is a pointer to a slink:VkDeviceImageMemoryRequirements
    structure containing parameters required for the memory requirements
    query.
  * pname:pSparseMemoryRequirementCount is a pointer to an integer related
    to the number of sparse memory requirements available or queried, as
    described below.
  * pname:pSparseMemoryRequirements is either `NULL` or a pointer to an
    array of sname:VkSparseImageMemoryRequirements2 structures.

include::{generated}/validity/protos/vkGetDeviceImageSparseMemoryRequirements.adoc[]
--
endif::VK_VERSION_1_3,VK_KHR_maintenance4[]

[open,refpage='VkImageSparseMemoryRequirementsInfo2',desc='(None)',type='structs']
--
The sname:VkImageSparseMemoryRequirementsInfo2 structure is defined as:

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

ifdef::VK_KHR_get_memory_requirements2[]
or the equivalent

include::{generated}/api/structs/VkImageSparseMemoryRequirementsInfo2KHR.adoc[]
endif::VK_KHR_get_memory_requirements2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:image is the image to query.

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

[open,refpage='VkSparseImageMemoryRequirements2',desc='(None)',type='structs']
--
The sname:VkSparseImageMemoryRequirements2 structure is defined as:

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

ifdef::VK_KHR_get_memory_requirements2[]
or the equivalent

include::{generated}/api/structs/VkSparseImageMemoryRequirements2KHR.adoc[]
endif::VK_KHR_get_memory_requirements2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:memoryRequirements is a slink:VkSparseImageMemoryRequirements
    structure describing the memory requirements of the sparse image.

include::{generated}/validity/structs/VkSparseImageMemoryRequirements2.adoc[]
--
endif::VK_VERSION_1_1,VK_KHR_get_memory_requirements2[]


[[sparsememory-resource-binding]]
=== Binding Resource Memory

Non-sparse resources are backed by a single physical allocation prior to
device use (via fname:vkBindImageMemory or fname:vkBindBufferMemory), and
their backing must: not be changed.
On the other hand, sparse resources can: be bound to memory non-contiguously
and these bindings can: be altered during the lifetime of the resource.

ifndef::VKSC_VERSION_1_0[]

[NOTE]
.Note
====
It is important to note that freeing a sname:VkDeviceMemory object with
fname:vkFreeMemory will not cause resources (or resource regions) bound to
the memory object to become unbound.
Applications must: not access resources bound to memory that has been freed.
====

endif::VKSC_VERSION_1_0[]

Sparse memory bindings execute on a queue that includes the
ename:VK_QUEUE_SPARSE_BINDING_BIT bit.
Applications must: use <<synchronization,synchronization primitives>> to
guarantee that other queues do not access ranges of memory concurrently with
a binding change.
Applications can: access other ranges of the same resource while a bind
operation is executing.

[NOTE]
.Note
====
Implementations must: provide a guarantee that simultaneously binding sparse
blocks while another queue accesses those same sparse blocks via a sparse
resource must: not access memory owned by another process or otherwise
corrupt the system.
====

While some implementations may: include ename:VK_QUEUE_SPARSE_BINDING_BIT
support in queue families that also include graphics and compute support,
other implementations may: only expose a
ename:VK_QUEUE_SPARSE_BINDING_BIT-only queue family.
In either case, applications must: use <<synchronization,synchronization
primitives>> to explicitly request any ordering dependencies between sparse
memory binding operations and other graphics/compute/transfer operations, as
sparse binding operations are not automatically ordered against command
buffer execution, even within a single queue.

When binding memory explicitly for the ename:VK_IMAGE_ASPECT_METADATA_BIT
the application must: use the ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT in
the sname:VkSparseMemoryBind::pname:flags field when binding memory.
Binding memory for metadata is done the same way as binding memory for the
mip tail, with the addition of the ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT
flag.

Binding the mip tail for any aspect must: only be performed using
slink:VkSparseImageOpaqueMemoryBindInfo.
If pname:formatProperties.flags contains
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, then it can: be bound with
a single slink:VkSparseMemoryBind structure, with pname:resourceOffset =
pname:imageMipTailOffset and pname:size = pname:imageMipTailSize.

If pname:formatProperties.flags does not contain
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT then the offset for the mip
tail in each array layer is given as:

[source,c++]
----
arrayMipTailOffset = imageMipTailOffset + arrayLayer * imageMipTailStride;
----

and the mip tail can: be bound with code:layerCount slink:VkSparseMemoryBind
structures, each using pname:size = pname:imageMipTailSize and
pname:resourceOffset = ptext:arrayMipTailOffset as defined above.

Sparse memory binding is handled by the following APIs and related data
structures.


[[sparsemem-memory-binding]]
==== Sparse Memory Binding Functions

[open,refpage='VkSparseMemoryBind',desc='Structure specifying a sparse memory bind operation',type='structs']
--
The sname:VkSparseMemoryBind structure is defined as:

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

  * pname:resourceOffset is the offset into the resource.
  * pname:size is the size of the memory region to be bound.
  * pname:memory is the slink:VkDeviceMemory object that the range of the
    resource is bound to.
    If pname:memory is dlink:VK_NULL_HANDLE, the range is unbound.
  * pname:memoryOffset is the offset into the slink:VkDeviceMemory object to
    bind the resource range to.
    If pname:memory is dlink:VK_NULL_HANDLE, this value is ignored.
  * pname:flags is a bitmask of elink:VkSparseMemoryBindFlagBits specifying
    usage of the binding operation.

The _binding range_ [eq]#[pname:resourceOffset, pname:resourceOffset {plus}
pname:size)# has different constraints based on pname:flags.
If pname:flags contains ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT, the
binding range must: be within the mip tail region of the metadata aspect.
This metadata region is defined by:

  {empty}:: [eq]#metadataRegion = [base, base {plus}
            pname:imageMipTailSize)#
  {empty}:: [eq]#base = pname:imageMipTailOffset {plus}
            pname:imageMipTailStride {times} n#

and pname:imageMipTailOffset, pname:imageMipTailSize, and
pname:imageMipTailStride values are from the
slink:VkSparseImageMemoryRequirements corresponding to the metadata aspect
of the image, and [eq]#n# is a valid array layer index for the image,

pname:imageMipTailStride is considered to be zero for aspects where
sname:VkSparseImageMemoryRequirements::pname:formatProperties.flags contains
ename:VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT.

If pname:flags does not contain ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT,
the binding range must: be within the range
[eq]#[0,slink:VkMemoryRequirements::pname:size)#.

.Valid Usage
****
  * [[VUID-VkSparseMemoryBind-memory-01096]]
    If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory and
    pname:memoryOffset must: match the memory requirements of the resource,
    as described in section <<resources-association>>
  * [[VUID-VkSparseMemoryBind-memory-01097]]
    If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory must: not have
    been created with a memory type that reports
    ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set
  * [[VUID-VkSparseMemoryBind-size-01098]]
    pname:size must: be greater than `0`
  * [[VUID-VkSparseMemoryBind-resourceOffset-01099]]
    pname:resourceOffset must: be less than the size of the resource
  * [[VUID-VkSparseMemoryBind-size-01100]]
    pname:size must: be less than or equal to the size of the resource minus
    pname:resourceOffset
  * [[VUID-VkSparseMemoryBind-memoryOffset-01101]]
    pname:memoryOffset must: be less than the size of pname:memory
  * [[VUID-VkSparseMemoryBind-size-01102]]
    pname:size must: be less than or equal to the size of pname:memory minus
    pname:memoryOffset
ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
  * [[VUID-VkSparseMemoryBind-memory-02730]]
    If pname:memory was created with
    slink:VkExportMemoryAllocateInfo::pname:handleTypes not equal to `0`, at
    least one handle type it contained must: also have been set in
    slink:VkExternalMemoryBufferCreateInfo::pname:handleTypes or
    slink:VkExternalMemoryImageCreateInfo::pname:handleTypes when the
    resource was created
  * [[VUID-VkSparseMemoryBind-memory-02731]]
    If pname:memory was created by a memory import operation, the external
    handle type of the imported memory must: also have been set in
    slink:VkExternalMemoryBufferCreateInfo::pname:handleTypes or
    slink:VkExternalMemoryImageCreateInfo::pname:handleTypes when the
    resource was created
endif::VK_VERSION_1_1,VK_KHR_external_memory[]
****

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

[open,refpage='VkSparseMemoryBindFlagBits',desc='Bitmask specifying usage of a sparse memory binding operation',type='enums']
--
Bits which can: be set in slink:VkSparseMemoryBind::pname:flags, specifying
usage of a sparse memory binding operation, are:

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

  * ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT specifies that the memory being
    bound is only for the metadata aspect.
--

[open,refpage='VkSparseMemoryBindFlags',desc='Bitmask of VkSparseMemoryBindFlagBits',type='flags']
--
include::{generated}/api/flags/VkSparseMemoryBindFlags.adoc[]

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

[open,refpage='VkSparseBufferMemoryBindInfo',desc='Structure specifying a sparse buffer memory bind operation',type='structs']
--
Memory is bound to sname:VkBuffer objects created with the
ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT flag using the following
structure:

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

  * pname:buffer is the slink:VkBuffer object to be bound.
  * pname:bindCount is the number of slink:VkSparseMemoryBind structures in
    the pname:pBinds array.
  * pname:pBinds is a pointer to an array of slink:VkSparseMemoryBind
    structures.

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

[open,refpage='VkSparseImageOpaqueMemoryBindInfo',desc='Structure specifying sparse image opaque memory bind information',type='structs']
--
Memory is bound to opaque regions of sname:VkImage objects created with the
ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT flag using the following structure:

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

  * pname:image is the slink:VkImage object to be bound.
  * pname:bindCount is the number of slink:VkSparseMemoryBind structures in
    the pname:pBinds array.
  * pname:pBinds is a pointer to an array of slink:VkSparseMemoryBind
    structures.

.Valid Usage
****
  * [[VUID-VkSparseImageOpaqueMemoryBindInfo-pBinds-01103]]
    If the pname:flags member of any element of pname:pBinds contains
    ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range defined
    must: be within the mip tail region of the metadata aspect of
    pname:image
****

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

[NOTE]
.Note
====
This operation is normally used to bind memory to fully-resident sparse
images or for mip tail regions of partially resident images.
However, it can: also be used to bind memory for the entire binding range of
partially resident images.

In case pname:flags does not contain
ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT, the pname:resourceOffset is in the
range [eq]#[0, slink:VkMemoryRequirements::pname:size)#, This range includes
data from all aspects of the image, including metadata.
For most implementations this will probably mean that the
pname:resourceOffset is a simple device address offset within the resource.
It is possible for an application to bind a range of memory that includes
both resource data and metadata.
However, the application would not know what part of the image the memory is
used for, or if any range is being used for metadata.

When pname:flags contains ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT, the
binding range specified must: be within the mip tail region of the metadata
aspect.
In this case the pname:resourceOffset is not required: to be a simple device
address offset within the resource.
However, it _is_ defined to be within [eq]#[pname:imageMipTailOffset,
pname:imageMipTailOffset {plus} pname:imageMipTailSize)# for the metadata
aspect.
See slink:VkSparseMemoryBind for the full constraints on binding region with
this flag present.
====

ifdef::editing-notes[]
[NOTE]
.editing-note
====
(Jon) The preceding NOTE refers to pname:flags, which is presumably a
reference to slink:VkSparseMemoryBind above, even though that is not
contextually clear.
====
endif::editing-notes[]

[open,refpage='VkSparseImageMemoryBindInfo',desc='Structure specifying sparse image memory bind information',type='structs']
--
Memory can: be bound to sparse image blocks of sname:VkImage objects created
with the ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag using the following
structure:

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

  * pname:image is the slink:VkImage object to be bound
  * pname:bindCount is the number of slink:VkSparseImageMemoryBind
    structures in pname:pBinds array
  * pname:pBinds is a pointer to an array of slink:VkSparseImageMemoryBind
    structures

.Valid Usage
****
  * [[VUID-VkSparseImageMemoryBindInfo-subresource-01722]]
    The pname:subresource.mipLevel member of each element of pname:pBinds
    must: be less than the pname:mipLevels specified in
    slink:VkImageCreateInfo when pname:image was created
  * [[VUID-VkSparseImageMemoryBindInfo-subresource-01723]]
    The pname:subresource.arrayLayer member of each element of pname:pBinds
    must: be less than the pname:arrayLayers specified in
    slink:VkImageCreateInfo when pname:image was created
  * [[VUID-VkSparseImageMemoryBindInfo-image-02901]]
    pname:image must: have been created with
    ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set
****

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

[open,refpage='VkSparseImageMemoryBind',desc='Structure specifying sparse image memory bind',type='structs']
--
The sname:VkSparseImageMemoryBind structure is defined as:

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

  * pname:subresource is the image _aspect_ and region of interest in the
    image.
  * pname:offset are the coordinates of the first texel within the image
    subresource to bind.
  * pname:extent is the size in texels of the region within the image
    subresource to bind.
    The extent must: be a multiple of the sparse image block dimensions,
    except when binding sparse image blocks along the edge of an image
    subresource it can: instead be such that any coordinate of
    [eq]#pname:offset {plus} pname:extent# equals the corresponding
    dimensions of the image subresource.
  * pname:memory is the slink:VkDeviceMemory object that the sparse image
    blocks of the image are bound to.
    If pname:memory is dlink:VK_NULL_HANDLE, the sparse image blocks are
    unbound.
  * pname:memoryOffset is an offset into slink:VkDeviceMemory object.
    If pname:memory is dlink:VK_NULL_HANDLE, this value is ignored.
  * pname:flags are sparse memory binding flags.

.Valid Usage
****
  * [[VUID-VkSparseImageMemoryBind-memory-01104]]
    If the <<features-sparseResidencyAliased, pname:sparseResidencyAliased>>
    feature is not enabled, and if any other resources are bound to ranges
    of pname:memory, the range of pname:memory being bound must: not overlap
    with those bound ranges
  * [[VUID-VkSparseImageMemoryBind-memory-01105]]
    pname:memory and pname:memoryOffset must: match the memory requirements
    of the calling command's pname:image, as described in section
    <<resources-association>>
  * [[VUID-VkSparseImageMemoryBind-subresource-01106]]
    pname:subresource must: be a valid image subresource for pname:image
    (see <<resources-image-views>>)
  * [[VUID-VkSparseImageMemoryBind-offset-01107]]
    pname:offset.x must: be a multiple of the sparse image block width
    (sname:VkSparseImageFormatProperties::pname:imageGranularity.width) of
    the image
  * [[VUID-VkSparseImageMemoryBind-extent-09388]]
    pname:extent.width must: be greater than `0`
  * [[VUID-VkSparseImageMemoryBind-extent-01108]]
    pname:extent.width must: either be a multiple of the sparse image block
    width of the image, or else [eq]#(pname:extent.width {plus}
    pname:offset.x)# must: equal the width of the image subresource
  * [[VUID-VkSparseImageMemoryBind-offset-01109]]
    pname:offset.y must: be a multiple of the sparse image block height
    (sname:VkSparseImageFormatProperties::pname:imageGranularity.height) of
    the image
  * [[VUID-VkSparseImageMemoryBind-extent-09389]]
    pname:extent.height must: be greater than `0`
  * [[VUID-VkSparseImageMemoryBind-extent-01110]]
    pname:extent.height must: either be a multiple of the sparse image block
    height of the image, or else [eq]#(pname:extent.height {plus}
    pname:offset.y)# must: equal the height of the image subresource
  * [[VUID-VkSparseImageMemoryBind-offset-01111]]
    pname:offset.z must: be a multiple of the sparse image block depth
    (sname:VkSparseImageFormatProperties::pname:imageGranularity.depth) of
    the image
  * [[VUID-VkSparseImageMemoryBind-extent-09390]]
    pname:extent.depth must: be greater than `0`
  * [[VUID-VkSparseImageMemoryBind-extent-01112]]
    pname:extent.depth must: either be a multiple of the sparse image block
    depth of the image, or else [eq]#(pname:extent.depth {plus}
    pname:offset.z)# must: equal the depth of the image subresource
ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
  * [[VUID-VkSparseImageMemoryBind-memory-02732]]
    If pname:memory was created with
    slink:VkExportMemoryAllocateInfo::pname:handleTypes not equal to `0`, at
    least one handle type it contained must: also have been set in
    slink:VkExternalMemoryImageCreateInfo::pname:handleTypes when the image
    was created
  * [[VUID-VkSparseImageMemoryBind-memory-02733]]
    If pname:memory was created by a memory import operation, the external
    handle type of the imported memory must: also have been set in
    slink:VkExternalMemoryImageCreateInfo::pname:handleTypes when
    pname:image was created
endif::VK_VERSION_1_1,VK_KHR_external_memory[]
****

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

[open,refpage='vkQueueBindSparse',desc='Bind device memory to a sparse resource object',type='protos']
--
To submit sparse binding operations to a queue, call:

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

  * pname:queue is the queue that the sparse binding operations will be
    submitted to.
  * pname:bindInfoCount is the number of elements in the pname:pBindInfo
    array.
  * pname:pBindInfo is a pointer to an array of slink:VkBindSparseInfo
    structures, each specifying a sparse binding submission batch.
  * pname:fence is an optional: handle to a fence to be signaled.
    If pname:fence is not dlink:VK_NULL_HANDLE, it defines a
    <<synchronization-fences-signaling, fence signal operation>>.

fname:vkQueueBindSparse is a <<devsandqueues-submission,queue submission
command>>, with each batch defined by an element of pname:pBindInfo as a
slink:VkBindSparseInfo structure.
Batches begin execution in the order they appear in pname:pBindInfo, but
may: complete out of order.

Within a batch, a given range of a resource must: not be bound more than
once.
Across batches, if a range is to be bound to one allocation and offset and
then to another allocation and offset, then the application must: guarantee
(usually using semaphores) that the binding operations are executed in the
correct order, as well as to order binding operations against the execution
of command buffer submissions.

As no operation to flink:vkQueueBindSparse causes any pipeline stage to
access memory, synchronization primitives used in this command effectively
only define execution dependencies.

Additional information about fence and semaphore operation is described in
<<synchronization, the synchronization chapter>>.

.Valid Usage
****
  * [[VUID-vkQueueBindSparse-fence-01113]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: be
    unsignaled
  * [[VUID-vkQueueBindSparse-fence-01114]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: not be
    associated with any other queue command that has not yet completed
    execution on that queue
  * [[VUID-vkQueueBindSparse-pSignalSemaphores-01115]]
    Each element of the pname:pSignalSemaphores member of each element of
    pname:pBindInfo must: be unsignaled when the semaphore signal operation
    it defines is executed on the device
  * [[VUID-vkQueueBindSparse-pWaitSemaphores-01116]]
    When a semaphore wait operation referring to a binary semaphore defined
    by any element of the pname:pWaitSemaphores member of any element of
    pname:pBindInfo executes on pname:queue, there must: be no other queues
    waiting on the same semaphore
ifndef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-vkQueueBindSparse-pWaitSemaphores-01117]]
    All elements of the pname:pWaitSemaphores member of all elements of the
    pname:pBindInfo parameter referring to a binary semaphore must: be
    semaphores that are signaled, or have
    <<synchronization-semaphores-signaling, semaphore signal operations>>
    previously submitted for execution
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-vkQueueBindSparse-pWaitSemaphores-03245]]
    All elements of the pname:pWaitSemaphores member of all elements of
    pname:pBindInfo created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_BINARY must: reference a semaphore signal
    operation that has been submitted for execution and any
    <<synchronization-semaphores-signaling, semaphore signal operations>> on
    which it depends (if any) must: have also been submitted for execution
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
****

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

[open,refpage='VkBindSparseInfo',desc='Structure specifying a sparse binding operation',type='structs']
--
The sname:VkBindSparseInfo structure is defined as:

include::{generated}/api/structs/VkBindSparseInfo.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:waitSemaphoreCount is the number of semaphores upon which to wait
    before executing the sparse binding operations for the batch.
  * pname:pWaitSemaphores is a pointer to an array of semaphores upon which
    to wait on before the sparse binding operations for this batch begin
    execution.
    If semaphores to wait on are provided, they define a
    <<synchronization-semaphores-waiting, semaphore wait operation>>.
  * pname:bufferBindCount is the number of sparse buffer bindings to perform
    in the batch.
  * pname:pBufferBinds is a pointer to an array of
    slink:VkSparseBufferMemoryBindInfo structures.
  * pname:imageOpaqueBindCount is the number of opaque sparse image bindings
    to perform.
  * pname:pImageOpaqueBinds is a pointer to an array of
    slink:VkSparseImageOpaqueMemoryBindInfo structures, indicating opaque
    sparse image bindings to perform.
  * pname:imageBindCount is the number of sparse image bindings to perform.
  * pname:pImageBinds is a pointer to an array of
    slink:VkSparseImageMemoryBindInfo structures, indicating sparse image
    bindings to perform.
  * pname:signalSemaphoreCount is the number of semaphores to be signaled
    once the sparse binding operations specified by the structure have
    completed execution.
  * pname:pSignalSemaphores is a pointer to an array of semaphores which
    will be signaled when the sparse binding operations for this batch have
    completed execution.
    If semaphores to be signaled are provided, they define a
    <<synchronization-semaphores-signaling, semaphore signal operation>>.

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
.Valid Usage
****
  * [[VUID-VkBindSparseInfo-pWaitSemaphores-03246]]
    If any element of pname:pWaitSemaphores or pname:pSignalSemaphores was
    created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE
    then the pname:pNext chain must: include a
    slink:VkTimelineSemaphoreSubmitInfo structure
  * [[VUID-VkBindSparseInfo-pNext-03247]]
    If the pname:pNext chain of this structure includes a
    slink:VkTimelineSemaphoreSubmitInfo structure and any element of
    pname:pWaitSemaphores was created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_TIMELINE then its pname:waitSemaphoreValueCount
    member must: equal pname:waitSemaphoreCount
  * [[VUID-VkBindSparseInfo-pNext-03248]]
    If the pname:pNext chain of this structure includes a
    slink:VkTimelineSemaphoreSubmitInfo structure and any element of
    pname:pSignalSemaphores was created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_TIMELINE then its
    pname:signalSemaphoreValueCount member must: equal
    pname:signalSemaphoreCount
  * [[VUID-VkBindSparseInfo-pSignalSemaphores-03249]]
    For each element of pname:pSignalSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pSignalSemaphoreValues must:
    have a value greater than the current value of the semaphore when the
    <<synchronization-semaphores-signaling,semaphore signal operation>> is
    executed
  * [[VUID-VkBindSparseInfo-pWaitSemaphores-03250]]
    For each element of pname:pWaitSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pWaitSemaphoreValues must:
    have a value which does not differ from the current value of the
    semaphore or from the value of any outstanding semaphore wait or signal
    operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
  * [[VUID-VkBindSparseInfo-pSignalSemaphores-03251]]
    For each element of pname:pSignalSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pSignalSemaphoreValues must:
    have a value which does not differ from the current value of the
    semaphore or from the value of any outstanding semaphore wait or signal
    operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
****
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

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

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
To specify the values to use when waiting for and signaling semaphores
created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE,
add a slink:VkTimelineSemaphoreSubmitInfo structure to the pname:pNext chain
of the slink:VkBindSparseInfo structure.
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[open,refpage='VkDeviceGroupBindSparseInfo',desc='Structure indicating which instances are bound',type='structs']
--
If the pname:pNext chain of slink:VkBindSparseInfo includes a
sname:VkDeviceGroupBindSparseInfo structure, then that structure includes
device indices specifying which instance of the resources and memory are
bound.

The sname:VkDeviceGroupBindSparseInfo structure is defined as:

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

ifdef::VK_KHR_device_group[]
or the equivalent

include::{generated}/api/structs/VkDeviceGroupBindSparseInfoKHR.adoc[]
endif::VK_KHR_device_group[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:resourceDeviceIndex is a device index indicating which instance of
    the resource is bound.
  * pname:memoryDeviceIndex is a device index indicating which instance of
    the memory the resource instance is bound to.

These device indices apply to all buffer and image memory binds included in
the batch pointing to this structure.
The semaphore waits and signals for the batch are executed only by the
physical device specified by the pname:resourceDeviceIndex.

If this structure is not present, pname:resourceDeviceIndex and
pname:memoryDeviceIndex are assumed to be zero.

.Valid Usage
****
  * [[VUID-VkDeviceGroupBindSparseInfo-resourceDeviceIndex-01118]]
    pname:resourceDeviceIndex and pname:memoryDeviceIndex must: both be
    valid device indices
  * [[VUID-VkDeviceGroupBindSparseInfo-memoryDeviceIndex-01119]]
    Each memory allocation bound in this batch must: have allocated an
    instance for pname:memoryDeviceIndex
****

include::{generated}/validity/structs/VkDeviceGroupBindSparseInfo.adoc[]
--
endif::VK_VERSION_1_1,VK_KHR_device_group[]
endif::VKSC_VERSION_1_0[]