forked from KhronosGroup/Vulkan-Docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory.txt
2063 lines (1678 loc) · 85.6 KB
/
memory.txt
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
// Copyright (c) 2015-2017 Khronos Group. This work is licensed under a
// Creative Commons Attribution 4.0 International License; see
// http://creativecommons.org/licenses/by/4.0/
[[memory]]
= Memory Allocation
Vulkan memory is broken up into two categories, _host memory_ and _device
memory_.
[[memory-host]]
== Host Memory
Host memory is memory needed by the Vulkan implementation for
non-device-visible storage.
This storage may: be used for e.g. internal software structures.
[[memory-allocation]]
Vulkan provides applications the opportunity to perform host memory
allocations on behalf of the Vulkan implementation.
If this feature is not used, the implementation will perform its own memory
allocations.
Since most memory allocations are off the critical path, this is not meant
as a performance feature.
Rather, this can: be useful for certain embedded systems, for debugging
purposes (e.g. putting a guard page after all host allocations), or for
memory allocation logging.
[open,refpage='VkAllocationCallbacks',desc='Structure containing callback function pointers for memory allocation',type='structs']
--
Allocators are provided by the application as a pointer to a
sname:VkAllocationCallbacks structure:
include::../api/structs/VkAllocationCallbacks.txt[]
* pname:pUserData is a value to be interpreted by the implementation of
the callbacks.
When any of the callbacks in sname:VkAllocationCallbacks are called, the
Vulkan implementation will pass this value as the first parameter to the
callback.
This value can: vary each time an allocator is passed into a command,
even when the same object takes an allocator in multiple commands.
* pname:pfnAllocation is a pointer to an application-defined memory
allocation function of type tlink:PFN_vkAllocationFunction.
* pname:pfnReallocation is a pointer to an application-defined memory
reallocation function of type tlink:PFN_vkReallocationFunction.
* pname:pfnFree is a pointer to an application-defined memory free
function of type tlink:PFN_vkFreeFunction.
* pname:pfnInternalAllocation is a pointer to an application-defined
function that is called by the implementation when the implementation
makes internal allocations, and it is of type
tlink:PFN_vkInternalAllocationNotification.
* pname:pfnInternalFree is a pointer to an application-defined function
that is called by the implementation when the implementation frees
internal allocations, and it is of type
tlink:PFN_vkInternalFreeNotification.
.Valid Usage
****
* [[VUID-VkAllocationCallbacks-pfnAllocation-00632]]
pname:pfnAllocation must: be a pointer to a valid user-defined
tlink:PFN_vkAllocationFunction
* [[VUID-VkAllocationCallbacks-pfnReallocation-00633]]
pname:pfnReallocation must: be a pointer to a valid user-defined
tlink:PFN_vkReallocationFunction
* [[VUID-VkAllocationCallbacks-pfnFree-00634]]
pname:pfnFree must: be a pointer to a valid user-defined
tlink:PFN_vkFreeFunction
* [[VUID-VkAllocationCallbacks-pfnInternalAllocation-00635]]
If either of pname:pfnInternalAllocation or pname:pfnInternalFree is not
`NULL`, both must: be valid callbacks
****
include::../validity/structs/VkAllocationCallbacks.txt[]
--
[open,refpage='PFN_vkAllocationFunction',desc='Application-defined memory allocation function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnAllocation is:
include::../api/funcpointers/PFN_vkAllocationFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the size in bytes of the requested allocation.
* pname:alignment is the requested alignment of the allocation in bytes
and must: be a power of two.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
[[vkAllocationFunction_return_rules]]
If pname:pfnAllocation is unable to allocate the requested memory, it must:
return `NULL`.
If the allocation was successful, it must: return a valid pointer to memory
allocation containing at least pname:size bytes, and with the pointer value
being a multiple of pname:alignment.
[NOTE]
.Note
====
Correct Vulkan operation cannot: be assumed if the application does not
follow these rules.
For example, pname:pfnAllocation (or pname:pfnReallocation) could cause
termination of running Vulkan instance(s) on a failed allocation for
debugging purposes, either directly or indirectly.
In these circumstances, it cannot: be assumed that any part of any affected
VkInstance objects are going to operate correctly (even
flink:vkDestroyInstance), and the application must: ensure it cleans up
properly via other means (e.g. process termination).
====
If pname:pfnAllocation returns `NULL`, and if the implementation is unable
to continue correct processing of the current command without the requested
allocation, it must: treat this as a run-time error, and generate
ename:VK_ERROR_OUT_OF_HOST_MEMORY at the appropriate time for the command in
which the condition was detected, as described in <<fundamentals-errorcodes,
Return Codes>>.
If the implementation is able to continue correct processing of the current
command without the requested allocation, then it may: do so, and must: not
generate ename:VK_ERROR_OUT_OF_HOST_MEMORY as a result of this failed
allocation.
--
[open,refpage='PFN_vkReallocationFunction',desc='Application-defined memory reallocation function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnReallocation is:
include::../api/funcpointers/PFN_vkReallocationFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:pOriginal must: be either `NULL` or a pointer previously returned
by pname:pfnReallocation or pname:pfnAllocation of the same allocator.
* pname:size is the size in bytes of the requested allocation.
* pname:alignment is the requested alignment of the allocation in bytes
and must: be a power of two.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
pname:pfnReallocation must: return an allocation with enough space for
pname:size bytes, and the contents of the original allocation from bytes
zero to [eq]#min(original size, new size) - 1# must: be preserved in the
returned allocation.
If pname:size is larger than the old size, the contents of the additional
space are undefined.
If satisfying these requirements involves creating a new allocation, then
the old allocation should: be freed.
If pname:pOriginal is `NULL`, then pname:pfnReallocation must: behave
equivalently to a call to tlink:PFN_vkAllocationFunction with the same
parameter values (without pname:pOriginal).
If pname:size is zero, then pname:pfnReallocation must: behave equivalently
to a call to tlink:PFN_vkFreeFunction with the same pname:pUserData
parameter value, and pname:pMemory equal to pname:pOriginal.
If pname:pOriginal is non-`NULL`, the implementation must: ensure that
pname:alignment is equal to the pname:alignment used to originally allocate
pname:pOriginal.
If this function fails and pname:pOriginal is non-`NULL` the application
must: not free the old allocation.
pname:pfnReallocation must: follow the same
<<vkAllocationFunction_return_rules, rules for return values as
tname:PFN_vkAllocationFunction>>.
--
[open,refpage='PFN_vkFreeFunction',desc='Application-defined memory free function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnFree is:
include::../api/funcpointers/PFN_vkFreeFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:pMemory is the allocation to be freed.
pname:pMemory may: be `NULL`, which the callback must: handle safely.
If pname:pMemory is non-`NULL`, it must: be a pointer previously allocated
by pname:pfnAllocation or pname:pfnReallocation.
The application should: free this memory.
--
[open,refpage='PFN_vkInternalAllocationNotification',desc='Application-defined memory allocation notification function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnInternalAllocation is:
include::../api/funcpointers/PFN_vkInternalAllocationNotification.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the requested size of an allocation.
* pname:allocationType is a elink:VkInternalAllocationType value
specifying the requested type of an allocation.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
This is a purely informational callback.
--
[open,refpage='PFN_vkInternalFreeNotification',desc='Application-defined memory free notification function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnInternalFree is:
include::../api/funcpointers/PFN_vkInternalFreeNotification.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the requested size of an allocation.
* pname:allocationType is a elink:VkInternalAllocationType value
specifying the requested type of an allocation.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
--
[open,refpage='VkSystemAllocationScope',desc='Allocation scope',type='enums',xrefs='VkAllocationCallbacks']
--
[[memory-host-allocation-scope]]
Each allocation has an _allocation scope_ which defines its lifetime and
which object it is associated with.
Possible values passed to the pname:allocationScope parameter of the
callback functions specified by slink:VkAllocationCallbacks, indicating the
allocation scope, are:
include::../api/enums/VkSystemAllocationScope.txt[]
* ename:VK_SYSTEM_ALLOCATION_SCOPE_COMMAND specifies that the allocation
is scoped to the duration of the Vulkan command.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT specifies that the allocation is
scoped to the lifetime of the Vulkan object that is being created or
used.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE specifies that the allocation is
scoped to the lifetime of a sname:VkPipelineCache
ifdef::VK_EXT_validation_cache[]
or sname:VkValidationCacheEXT
endif::VK_EXT_validation_cache[]
object.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_DEVICE specifies that the allocation is
scoped to the lifetime of the Vulkan device.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE specifies that the allocation
is scoped to the lifetime of the Vulkan instance.
Most Vulkan commands operate on a single object, or there is a sole object
that is being created or manipulated.
When an allocation uses an allocation scope of
ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT or
ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE, the allocation is scoped to the
object being created or manipulated.
When an implementation requires host memory, it will make callbacks to the
application using the most specific allocator and allocation scope
available:
* If an allocation is scoped to the duration of a command, the allocator
will use the ename:VK_SYSTEM_ALLOCATION_SCOPE_COMMAND allocation scope.
The most specific allocator available is used: if the object being
created or manipulated has an allocator, that object's allocator will be
used, else if the parent sname:VkDevice has an allocator it will be
used, else if the parent sname:VkInstance has an allocator it will be
used.
Else,
* If an allocation is associated with an object of type
ifdef::VK_EXT_validation_cache[]
sname:VkValidationCacheEXT or
endif::VK_EXT_validation_cache[]
sname:VkPipelineCache, the allocator will use the
ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE allocation scope.
The most specific allocator available is used (cache, else device, else
instance).
Else,
* If an allocation is scoped to the lifetime of an object, that object is
being created or manipulated by the command, and that object's type is
not sname:VkDevice or sname:VkInstance, the allocator will use an
allocation scope of ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT.
The most specific allocator available is used (object, else device, else
instance).
Else,
* If an allocation is scoped to the lifetime of a device, the allocator
will use an allocation scope of ename:VK_SYSTEM_ALLOCATION_SCOPE_DEVICE.
The most specific allocator available is used (device, else instance).
Else,
* If the allocation is scoped to the lifetime of an instance and the
instance has an allocator, its allocator will be used with an allocation
scope of ename:VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE.
* Otherwise an implementation will allocate memory through an alternative
mechanism that is unspecified.
--
Objects that are allocated from pools do not specify their own allocator.
When an implementation requires host memory for such an object, that memory
is sourced from the object's parent pool's allocator.
The application is not expected to handle allocating memory that is intended
for execution by the host due to the complexities of differing security
implementations across multiple platforms.
The implementation will allocate such memory internally and invoke an
application provided informational callback when these _internal
allocations_ are allocated and freed.
Upon allocation of executable memory, pname:pfnInternalAllocation will be
called.
Upon freeing executable memory, pname:pfnInternalFree will be called.
An implementation will only call an informational callback for executable
memory allocations and frees.
[open,refpage='VkInternalAllocationType',desc='Allocation type',type='enums',xrefs='PFN_vkInternalAllocationNotification PFN_vkInternalFreeNotification']
--
The pname:allocationType parameter to the pname:pfnInternalAllocation and
pname:pfnInternalFree functions may: be one of the following values:
include::../api/enums/VkInternalAllocationType.txt[]
* ename:VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE specifies that the
allocation is intended for execution by the host.
--
An implementation must: only make calls into an application-provided
allocator during the execution of an API command.
An implementation must: only make calls into an application-provided
allocator from the same thread that called the provoking API command.
The implementation should: not synchronize calls to any of the callbacks.
If synchronization is needed, the callbacks must: provide it themselves.
The informational callbacks are subject to the same restrictions as the
allocation callbacks.
If an implementation intends to make calls through an
sname:VkAllocationCallbacks structure between the time a ftext:vkCreate*
command returns and the time a corresponding ftext:vkDestroy* command
begins, that implementation must: save a copy of the allocator before the
ftext:vkCreate* command returns.
The callback functions and any data structures they rely upon must: remain
valid for the lifetime of the object they are associated with.
If an allocator is provided to a ftext:vkCreate* command, a _compatible_
allocator must: be provided to the corresponding ftext:vkDestroy* command.
Two sname:VkAllocationCallbacks structures are compatible if memory
allocated with pname:pfnAllocation or pname:pfnReallocation in each can: be
freed with pname:pfnReallocation or pname:pfnFree in the other.
An allocator must: not be provided to a ftext:vkDestroy* command if an
allocator was not provided to the corresponding ftext:vkCreate* command.
If a non-`NULL` allocator is used, the pname:pfnAllocation,
pname:pfnReallocation and pname:pfnFree members must: be non-`NULL` and
point to valid implementations of the callbacks.
An application can: choose to not provide informational callbacks by setting
both pname:pfnInternalAllocation and pname:pfnInternalFree to `NULL`.
pname:pfnInternalAllocation and pname:pfnInternalFree must: either both be
`NULL` or both be non-`NULL`.
If pname:pfnAllocation or pname:pfnReallocation fail, the implementation
may: fail object creation and/or generate an
ename:VK_ERROR_OUT_OF_HOST_MEMORY error, as appropriate.
Allocation callbacks must: not call any Vulkan commands.
The following sets of rules define when an implementation is permitted to
call the allocator callbacks.
pname:pfnAllocation or pname:pfnReallocation may: be called in the following
situations:
* Allocations scoped to a sname:VkDevice or sname:VkInstance may: be
allocated from any API command.
* Allocations scoped to a command may: be allocated from any API command.
* Allocations scoped to a sname:VkPipelineCache may: only be allocated
from:
** fname:vkCreatePipelineCache
** fname:vkMergePipelineCaches for pname:dstCache
** fname:vkCreateGraphicsPipelines for pname:pipelineCache
** fname:vkCreateComputePipelines for pname:pipelineCache
ifdef::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkValidationCacheEXT may: only be
allocated from:
** fname:vkCreateValidationCacheEXT
** fname:vkMergeValidationCachesEXT for pname:dstCache
** fname:vkCreateShaderModule for pname:validationCache in
sname:VkShaderModuleValidationCacheCreateInfoEXT
endif::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkDescriptorPool may: only be allocated
from:
** any command that takes the pool as a direct argument
** fname:vkAllocateDescriptorSets for the pname:descriptorPool member of
its pname:pAllocateInfo parameter
** fname:vkCreateDescriptorPool
* Allocations scoped to a sname:VkCommandPool may: only be allocated from:
** any command that takes the pool as a direct argument
** fname:vkCreateCommandPool
** fname:vkAllocateCommandBuffers for the pname:commandPool member of its
pname:pAllocateInfo parameter
** any ftext:vkCmd* command whose pname:commandBuffer was allocated from
that sname:VkCommandPool
* Allocations scoped to any other object may: only be allocated in that
object's ftext:vkCreate* command.
pname:pfnFree may: be called in the following situations:
* Allocations scoped to a sname:VkDevice or sname:VkInstance may: be freed
from any API command.
* Allocations scoped to a command must: be freed by any API command which
allocates such memory.
* Allocations scoped to a sname:VkPipelineCache may: be freed from
fname:vkDestroyPipelineCache.
ifdef::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkValidationCacheEXT may: be freed from
fname:vkDestroyValidationCacheEXT.
endif::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkDescriptorPool may: be freed from
** any command that takes the pool as a direct argument
* Allocations scoped to a sname:VkCommandPool may: be freed from:
** any command that takes the pool as a direct argument
** fname:vkResetCommandBuffer whose pname:commandBuffer was allocated from
that sname:VkCommandPool
* Allocations scoped to any other object may: be freed in that object's
ftext:vkDestroy* command.
* Any command that allocates host memory may: also free host memory of the
same scope.
[[memory-device]]
== Device Memory
_Device memory_ is memory that is visible to the device -- for example
the contents of the image or buffer objects, which can: be natively used by
the device.
Memory properties of a physical device describe the memory heaps and memory
types available.
[open,refpage='vkGetPhysicalDeviceMemoryProperties',desc='Reports memory information for the specified physical device',type='protos']
--
To query memory properties, call:
include::../api/protos/vkGetPhysicalDeviceMemoryProperties.txt[]
* pname:physicalDevice is the handle to the device to query.
* pname:pMemoryProperties points to an instance of
sname:VkPhysicalDeviceMemoryProperties structure in which the properties
are returned.
include::../validity/protos/vkGetPhysicalDeviceMemoryProperties.txt[]
--
[open,refpage='VkPhysicalDeviceMemoryProperties',desc='Structure specifying physical device memory properties',type='structs']
--
The sname:VkPhysicalDeviceMemoryProperties structure is defined as:
include::../api/structs/VkPhysicalDeviceMemoryProperties.txt[]
* pname:memoryTypeCount is the number of valid elements in the
pname:memoryTypes array.
* pname:memoryTypes is an array of slink:VkMemoryType structures
describing the _memory types_ that can: be used to access memory
allocated from the heaps specified by pname:memoryHeaps.
* pname:memoryHeapCount is the number of valid elements in the
pname:memoryHeaps array.
* pname:memoryHeaps is an array of slink:VkMemoryHeap structures
describing the _memory heaps_ from which memory can: be allocated.
The sname:VkPhysicalDeviceMemoryProperties structure describes a number of
_memory heaps_ as well as a number of _memory types_ that can: be used to
access memory allocated in those heaps.
Each heap describes a memory resource of a particular size, and each memory
type describes a set of memory properties (e.g. host cached vs uncached)
that can: be used with a given memory heap.
Allocations using a particular memory type will consume resources from the
heap indicated by that memory type's heap index.
More than one memory type may: share each heap, and the heaps and memory
types provide a mechanism to advertise an accurate size of the physical
memory resources while allowing the memory to be used with a variety of
different properties.
The number of memory heaps is given by pname:memoryHeapCount and is less
than or equal to ename:VK_MAX_MEMORY_HEAPS.
Each heap is described by an element of the pname:memoryHeaps array as a
slink:VkMemoryHeap structure.
The number of memory types available across all memory heaps is given by
pname:memoryTypeCount and is less than or equal to
ename:VK_MAX_MEMORY_TYPES.
Each memory type is described by an element of the pname:memoryTypes array
as a slink:VkMemoryType structure.
At least one heap must: include ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT in
slink:VkMemoryHeap::pname:flags.
If there are multiple heaps that all have similar performance
characteristics, they may: all include
ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT.
In a unified memory architecture (UMA) system there is often only a single
memory heap which is considered to be equally "`local`" to the host and to
the device, and such an implementation must: advertise the heap as
device-local.
[[memory-device-bitmask-list]]
Each memory type returned by flink:vkGetPhysicalDeviceMemoryProperties must:
have its pname:propertyFlags set to one of the following values:
* 0
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
There must: be at least one memory type with both the
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bits set in its
pname:propertyFlags.
There must: be at least one memory type with the
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set in its
pname:propertyFlags.
For each pair of elements *X* and *Y* returned in pname:memoryTypes, *X*
must: be placed at a lower index position than *Y* if:
* either the set of bit flags returned in the pname:propertyFlags member
of *X* is a strict subset of the set of bit flags returned in the
pname:propertyFlags member of *Y*.
* or the pname:propertyFlags members of *X* and *Y* are equal, and *X*
belongs to a memory heap with greater performance (as determined in an
implementation-specific manner).
[NOTE]
.Note
====
There is no ordering requirement between *X* and *Y* elements for the case
their pname:propertyFlags members are not in a subset relation.
That potentially allows more than one possible way to order the same set of
memory types.
Notice that the
<<memory-device-bitmask-list,list of all allowed memory property flag combinations>>
is written in the required order.
But if instead
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT was before
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
the list would still be in the required order.
====
This ordering requirement enables applications to use a simple search loop
to select the desired memory type along the lines of:
[source,c++]
---------------------------------------------------
// Find a memory in `memoryTypeBitsRequirement` that includes all of `requiredProperties`
int32_t findProperties(const VkPhysicalDeviceMemoryProperties* pMemoryProperties,
uint32_t memoryTypeBitsRequirement,
VkMemoryPropertyFlags requiredProperties) {
const uint32_t memoryCount = pMemoryProperties->memoryTypeCount;
for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) {
const uint32_t memoryTypeBits = (1 << memoryIndex);
const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits;
const VkMemoryPropertyFlags properties =
pMemoryProperties->memoryTypes[memoryIndex].propertyFlags;
const bool hasRequiredProperties =
(properties & requiredProperties) == requiredProperties;
if (isRequiredMemoryType && hasRequiredProperties)
return static_cast<int32_t>(memoryIndex);
}
// failed to find memory type
return -1;
}
// Try to find an optimal memory type, or if it does not exist try fallback memory type
// `device` is the VkDevice
// `image` is the VkImage that requires memory to be bound
// `memoryProperties` properties as returned by vkGetPhysicalDeviceMemoryProperties
// `requiredProperties` are the property flags that must be present
// `optimalProperties` are the property flags that are preferred by the application
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(device, image, &memoryRequirements);
int32_t memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, optimalProperties);
if (memoryType == -1) // not found; try fallback properties
memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, requiredProperties);
---------------------------------------------------
include::../validity/structs/VkPhysicalDeviceMemoryProperties.txt[]
--
ifdef::VK_KHR_get_physical_device_properties2[]
[open,refpage='vkGetPhysicalDeviceMemoryProperties2KHR',desc='Reports memory information for the specified physical device',type='protos']
--
To query memory properties, call:
include::../api/protos/vkGetPhysicalDeviceMemoryProperties2KHR.txt[]
* pname:physicalDevice is the handle to the device to query.
* pname:pMemoryProperties points to an instance of
sname:VkPhysicalDeviceMemoryProperties2KHR structure in which the
properties are returned.
fname:vkGetPhysicalDeviceMemoryProperties2KHR behaves similarly to
flink:vkGetPhysicalDeviceMemoryProperties, with the ability to return
extended information in a pname:pNext chain of output structures.
include::../validity/protos/vkGetPhysicalDeviceMemoryProperties2KHR.txt[]
--
[open,refpage='VkPhysicalDeviceMemoryProperties2KHR',desc='Structure specifying physical device memory properties',type='structs']
--
The sname:VkPhysicalDeviceMemoryProperties2KHR structure is defined as:
include::../api/structs/VkPhysicalDeviceMemoryProperties2KHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memoryProperties is a structure of type
slink:VkPhysicalDeviceMemoryProperties which is populated with the same
values as in flink:vkGetPhysicalDeviceMemoryProperties.
include::../validity/structs/VkPhysicalDeviceMemoryProperties2KHR.txt[]
--
endif::VK_KHR_get_physical_device_properties2[]
[open,refpage='VkMemoryHeap',desc='Structure specifying a memory heap',type='structs']
--
The sname:VkMemoryHeap structure is defined as:
include::../api/structs/VkMemoryHeap.txt[]
* pname:size is the total memory size in bytes in the heap.
* pname:flags is a bitmask of elink:VkMemoryHeapFlagBits specifying
attribute flags for the heap.
include::../validity/structs/VkMemoryHeap.txt[]
--
[open,refpage='VkMemoryHeapFlagBits',desc='Bitmask specifying attribute flags for a heap',type='enums']
--
Bits which may: be set in slink:VkMemoryHeap::pname:flags, indicating
attribute flags for the heap, are:
include::../api/enums/VkMemoryHeapFlagBits.txt[]
* ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT indicates that the heap
corresponds to device local memory.
Device local memory may: have different performance characteristics than
host local memory, and may: support different memory property flags.
ifdef::VK_KHX_device_group_creation[]
* ename:VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX indicates that in a logical
device representing more than one physical device, there is a
per-physical device instance of the heap memory.
By default, an allocation from such a heap will be replicated to each
physical device's instance of the heap.
endif::VK_KHX_device_group_creation[]
--
[open,refpage='VkMemoryType',desc='Structure specifying memory type',type='structs']
--
The sname:VkMemoryType structure is defined as:
include::../api/structs/VkMemoryType.txt[]
* pname:heapIndex describes which memory heap this memory type corresponds
to, and must: be less than pname:memoryHeapCount from the
slink:VkPhysicalDeviceMemoryProperties structure.
* pname:propertyFlags is a bitmask of elink:VkMemoryPropertyFlagBits of
properties for this memory type.
include::../validity/structs/VkMemoryType.txt[]
--
[open,refpage='VkMemoryPropertyFlagBits',desc='Bitmask specifying properties for a memory type',type='enums']
--
Bits which may: be set in slink:VkMemoryType::pname:propertyFlags,
indicating properties of a memory heap, are:
include::../api/enums/VkMemoryPropertyFlagBits.txt[]
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit indicates that memory
allocated with this type is the most efficient for device access.
This property will be set if and only if the memory type belongs to a
heap with the ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit indicates that memory
allocated with this type can: be mapped for host access using
flink:vkMapMemory.
* ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit indicates that the host
cache management commands flink:vkFlushMappedMemoryRanges and
flink:vkInvalidateMappedMemoryRanges are not needed to flush host writes
to the device or make device writes visible to the host, respectively.
* ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT bit indicates that memory
allocated with this type is cached on the host.
Host memory accesses to uncached memory are slower than to cached
memory, however uncached memory is always host coherent.
* ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit indicates that the
memory type only allows device access to the memory.
Memory types must: not have both
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT and
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set.
Additionally, the object's backing memory may: be provided by the
implementation lazily as specified in <<memory-device-lazy_allocation,
Lazily Allocated Memory>>.
--
[open,refpage='VkDeviceMemory',desc='Opaque handle to a device memory object',type='handles']
--
A Vulkan device operates on data in device memory via memory objects that
are represented in the API by a sname:VkDeviceMemory handle:
include::../api/handles/VkDeviceMemory.txt[]
--
[open,refpage='vkAllocateMemory',desc='Allocate GPU memory',type='protos']
--
To allocate memory objects, call:
include::../api/protos/vkAllocateMemory.txt[]
* pname:device is the logical device that owns the memory.
* pname:pAllocateInfo is a pointer to an instance of the
slink:VkMemoryAllocateInfo structure describing parameters of the
allocation.
A successful returned allocation must: use the requested parameters --
no substitution is permitted by the implementation.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname:pMemory is a pointer to a sname:VkDeviceMemory handle in which
information about the allocated memory is returned.
Allocations returned by fname:vkAllocateMemory are guaranteed to meet any
alignment requirement of the implementation.
For example, if an implementation requires 128 byte alignment for images and
64 byte alignment for buffers, the device memory returned through this
mechanism would be 128-byte aligned.
This ensures that applications can: correctly suballocate objects of
different types (with potentially different alignment requirements) in the
same memory object.
When memory is allocated, its contents are undefined.
There is an implementation-dependent maximum number of memory allocations
that can: be simultaneously created on a device.
This is specified by the
<<features-limits-maxMemoryAllocationCount,pname:maxMemoryAllocationCount>>
member of the slink:VkPhysicalDeviceLimits structure.
If pname:maxMemoryAllocationCount is exceeded, fname:vkAllocateMemory will
return ename:VK_ERROR_TOO_MANY_OBJECTS.
Some platforms may: have a limit on the maximum size of a single allocation.
For example, certain systems may: fail to create allocations with a size
greater than or equal to 4GB.
Such a limit is implementation-dependent, and if such a failure occurs then
the error ename:VK_ERROR_OUT_OF_DEVICE_MEMORY must: be returned.
.Valid Usage
****
* pname:pAllocateInfo\->pname:allocationSize must: be less than or equal
to
slink:VkPhysicalDeviceMemoryProperties::pname:memoryHeaps[pname:pAllocateInfo\->pname:memoryTypeIndex].pname:size
as returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
* pname:pAllocateInfo\->pname:memoryTypeIndex must: be less than
slink:VkPhysicalDeviceMemoryProperties::pname:memoryTypeCount as
returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
****
include::../validity/protos/vkAllocateMemory.txt[]
--
[open,refpage='VkMemoryAllocateInfo',desc='Structure containing parameters of a memory allocation',type='structs']
--
The sname:VkMemoryAllocateInfo structure is defined as:
include::../api/structs/VkMemoryAllocateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:allocationSize is the size of the allocation in bytes
* pname:memoryTypeIndex is an index identifying a memory type from the
pname:memoryTypes array of the slink:VkPhysicalDeviceMemoryProperties
structure
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
If the pname:pNext chain contains an instance of
ifdef::VK_KHR_external_memory_win32[]
slink:VkImportMemoryWin32HandleInfoKHR with a non-zero value for
sname:VkImportMemoryWin32HandleInfoKHR::pname:handleType,
endif::VK_KHR_external_memory_win32[]
ifdef::VK_KHR_external_memory_win32+VK_KHR_external_memory_fd[]
or
endif::VK_KHR_external_memory_win32+VK_KHR_external_memory_fd[]
ifdef::VK_KHR_external_memory_fd[]
slink:VkImportMemoryFdInfoKHR with a non-zero value for
sname:VkImportMemoryFdInfoKHR::pname:handleType,
endif::VK_KHR_external_memory_fd[]
the slink:VkMemoryAllocateInfo instance defines a memory import operation.
Importing memory must: not modify the content of the memory.
Implementations must: ensure that importing memory does not enable the
importing Vulkan instance to access any memory or resources in other Vulkan
instances other than that corresponding to the memory object imported.
Implementations must: also ensure accessing imported memory which has not
been initialized does not allow the importing Vulkan instance to obtain data
from the exporting Vulkan instance or vice-versa.
[NOTE]
.Note
====
How exported and imported memory is isolated is left to the implementation,
but applications should be aware that such isolation may: prevent
implementations from placing multiple exportable memory objects in the same
physical or virtual page.
Hence, applications should: avoid creating many small external memory
objects whenever possible.
====
When performing a memory import operation, it is the responsibility of the
application to ensure the external handles meet all valid usage
requirements.
However, implementations must: perform sufficient validation of external
handles to ensure that the operation results in a valid memory object which
will not cause program termination, device loss, queue stalls, or corruption
of other resources when used as allowed according to its allocation
parameters.
If the external handle provided does not meet these requirements, the
implementation must: fail the memory import operation with the error code
ename:VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR.
endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
.Valid Usage
****
* [[VUID-VkMemoryAllocateInfo-allocationSize-00638]]
pname:allocationSize must: be greater than `0`
ifdef::VK_KHR_external_memory[]
ifdef::VK_KHR_dedicated_allocation,VK_NV_dedicated_allocation[]
* [[VUID-VkMemoryAllocateInfo-pNext-00639]]
If the pname:pNext chain contains an instance of
sname:VkExportMemoryAllocateInfoKHR, and any of the handle types
specified in sname:VkExportMemoryAllocateInfoKHR::pname:handleTypes
require a dedicated allocation, as reported by
flink:vkGetPhysicalDeviceImageFormatProperties2KHR in
sname:VkExternalImageFormatPropertiesKHR::pname:externalMemoryProperties::pname:externalMemoryFeatures
or
sname:VkExternalBufferPropertiesKHR::pname:externalMemoryProperties::pname:externalMemoryFeatures,
the pname:pNext chain must contain an instance of
ifdef::VK_KHR_dedicated_allocation[slink:VkMemoryDedicatedAllocateInfoKHR]
ifdef::VK_KHR_dedicated_allocation+VK_NV_dedicated_allocation[or]
ifdef::VK_NV_dedicated_allocation[slink:VkDedicatedAllocationMemoryAllocateInfoNV]
with either its pname:image or pname:buffer field set to a value other
than ename:VK_NULL_HANDLE.
endif::VK_KHR_dedicated_allocation,VK_NV_dedicated_allocation[]
endif::VK_KHR_external_memory[]
ifdef::VK_KHR_external_memory+VK_NV_external_memory[]
* [[VUID-VkMemoryAllocateInfo-pNext-00640]]
If the pname:pNext chain contains an instance of
slink:VkExportMemoryAllocateInfoKHR, it must: not contain an instance of
slink:VkExportMemoryAllocateInfoNV or
slink:VkExportMemoryWin32HandleInfoNV.
endif::VK_KHR_external_memory+VK_NV_external_memory[]
ifdef::VK_KHR_external_memory_win32+VK_NV_external_memory_win32[]
* [[VUID-VkMemoryAllocateInfo-pNext-00641]]
If the pname:pNext chain contains an instance of
slink:VkImportMemoryWin32HandleInfoKHR, it must: not contain an instance
of slink:VkImportMemoryWin32HandleInfoNV.
endif::VK_KHR_external_memory_win32+VK_NV_external_memory_win32[]
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryAllocateInfo-allocationSize-00642]]
If the parameters define an import operation and the external handle
specified was created by the Vulkan API, the values of
pname:allocationSize and pname:memoryTypeIndex must: match those
specified when the memory object being imported was created.
endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
ifdef::VK_KHR_external_memory+VK_KHX_device_group[]
* [[VUID-VkMemoryAllocateInfo-None-00643]]
If the parameters define an import operation and the external handle
specified was created by the Vulkan API, the device mask specified by
slink:VkMemoryAllocateFlagsInfoKHX must: match that specified when the
memory object being imported was allocated.
* [[VUID-VkMemoryAllocateInfo-None-00644]]
If the parameters define an import operation and the external handle
specified was created by the Vulkan API, the list of physical devices
that comprise the logical device passed to flink:vkAllocateMemory must:
match the list of physical devices that comprise the logical device on
which the memory was originally allocated.
endif::VK_KHR_external_memory+VK_KHX_device_group[]
ifdef::VK_KHR_external_memory_win32[]
* [[VUID-VkMemoryAllocateInfo-memoryTypeIndex-00645]]
If the parameters define an import operation and the external handle is
an NT handle or a global share handle created outside of the Vulkan API,
the value of pname:memoryTypeIndex must: be one of those returned by
flink:vkGetMemoryWin32HandlePropertiesKHR.
* [[VUID-VkMemoryAllocateInfo-allocationSize-00646]]
If the parameters define an import operation and the external handle
type is ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR, or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR,
pname:allocationSize must: match the size reported in the memory
requirements of the pname:image or pname:buffer member of the instance
of sname:VkDedicatedAllocationMemoryAllocateInfoNV included in the
pname:pNext chain.
* [[VUID-VkMemoryAllocateInfo-allocationSize-00647]]
If the parameters define an import operation and the external handle
type is ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR,
pname:allocationSize must: match the size specified when creating the
Direct3D 12 heap from which the external handle was extracted.
endif::VK_KHR_external_memory_win32[]
ifdef::VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryAllocateInfo-memoryTypeIndex-00648]]
If the parameters define an import operation and the external handle is
a POSIX file descriptor created outside of the Vulkan API, the value of
pname:memoryTypeIndex must: be one of those returned by
flink:vkGetMemoryFdPropertiesKHR.
endif::VK_KHR_external_memory_fd[]
****
include::../validity/structs/VkMemoryAllocateInfo.txt[]
--
ifdef::VK_KHR_dedicated_allocation[]
[open,refpage='VkMemoryDedicatedAllocateInfoKHR',desc='Specify a dedicated memory allocation resource',type='structs']
--
If the pname:pNext chain includes a sname:VkMemoryDedicatedAllocateInfoKHR
structure, then that structure includes a handle of the sole buffer or image
resource that the memory can: be bound to.
The sname:VkMemoryDedicatedAllocateInfoKHR structure is defined as:
include::../api/structs/VkMemoryDedicatedAllocateInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this
memory will be bound to.
* pname:buffer is dlink:VK_NULL_HANDLE or a handle of a buffer which this
memory will be bound to.
.Valid Usage
****
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01432]]
At least one of pname:image and pname:buffer must: be
dlink:VK_NULL_HANDLE
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01433]]
If pname:image is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the image