Halide
vulkan_memory.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_VULKAN_MEMORY_H
2 #define HALIDE_RUNTIME_VULKAN_MEMORY_H
3 
6 #include "vulkan_internal.h"
7 
8 // Uncomment to enable verbose memory allocation debugging
9 // #define HL_VK_DEBUG_MEM 1
10 
11 namespace Halide {
12 namespace Runtime {
13 namespace Internal {
14 namespace Vulkan {
15 
16 // --------------------------------------------------------------------------
17 
18 // Enable external client to override Vulkan allocation callbacks (if they so desire)
20 WEAK const VkAllocationCallbacks *custom_allocation_callbacks = nullptr; // nullptr => use Vulkan runtime implementation
21 
22 // --------------------------------------------------------------------------
23 
24 // Runtime configuration parameters to adjust the behaviour of the block allocator
26  size_t maximum_pool_size = 0; //< Maximum number of bytes to allocate for the entire pool (including all blocks). Specified in bytes. Zero means no constraint
27  size_t minimum_block_size = 32 * 1024 * 1024; //< Default block size is 32MB
28  size_t maximum_block_size = 0; //< Specified in bytes. Zero means no constraint
29  size_t maximum_block_count = 0; //< Maximum number of blocks to allocate. Zero means no constraint
30  size_t nearest_multiple = 32; //< Always round up the requested region sizes to the given integer value. Zero means no constraint
31 };
33 
34 // --------------------------------------------------------------------------
35 
36 /** Vulkan Memory Allocator class interface for managing large
37  * memory requests stored as contiguous blocks of memory, which
38  * are then sub-allocated into smaller regions of
39  * memory to avoid the excessive cost of vkAllocate and the limited
40  * number of available allocation calls through the API.
41  */
43 public:
44  // disable copy constructors and assignment
47 
48  // disable non-factory constrction
49  VulkanMemoryAllocator() = delete;
50  ~VulkanMemoryAllocator() = delete;
51 
52  // Factory methods for creation / destruction
53  static VulkanMemoryAllocator *create(void *user_context, const VulkanMemoryConfig &config,
54  VkDevice dev, VkPhysicalDevice phys_dev,
55  const SystemMemoryAllocatorFns &system_allocator,
56  const VkAllocationCallbacks *alloc_callbacks = nullptr);
57 
58  static int destroy(void *user_context, VulkanMemoryAllocator *allocator);
59 
60  // Public interface methods
61  MemoryRegion *reserve(void *user_context, MemoryRequest &request);
62  int release(void *user_context, MemoryRegion *region); //< unmark and cache the region for reuse
63  int reclaim(void *user_context, MemoryRegion *region); //< free the region and consolidate
64  int retain(void *user_context, MemoryRegion *region); //< retain the region and increase its use count
65  bool collect(void *user_context); //< returns true if any blocks were removed
66  int release(void *user_context);
67  int destroy(void *user_context);
68 
69  void *map(void *user_context, MemoryRegion *region);
70  int unmap(void *user_context, MemoryRegion *region);
71  MemoryRegion *create_crop(void *user_context, MemoryRegion *region, uint64_t offset);
72  int destroy_crop(void *user_context, MemoryRegion *region);
73  MemoryRegion *owner_of(void *user_context, MemoryRegion *region);
74 
75  VkDevice current_device() const {
76  return this->device;
77  }
78  VkPhysicalDevice current_physical_device() const {
79  return this->physical_device;
80  }
82  return this->alloc_callbacks;
83  }
84 
85  static const VulkanMemoryConfig &default_config();
86 
87  static int allocate_block(void *instance_ptr, MemoryBlock *block);
88  static int deallocate_block(void *instance_ptr, MemoryBlock *block);
89 
90  static int allocate_region(void *instance_ptr, MemoryRegion *region);
91  static int deallocate_region(void *instance_ptr, MemoryRegion *region);
92 
93  size_t bytes_allocated_for_blocks() const;
94  size_t blocks_allocated() const;
95 
96  size_t bytes_allocated_for_regions() const;
97  size_t regions_allocated() const;
98 
99 private:
100  static constexpr uint32_t invalid_usage_flags = uint32_t(-1);
101  static constexpr uint32_t invalid_memory_type = uint32_t(VK_MAX_MEMORY_TYPES);
102 
103  // Initializes a new instance
104  int initialize(void *user_context, const VulkanMemoryConfig &config,
105  VkDevice dev, VkPhysicalDevice phys_dev,
106  const SystemMemoryAllocatorFns &system_allocator,
107  const VkAllocationCallbacks *alloc_callbacks = nullptr);
108 
109  uint32_t select_memory_usage(void *user_context, MemoryProperties properties) const;
110 
111  uint32_t select_memory_type(void *user_context,
112  VkPhysicalDevice physical_device,
113  MemoryProperties properties,
114  uint32_t required_flags) const;
115 
116  size_t block_byte_count = 0;
117  size_t block_count = 0;
118  size_t region_byte_count = 0;
119  size_t region_count = 0;
120  void *owner_context = nullptr;
121  VulkanMemoryConfig config;
122  VkDevice device = nullptr;
123  VkPhysicalDevice physical_device = nullptr;
124  VkPhysicalDeviceLimits physical_device_limits = {};
125  const VkAllocationCallbacks *alloc_callbacks = nullptr;
126  BlockAllocator *block_allocator = nullptr;
127 };
128 
130  const VulkanMemoryConfig &cfg, VkDevice dev, VkPhysicalDevice phys_dev,
131  const SystemMemoryAllocatorFns &system_allocator,
132  const VkAllocationCallbacks *alloc_callbacks) {
133 
134  if (system_allocator.allocate == nullptr) {
135  error(user_context) << "VulkanBlockAllocator: Unable to create instance! Missing system allocator interface!\n";
136  return nullptr;
137  }
138 
139  VulkanMemoryAllocator *result = reinterpret_cast<VulkanMemoryAllocator *>(
140  system_allocator.allocate(user_context, sizeof(VulkanMemoryAllocator)));
141 
142  if (result == nullptr) {
143  error(user_context) << "VulkanMemoryAllocator: Failed to create instance! Out of memory!\n";
144  return nullptr; // caller must handle error case for out-of-memory
145  }
146 
147  result->initialize(user_context, cfg, dev, phys_dev, system_allocator, alloc_callbacks);
148  return result;
149 }
150 
151 int VulkanMemoryAllocator::destroy(void *user_context, VulkanMemoryAllocator *instance) {
152  if (instance == nullptr) {
153  error(user_context) << "VulkanBlockAllocator: Unable to destroy instance! Invalide instance pointer!\n";
155  }
156  const BlockAllocator::MemoryAllocators &allocators = instance->block_allocator->current_allocators();
157  instance->destroy(user_context);
158  BlockAllocator::destroy(user_context, instance->block_allocator);
159  if (allocators.system.deallocate == nullptr) {
160  error(user_context) << "VulkanBlockAllocator: Unable to destroy instance! Missing system allocator interface!\n";
162  }
163  allocators.system.deallocate(user_context, instance);
165 }
166 
167 int VulkanMemoryAllocator::initialize(void *user_context,
168  const VulkanMemoryConfig &cfg, VkDevice dev, VkPhysicalDevice phys_dev,
169  const SystemMemoryAllocatorFns &system_allocator,
170  const VkAllocationCallbacks *callbacks) {
171 
172  owner_context = user_context;
173  config = cfg;
174  device = dev;
175  physical_device = phys_dev;
176  alloc_callbacks = callbacks;
177  region_count = 0;
178  region_byte_count = 0;
179  block_count = 0;
180  block_byte_count = 0;
182  allocators.system = system_allocator;
185  BlockAllocator::Config block_allocator_config = {0};
186  block_allocator_config.maximum_pool_size = cfg.maximum_pool_size;
187  block_allocator_config.maximum_block_count = cfg.maximum_block_count;
188  block_allocator_config.maximum_block_size = cfg.maximum_block_size;
189  block_allocator_config.minimum_block_size = cfg.minimum_block_size;
190  block_allocator_config.nearest_multiple = cfg.nearest_multiple;
191  block_allocator = BlockAllocator::create(user_context, block_allocator_config, allocators);
192  if (block_allocator == nullptr) {
193  error(user_context) << "VulkanMemoryAllocator: Failed to create BlockAllocator! Out of memory?!\n";
195  }
196 
197  // get the physical device properties to determine limits and allocation requirements
198  VkPhysicalDeviceProperties physical_device_properties = {0};
199  memset(&physical_device_limits, 0, sizeof(VkPhysicalDeviceLimits));
200  vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
201  memcpy(&physical_device_limits, &(physical_device_properties.limits), sizeof(VkPhysicalDeviceLimits));
203 }
204 
206 #if defined(HL_VK_DEBUG_MEM)
207  debug(nullptr) << "VulkanMemoryAllocator: Reserving memory ("
208  << "user_context=" << user_context << " "
209  << "block_allocator=" << (void *)(block_allocator) << " "
210  << "request_size=" << (uint32_t)(request.size) << " "
211  << "device=" << (void *)(device) << " "
212  << "physical_device=" << (void *)(physical_device) << ") ...\n";
213 #endif
214 
215  if ((device == nullptr) || (physical_device == nullptr)) {
216  error(user_context) << "VulkanMemoryAllocator: Unable to reserve memory! Invalid device handle!\n";
217  return nullptr;
218  }
219 
220  if (block_allocator == nullptr) {
221  error(user_context) << "VulkanMemoryAllocator: Unable to reserve memory! Invalid block allocator!\n";
222  return nullptr;
223  }
224 
225  return block_allocator->reserve(this, request);
226 }
227 
228 void *VulkanMemoryAllocator::map(void *user_context, MemoryRegion *region) {
229 #if defined(HL_VK_DEBUG_MEM)
230  debug(nullptr) << "VulkanMemoryAllocator: Mapping region ("
231  << "user_context=" << user_context << " "
232  << "device=" << (void *)(device) << " "
233  << "physical_device=" << (void *)(physical_device) << " "
234  << "region=" << (void *)(region) << " "
235  << "region_size=" << (uint32_t)region->size << " "
236  << "region_offset=" << (uint32_t)region->offset << " "
237  << "crop_offset=" << (uint32_t)region->range.head_offset << ") ...\n";
238 #endif
239  if ((device == nullptr) || (physical_device == nullptr)) {
240  error(user_context) << "VulkanMemoryAllocator: Unable to map memory! Invalid device handle!\n";
241  return nullptr;
242  }
243 
244  if (block_allocator == nullptr) {
245  error(user_context) << "VulkanMemoryAllocator: Unable to map memory! Invalid block allocator!\n";
246  return nullptr;
247  }
248 
249  MemoryRegion *owner = owner_of(user_context, region);
250  RegionAllocator *region_allocator = RegionAllocator::find_allocator(user_context, owner);
251  if (region_allocator == nullptr) {
252  error(user_context) << "VulkanMemoryAllocator: Unable to map region! Invalid region allocator handle!\n";
253  return nullptr; // NOTE: caller must handle nullptr
254  }
255 
256  BlockResource *block_resource = region_allocator->block_resource();
257  if (block_resource == nullptr) {
258  error(user_context) << "VulkanMemoryAllocator: Unable to map region! Invalid block resource handle!\n";
259  return nullptr; // NOTE: caller must handle nullptr
260  }
261 
262  VkDeviceMemory *device_memory = reinterpret_cast<VkDeviceMemory *>(block_resource->memory.handle);
263  if (device_memory == nullptr) {
264  error(user_context) << "VulkanMemoryAllocator: Unable to map region! Invalid device memory handle!\n";
265  return nullptr; // NOTE: caller must handle nullptr
266  }
267 
268  void *mapped_ptr = nullptr;
269  VkDeviceSize memory_offset = region->offset + region->range.head_offset;
270  VkDeviceSize memory_size = region->size - region->range.tail_offset - region->range.head_offset;
271  if (((double)region->size - (double)region->range.tail_offset - (double)region->range.head_offset) <= 0.0) {
272  error(user_context) << "VulkanMemoryAllocator: Unable to map region! Invalid memory range !\n";
273  return nullptr;
274  }
275  debug(nullptr) << "VulkanMemoryAllocator: MapMemory ("
276  << "user_context=" << user_context << "\n"
277  << " region_size=" << (uint32_t)region->size << "\n"
278  << " region_offset=" << (uint32_t)region->offset << "\n"
279  << " region_range.head_offset=" << (uint32_t)region->range.head_offset << "\n"
280  << " region_range.tail_offset=" << (uint32_t)region->range.tail_offset << "\n"
281  << " memory_offset=" << (uint32_t)memory_offset << "\n"
282  << " memory_size=" << (uint32_t)memory_size << ") ...\n";
283 
284  VkResult result = vkMapMemory(device, *device_memory, memory_offset, memory_size, 0, (void **)(&mapped_ptr));
285  if (result != VK_SUCCESS) {
286  error(user_context) << "VulkanMemoryAllocator: Mapping region failed! vkMapMemory returned error code: " << vk_get_error_name(result) << "\n";
287  return nullptr;
288  }
289 
290  return mapped_ptr;
291 }
292 
293 int VulkanMemoryAllocator::unmap(void *user_context, MemoryRegion *region) {
294 #if defined(HL_VK_DEBUG_MEM)
295  debug(nullptr) << "VulkanMemoryAllocator: Unmapping region ("
296  << "user_context=" << user_context << " "
297  << "device=" << (void *)(device) << " "
298  << "physical_device=" << (void *)(physical_device) << " "
299  << "region=" << (void *)(region) << " "
300  << "region_size=" << (uint32_t)region->size << " "
301  << "region_offset=" << (uint32_t)region->offset << " "
302  << "crop_offset=" << (uint32_t)region->range.head_offset << ") ...\n";
303 #endif
304  if ((device == nullptr) || (physical_device == nullptr)) {
305  error(user_context) << "VulkanMemoryAllocator: Unable to unmap region! Invalid device handle!\n";
307  }
308 
309  MemoryRegion *owner = owner_of(user_context, region);
310  RegionAllocator *region_allocator = RegionAllocator::find_allocator(user_context, owner);
311  if (region_allocator == nullptr) {
312  error(user_context) << "VulkanMemoryAllocator: Unable to unmap region! Invalid region allocator handle!\n";
314  }
315 
316  BlockResource *block_resource = region_allocator->block_resource();
317  if (block_resource == nullptr) {
318  error(user_context) << "VulkanMemoryAllocator: Unable to unmap region! Invalid block resource handle!\n";
320  }
321 
322  VkDeviceMemory *device_memory = reinterpret_cast<VkDeviceMemory *>(block_resource->memory.handle);
323  if (device_memory == nullptr) {
324  error(user_context) << "VulkanMemoryAllocator: Unable to unmap region! Invalid device memory handle!\n";
326  }
327 
328  vkUnmapMemory(device, *device_memory);
330 }
331 
333 #if defined(HL_VK_DEBUG_MEM)
334  debug(nullptr) << "VulkanMemoryAllocator: Cropping region ("
335  << "user_context=" << user_context << " "
336  << "device=" << (void *)(device) << " "
337  << "physical_device=" << (void *)(physical_device) << " "
338  << "region=" << (void *)(region) << " "
339  << "region_size=" << (uint32_t)region->size << " "
340  << "region_offset=" << (uint32_t)region->offset << " "
341  << "crop_offset=" << (int64_t)offset << ") ...\n";
342 #endif
343  if ((device == nullptr) || (physical_device == nullptr)) {
344  error(user_context) << "VulkanMemoryAllocator: Unable to crop region! Invalid device handle!\n";
345  return nullptr;
346  }
347 
348  MemoryRegion *owner = owner_of(user_context, region);
349  RegionAllocator *region_allocator = RegionAllocator::find_allocator(user_context, owner);
350  if (region_allocator == nullptr) {
351  error(user_context) << "VulkanMemoryAllocator: Unable to unmap region! Invalid region allocator handle!\n";
352  return nullptr; // NOTE: caller must handle nullptr
353  }
354 
355  // increment usage count
356  int error_code = region_allocator->retain(this, owner);
357  if (error_code != halide_error_code_success) {
358  error(user_context) << "VulkanMemoryAllocator: Unable to crop region! Failed to retain memory region!\n";
359  return nullptr; // NOTE: caller must handle nullptr
360  }
361 
362  // create a new region to return, and copy all the other region's properties
363  const BlockAllocator::MemoryAllocators &allocators = block_allocator->current_allocators();
364  if (allocators.system.allocate == nullptr) {
365  error(user_context) << "VulkanMemoryAllocator: Unable to create crop! Missing system allocator interface!\n";
366  return nullptr;
367  }
368 
369  MemoryRegion *memory_region = reinterpret_cast<MemoryRegion *>(
370  allocators.system.allocate(user_context, sizeof(MemoryRegion)));
371 
372  if (memory_region == nullptr) {
373  error(user_context) << "VulkanMemoryAllocator: Failed to allocate memory region! Out of memory!\n";
374  return nullptr;
375  }
376  memcpy(memory_region, owner, sizeof(MemoryRegion));
377 
378  // point the handle to the owner of the allocated region, and update the head offset
379  memory_region->is_owner = false;
380  memory_region->handle = (void *)owner;
381  memory_region->range.head_offset = owner->range.head_offset + offset;
382  return memory_region;
383 }
384 
385 int VulkanMemoryAllocator::destroy_crop(void *user_context, MemoryRegion *region) {
386  if (region == nullptr) {
387  error(user_context) << "VulkanMemoryAllocator: Failed to destroy crop! Invalid memory region!\n";
389  }
390 
391  MemoryRegion *owner = owner_of(user_context, region);
392  RegionAllocator *region_allocator = RegionAllocator::find_allocator(user_context, owner);
393  if (region_allocator == nullptr) {
394  error(user_context) << "VulkanMemoryAllocator: Unable to destroy crop region! Invalid region allocator handle!\n";
396  }
397 
398  // decrement usage count
399  int error_code = region_allocator->release(this, owner);
400  if (error_code != halide_error_code_success) {
401  error(user_context) << "VulkanBlockAllocator: Unable to destroy crop region! Region allocator failed to release memory region!\n";
402  return error_code;
403  }
404 
405  // discard the copied region struct
406  const BlockAllocator::MemoryAllocators &allocators = block_allocator->current_allocators();
407  if (allocators.system.deallocate == nullptr) {
408  error(user_context) << "VulkanBlockAllocator: Unable to destroy crop region! Missing system allocator interface!\n";
410  }
411  allocators.system.deallocate(user_context, region);
413 }
414 
416  if (region->is_owner) {
417  return region;
418  } else {
419  // If this is a cropped region, use the handle to retrieve the owner of the allocation
420  return reinterpret_cast<MemoryRegion *>(region->handle);
421  }
422 }
423 
424 int VulkanMemoryAllocator::release(void *user_context, MemoryRegion *region) {
425 #if defined(HL_VK_DEBUG_MEM)
426  debug(nullptr) << "VulkanMemoryAllocator: Releasing region ("
427  << "user_context=" << user_context << " "
428  << "region=" << (void *)(region) << " "
429  << "size=" << (uint32_t)region->size << " "
430  << "offset=" << (uint32_t)region->offset << ") ...\n";
431 #endif
432  if ((device == nullptr) || (physical_device == nullptr)) {
433  error(user_context) << "VulkanMemoryAllocator: Unable to release region! Invalid device handle!\n";
435  }
436  if (block_allocator == nullptr) {
437  error(user_context) << "VulkanMemoryAllocator: Unable to release region! Invalid block allocator!\n";
439  }
440  return block_allocator->release(this, region);
441 }
442 
443 int VulkanMemoryAllocator::reclaim(void *user_context, MemoryRegion *region) {
444 #if defined(HL_VK_DEBUG_MEM)
445  debug(nullptr) << "VulkanMemoryAllocator: Reclaiming region ("
446  << "user_context=" << user_context << " "
447  << "region=" << (void *)(region) << " "
448  << "size=" << (uint32_t)region->size << " "
449  << "offset=" << (uint32_t)region->offset << ") ...\n";
450 #endif
451  if ((device == nullptr) || (physical_device == nullptr)) {
452  error(user_context) << "VulkanMemoryAllocator: Unable to reclaim region! Invalid device handle!\n";
454  }
455  if (block_allocator == nullptr) {
456  error(user_context) << "VulkanMemoryAllocator: Unable to reclaim region! Invalid block allocator!\n";
458  }
459  return block_allocator->reclaim(this, region);
460 }
461 
462 int VulkanMemoryAllocator::retain(void *user_context, MemoryRegion *region) {
463 #if defined(HL_VK_DEBUG_MEM)
464  debug(nullptr) << "VulkanMemoryAllocator: Retaining region ("
465  << "user_context=" << user_context << " "
466  << "region=" << (void *)(region) << " "
467  << "size=" << (uint32_t)region->size << " "
468  << "offset=" << (uint32_t)region->offset << ") ...\n";
469 #endif
470  if ((device == nullptr) || (physical_device == nullptr)) {
471  error(user_context) << "VulkanMemoryAllocator: Unable to retain region! Invalid device handle!\n";
473  }
474  if (block_allocator == nullptr) {
475  error(user_context) << "VulkanMemoryAllocator: Unable to retain region! Invalid block allocator!\n";
477  }
478  return block_allocator->retain(this, region);
479 }
480 
481 bool VulkanMemoryAllocator::collect(void *user_context) {
482 #if defined(HL_VK_DEBUG_MEM)
483  debug(nullptr) << "VulkanMemoryAllocator: Collecting unused memory ("
484  << "user_context=" << user_context << ") ... \n";
485 #endif
486  if ((device == nullptr) || (physical_device == nullptr) || (block_allocator == nullptr)) {
487  return false;
488  }
489  return block_allocator->collect(this);
490 }
491 
492 int VulkanMemoryAllocator::release(void *user_context) {
493 #if defined(HL_VK_DEBUG_MEM)
494  debug(nullptr) << "VulkanMemoryAllocator: Releasing block allocator ("
495  << "user_context=" << user_context << ") ... \n";
496 #endif
497  if ((device == nullptr) || (physical_device == nullptr)) {
498  error(user_context) << "VulkanMemoryAllocator: Unable to release allocator! Invalid device handle!\n";
500  }
501  if (block_allocator == nullptr) {
502  error(user_context) << "VulkanMemoryAllocator: Unable to release allocator! Invalid block allocator!\n";
504  }
505 
506  return block_allocator->release(this);
507 }
508 
509 int VulkanMemoryAllocator::destroy(void *user_context) {
510 #if defined(HL_VK_DEBUG_MEM)
511  debug(nullptr) << "VulkanMemoryAllocator: Destroying allocator ("
512  << "user_context=" << user_context << ") ... \n";
513 #endif
514  if (block_allocator != nullptr) {
515  block_allocator->destroy(this);
516  }
517  region_count = 0;
518  region_byte_count = 0;
519  block_count = 0;
520  block_byte_count = 0;
522 }
523 
524 const VulkanMemoryConfig &
526  static VulkanMemoryConfig result;
527  return result;
528 }
529 
530 // --
531 
532 int VulkanMemoryAllocator::allocate_block(void *instance_ptr, MemoryBlock *block) {
533  VulkanMemoryAllocator *instance = reinterpret_cast<VulkanMemoryAllocator *>(instance_ptr);
534  if (instance == nullptr) {
536  }
537 
538  void *user_context = instance->owner_context;
539  if ((instance->device == nullptr) || (instance->physical_device == nullptr)) {
540  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid device handle!\n";
542  }
543 
544  if (block == nullptr) {
545  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid pointer!\n";
547  }
548 
549 #if defined(HL_VK_DEBUG_MEM)
550  debug(nullptr) << "VulkanMemoryAllocator: Allocating block ("
551  << "user_context=" << user_context << " "
552  << "block=" << (void *)(block) << " "
553  << "size=" << (uint64_t)block->size << ", "
554  << "dedicated=" << (block->dedicated ? "true" : "false") << " "
555  << "usage=" << halide_memory_usage_name(block->properties.usage) << " "
556  << "caching=" << halide_memory_caching_name(block->properties.caching) << " "
557  << "visibility=" << halide_memory_visibility_name(block->properties.visibility) << ")\n";
558 #endif
559 
560  // Find an appropriate memory type given the flags
561  uint32_t memory_type = instance->select_memory_type(user_context, instance->physical_device, block->properties, 0);
562  if (memory_type == invalid_memory_type) {
563  error(user_context) << "VulkanMemoryAllocator: Unable to find appropriate memory type for device!\n";
565  }
566 
567  // Allocate memory
568  VkMemoryAllocateInfo alloc_info = {
570  nullptr, // struct extending this
571  block->size, // size of allocation in bytes
572  memory_type // memory type index from physical device
573  };
574 
575  VkDeviceMemory *device_memory = (VkDeviceMemory *)vk_host_malloc(nullptr, sizeof(VkDeviceMemory), 0, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, instance->alloc_callbacks);
576  if (device_memory == nullptr) {
577  debug(nullptr) << "VulkanBlockAllocator: Unable to allocate block! Failed to allocate device memory handle!\n";
579  }
580 
581  VkResult result = vkAllocateMemory(instance->device, &alloc_info, instance->alloc_callbacks, device_memory);
582  if (result != VK_SUCCESS) {
583  debug(nullptr) << "VulkanMemoryAllocator: Allocation failed! vkAllocateMemory returned: " << vk_get_error_name(result) << "\n";
585  }
586 #ifdef DEBUG_RUNTIME
587  debug(nullptr) << "vkAllocateMemory: Allocated memory for device region (" << (uint64_t)block->size << " bytes) ...\n";
588 #endif
589 
590  uint32_t usage_flags = instance->select_memory_usage(user_context, block->properties);
591 
592  VkBufferCreateInfo create_info = {
594  nullptr, // struct extending this
595  0, // create flags
596  sizeof(uint32_t), // buffer size (in bytes)
597  usage_flags, // buffer usage flags
598  VK_SHARING_MODE_EXCLUSIVE, // sharing mode
599  0, nullptr};
600 
601  // Create a buffer to determine alignment requirements
602  VkBuffer buffer = {0};
603  result = vkCreateBuffer(instance->device, &create_info, instance->alloc_callbacks, &buffer);
604  if (result != VK_SUCCESS) {
605  debug(nullptr) << "VulkanMemoryAllocator: Failed to create buffer!\n\t"
606  << "vkCreateBuffer returned: " << vk_get_error_name(result) << "\n";
608  }
609 
610  VkMemoryRequirements memory_requirements = {0};
611  vkGetBufferMemoryRequirements(instance->device, buffer, &memory_requirements);
612  vkDestroyBuffer(instance->device, buffer, instance->alloc_callbacks);
613 
614 #if defined(HL_VK_DEBUG_MEM)
615  debug(nullptr) << "VulkanMemoryAllocator: Block allocated ("
616  << "size=" << (uint32_t)block->size << ", "
617  << "alignment=" << (uint32_t)memory_requirements.alignment << ", "
618  << "uniform_buffer_offset_alignment=" << (uint32_t)instance->physical_device_limits.minUniformBufferOffsetAlignment << ", "
619  << "storage_buffer_offset_alignment=" << (uint32_t)instance->physical_device_limits.minStorageBufferOffsetAlignment << ", "
620  << "dedicated=" << (block->dedicated ? "true" : "false") << ")\n";
621 #endif
622 
623  // Enforce any alignment constrainst reported by the device limits for each usage type
624  if (usage_flags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) {
625  block->properties.alignment = instance->physical_device_limits.minStorageBufferOffsetAlignment;
626  } else if (usage_flags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) {
627  block->properties.alignment = instance->physical_device_limits.minUniformBufferOffsetAlignment;
628  }
629  // Some drivers appear to report a buffer alignment constraint (regardless of usage) that can be larger than either of the above
630  if (memory_requirements.alignment > block->properties.alignment) {
631  block->properties.alignment = memory_requirements.alignment;
632  }
633  block->handle = (void *)device_memory;
634  instance->block_byte_count += block->size;
635  instance->block_count++;
637 }
638 
639 int VulkanMemoryAllocator::deallocate_block(void *instance_ptr, MemoryBlock *block) {
640  VulkanMemoryAllocator *instance = reinterpret_cast<VulkanMemoryAllocator *>(instance_ptr);
641  if (instance == nullptr) {
643  }
644 
645  void *user_context = instance->owner_context;
646 #if defined(HL_VK_DEBUG_MEM)
647  debug(nullptr) << "VulkanMemoryAllocator: Deallocating block ("
648  << "user_context=" << user_context << " "
649  << "block=" << (void *)(block) << ") ... \n";
650 #endif
651 
652  if ((instance->device == nullptr) || (instance->physical_device == nullptr)) {
653  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid device handle!\n";
655  }
656 
657  if (block == nullptr) {
658  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid pointer!\n";
660  }
661 
662 #if defined(HL_VK_DEBUG_MEM)
663  debug(nullptr) << "VulkanBlockAllocator: deallocating block ("
664  << "size=" << (uint32_t)block->size << ", "
665  << "dedicated=" << (block->dedicated ? "true" : "false") << " "
666  << "usage=" << halide_memory_usage_name(block->properties.usage) << " "
667  << "caching=" << halide_memory_caching_name(block->properties.caching) << " "
668  << "visibility=" << halide_memory_visibility_name(block->properties.visibility) << ")\n";
669 #endif
670 
671  if (block->handle == nullptr) {
672  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid handle!\n";
674  }
675 
676  VkDeviceMemory *device_memory = reinterpret_cast<VkDeviceMemory *>(block->handle);
677  if (device_memory == nullptr) {
678  error(user_context) << "VulkanBlockAllocator: Unable to deallocate block! Invalid device memory handle!\n";
680  }
681 
682  vkFreeMemory(instance->device, *device_memory, instance->alloc_callbacks);
683 #ifdef DEBUG_RUNTIME
684  debug(nullptr) << "vkFreeMemory: Deallocated memory for device region (" << (uint64_t)block->size << " bytes) ...\n";
685 #endif
686 
687  if (instance->block_count > 0) {
688  instance->block_count--;
689  } else {
690  error(nullptr) << "VulkanRegionAllocator: Block counter invalid ... reseting to zero!\n";
691  instance->block_count = 0;
692  }
693 
694  if (int64_t(instance->block_byte_count) - int64_t(block->size) >= 0) {
695  instance->block_byte_count -= block->size;
696  } else {
697  error(nullptr) << "VulkanRegionAllocator: Block byte counter invalid ... reseting to zero!\n";
698  instance->block_byte_count = 0;
699  }
700 
701  block->handle = nullptr;
702  vk_host_free(nullptr, device_memory, instance->alloc_callbacks);
703  device_memory = nullptr;
705 }
706 
708  return block_count;
709 }
710 
712  return block_byte_count;
713 }
714 
715 uint32_t VulkanMemoryAllocator::select_memory_type(void *user_context,
716  VkPhysicalDevice physical_device,
717  MemoryProperties properties,
718  uint32_t required_flags) const {
719 
720  uint32_t want_flags = 0; //< preferred memory flags for requested access type
721  uint32_t need_flags = 0; //< must have in order to enable requested access
722  switch (properties.visibility) {
725  break;
728  break;
732  break;
735  break;
738  default:
739  error(nullptr) << "VulkanMemoryAllocator: Unable to convert type! Invalid memory visibility request!\n\t"
740  << "visibility=" << halide_memory_visibility_name(properties.visibility) << "\n";
741  return invalid_memory_type;
742  };
743 
744  switch (properties.caching) {
746  if (need_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
748  }
749  break;
751  if (need_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
753  }
754  break;
756  if (need_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
758  }
759  break;
762  break;
764  default:
765  error(user_context) << "VulkanMemoryAllocator: Unable to convert type! Invalid memory caching request!\n\t"
766  << "caching=" << halide_memory_caching_name(properties.caching) << "\n";
767  return invalid_memory_type;
768  };
769 
770  VkPhysicalDeviceMemoryProperties device_memory_properties;
771  vkGetPhysicalDeviceMemoryProperties(physical_device, &device_memory_properties);
772 
773  uint32_t result = invalid_memory_type;
774  for (uint32_t i = 0; i < device_memory_properties.memoryTypeCount; ++i) {
775 
776  // if required flags are given, see if the memory type matches the requirement
777  if (required_flags) {
778  if (((required_flags >> i) & 1) == 0) {
779  continue;
780  }
781  }
782 
783  const VkMemoryPropertyFlags properties = device_memory_properties.memoryTypes[i].propertyFlags;
784  if (need_flags) {
785  if ((properties & need_flags) != need_flags) {
786  continue;
787  }
788  }
789 
790  if (want_flags) {
791  if ((properties & want_flags) != want_flags) {
792  continue;
793  }
794  }
795 
796  result = i;
797  break;
798  }
799 
800  if (result == invalid_memory_type) {
801  error(user_context) << "VulkanBlockAllocator: Failed to find appropriate memory type for given properties:\n\t"
802  << "usage=" << halide_memory_usage_name(properties.usage) << " "
803  << "caching=" << halide_memory_caching_name(properties.caching) << " "
804  << "visibility=" << halide_memory_visibility_name(properties.visibility) << "\n";
805  return invalid_memory_type;
806  }
807 
808  return result;
809 }
810 
811 // --
812 
813 int VulkanMemoryAllocator::allocate_region(void *instance_ptr, MemoryRegion *region) {
814 
815  VulkanMemoryAllocator *instance = reinterpret_cast<VulkanMemoryAllocator *>(instance_ptr);
816  if (instance == nullptr) {
818  }
819 
820  void *user_context = instance->owner_context;
821 #if defined(HL_VK_DEBUG_MEM)
822  debug(nullptr) << "VulkanMemoryAllocator: Allocating region ("
823  << "user_context=" << user_context << " "
824  << "region=" << (void *)(region) << ") ... \n";
825 #endif
826 
827  if ((instance->device == nullptr) || (instance->physical_device == nullptr)) {
828  error(user_context) << "VulkanRegionAllocator: Unable to allocate region! Invalid device handle!\n";
830  }
831 
832  if (region == nullptr) {
833  error(user_context) << "VulkanRegionAllocator: Unable to allocate region! Invalid pointer!\n";
835  }
836 
837 #if defined(HL_VK_DEBUG_MEM)
838  debug(nullptr) << "VulkanRegionAllocator: Allocating region ("
839  << "size=" << (uint32_t)region->size << ", "
840  << "offset=" << (uint32_t)region->offset << ", "
841  << "dedicated=" << (region->dedicated ? "true" : "false") << " "
842  << "usage=" << halide_memory_usage_name(region->properties.usage) << " "
843  << "caching=" << halide_memory_caching_name(region->properties.caching) << " "
844  << "visibility=" << halide_memory_visibility_name(region->properties.visibility) << ")\n";
845 #endif
846 
847  uint32_t usage_flags = instance->select_memory_usage(user_context, region->properties);
848 
849  VkBufferCreateInfo create_info = {
851  nullptr, // struct extending this
852  0, // create flags
853  region->size, // buffer size (in bytes)
854  usage_flags, // buffer usage flags
855  VK_SHARING_MODE_EXCLUSIVE, // sharing mode
856  0, nullptr};
857 
858  VkBuffer *buffer = (VkBuffer *)vk_host_malloc(nullptr, sizeof(VkBuffer), 0, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, instance->alloc_callbacks);
859  if (buffer == nullptr) {
860  error(user_context) << "VulkanRegionAllocator: Unable to allocate region! Failed to allocate buffer handle!\n";
862  }
863 
864  VkResult result = vkCreateBuffer(instance->device, &create_info, instance->alloc_callbacks, buffer);
865  if (result != VK_SUCCESS) {
866  error(user_context) << "VulkanRegionAllocator: Failed to create buffer!\n\t"
867  << "vkCreateBuffer returned: " << vk_get_error_name(result) << "\n";
869  }
870 #ifdef DEBUG_RUNTIME
871  debug(nullptr) << "vkCreateBuffer: Created buffer for device region (" << (uint64_t)region->size << " bytes) ...\n";
872 #endif
873 
874  RegionAllocator *region_allocator = RegionAllocator::find_allocator(user_context, region);
875  if (region_allocator == nullptr) {
876  error(user_context) << "VulkanBlockAllocator: Unable to allocate region! Invalid region allocator!\n";
878  }
879 
880  BlockResource *block_resource = region_allocator->block_resource();
881  if (block_resource == nullptr) {
882  error(user_context) << "VulkanBlockAllocator: Unable to allocate region! Invalid block resource handle!\n";
884  }
885 
886  VkDeviceMemory *device_memory = reinterpret_cast<VkDeviceMemory *>(block_resource->memory.handle);
887  if (device_memory == nullptr) {
888  error(user_context) << "VulkanBlockAllocator: Unable to allocate region! Invalid device memory handle!\n";
890  }
891 
892  // Finally, bind buffer to the device memory
893  result = vkBindBufferMemory(instance->device, *buffer, *device_memory, region->offset);
894  if (result != VK_SUCCESS) {
895  error(user_context) << "VulkanRegionAllocator: Failed to bind buffer!\n\t"
896  << "vkBindBufferMemory returned: " << vk_get_error_name(result) << "\n";
898  }
899 
900  region->handle = (void *)buffer;
901  region->is_owner = true;
902  instance->region_byte_count += region->size;
903  instance->region_count++;
905 }
906 
907 int VulkanMemoryAllocator::deallocate_region(void *instance_ptr, MemoryRegion *region) {
908  VulkanMemoryAllocator *instance = reinterpret_cast<VulkanMemoryAllocator *>(instance_ptr);
909  if (instance == nullptr) {
911  }
912 
913  void *user_context = instance->owner_context;
914 #if defined(HL_VK_DEBUG_MEM)
915  debug(nullptr) << "VulkanMemoryAllocator: Deallocating region ("
916  << "user_context=" << user_context << " "
917  << "region=" << (void *)(region) << ") ... \n";
918 #endif
919 
920  if ((instance->device == nullptr) || (instance->physical_device == nullptr)) {
921  error(user_context) << "VulkanRegionAllocator: Unable to deallocate region! Invalid device handle!\n";
923  }
924 
925  if (region == nullptr) {
926  error(user_context) << "VulkanRegionAllocator: Unable to deallocate region! Invalid pointer!\n";
928  }
929 
930 #if defined(HL_VK_DEBUG_MEM)
931  debug(nullptr) << "VulkanRegionAllocator: Deallocating region ("
932  << "size=" << (uint32_t)region->size << ", "
933  << "offset=" << (uint32_t)region->offset << ", "
934  << "dedicated=" << (region->dedicated ? "true" : "false") << " "
935  << "usage=" << halide_memory_usage_name(region->properties.usage) << " "
936  << "caching=" << halide_memory_caching_name(region->properties.caching) << " "
937  << "visibility=" << halide_memory_visibility_name(region->properties.visibility) << ")\n";
938 #endif
939 
940  if (region->handle == nullptr) {
941  error(user_context) << "VulkanRegionAllocator: Unable to deallocate region! Invalid handle!\n";
943  }
944 
945  VkBuffer *buffer = reinterpret_cast<VkBuffer *>(region->handle);
946  if (buffer == nullptr) {
947  error(user_context) << "VulkanRegionAllocator: Unable to deallocate region! Invalid buffer handle!\n";
949  }
950 
951  vkDestroyBuffer(instance->device, *buffer, instance->alloc_callbacks);
952 #ifdef DEBUG_RUNTIME
953  debug(nullptr) << "vkDestroyBuffer: Destroyed buffer for device region (" << (uint64_t)region->size << " bytes) ...\n";
954 #endif
955  region->handle = nullptr;
956  if (instance->region_count > 0) {
957  instance->region_count--;
958  } else {
959  error(nullptr) << "VulkanRegionAllocator: Region counter invalid ... reseting to zero!\n";
960  instance->region_count = 0;
962  }
963 
964  if (int64_t(instance->region_byte_count) - int64_t(region->size) >= 0) {
965  instance->region_byte_count -= region->size;
966  } else {
967  error(nullptr) << "VulkanRegionAllocator: Region byte counter invalid ... reseting to zero!\n";
968  instance->region_byte_count = 0;
970  }
971  vk_host_free(nullptr, buffer, instance->alloc_callbacks);
972  buffer = nullptr;
974 }
975 
977  return region_count;
978 }
979 
981  return region_byte_count;
982 }
983 
984 uint32_t VulkanMemoryAllocator::select_memory_usage(void *user_context, MemoryProperties properties) const {
985  uint32_t result = 0;
986  switch (properties.usage) {
989  break;
993  break;
996  break;
999  break;
1002  break;
1005  default:
1006  error(user_context) << "VulkanRegionAllocator: Unable to convert type! Invalid memory usage request!\n\t"
1007  << "usage=" << halide_memory_usage_name(properties.usage) << "\n";
1008  return invalid_usage_flags;
1009  };
1010 
1011  if (result == invalid_usage_flags) {
1012  error(user_context) << "VulkanRegionAllocator: Failed to find appropriate memory usage for given properties:\n\t"
1013  << "usage=" << halide_memory_usage_name(properties.usage) << " "
1014  << "caching=" << halide_memory_caching_name(properties.caching) << " "
1015  << "visibility=" << halide_memory_visibility_name(properties.visibility) << "\n";
1016  return invalid_usage_flags;
1017  }
1018 
1019  return result;
1020 }
1021 
1022 // --------------------------------------------------------------------------
1023 
1024 namespace {
1025 
1026 // --------------------------------------------------------------------------
1027 // Halide System allocator for host allocations
1028 void *vk_system_malloc(void *user_context, size_t size) {
1029  return malloc(size);
1030 }
1031 
1032 void vk_system_free(void *user_context, void *ptr) {
1033  free(ptr);
1034 }
1035 
1036 // Vulkan host-side allocation
1037 void *vk_host_malloc(void *user_context, size_t size, size_t alignment, VkSystemAllocationScope scope, const VkAllocationCallbacks *callbacks) {
1038  if (callbacks) {
1039  return callbacks->pfnAllocation(user_context, size, alignment, scope);
1040  } else {
1041  return vk_system_malloc(user_context, size);
1042  }
1043 }
1044 
1045 void vk_host_free(void *user_context, void *ptr, const VkAllocationCallbacks *callbacks) {
1046  if (callbacks) {
1047  return callbacks->pfnFree(user_context, ptr);
1048  } else {
1049  return vk_system_free(user_context, ptr);
1050  }
1051 }
1052 
1053 VulkanMemoryAllocator *vk_create_memory_allocator(void *user_context,
1054  VkDevice device,
1055  VkPhysicalDevice physical_device,
1056  const VkAllocationCallbacks *alloc_callbacks) {
1057 
1058  SystemMemoryAllocatorFns system_allocator = {vk_system_malloc, vk_system_free};
1059  VulkanMemoryConfig config = memory_allocator_config;
1060 
1061  // Parse the allocation config string (if specified).
1062  //
1063  // `HL_VK_ALLOC_CONFIG=N:N:N` will tell Halide to configure the Vulkan memory
1064  // allocator use the given constraints specified as three integer values
1065  // separated by a `:` or `;`. These values correspond to `minimum_block_size`,
1066  // `maximum_block_size` and `maximum_block_count`.
1067  //
1068  const char *alloc_config = vk_get_alloc_config_internal(user_context);
1070  StringTable alloc_config_values;
1071  alloc_config_values.parse(user_context, alloc_config, HL_VK_ENV_DELIM);
1072  if (alloc_config_values.size() > 0) {
1073  config.maximum_pool_size = atoi(alloc_config_values[0]) * 1024 * 1024;
1074  print(user_context) << "Vulkan: Configuring allocator with " << (uint32_t)config.maximum_pool_size << " for maximum pool size (in bytes)\n";
1075  }
1076  if (alloc_config_values.size() > 1) {
1077  config.minimum_block_size = atoi(alloc_config_values[1]) * 1024 * 1024;
1078  print(user_context) << "Vulkan: Configuring allocator with " << (uint32_t)config.minimum_block_size << " for minimum block size (in bytes)\n";
1079  }
1080  if (alloc_config_values.size() > 2) {
1081  config.maximum_block_size = atoi(alloc_config_values[2]) * 1024 * 1024;
1082  print(user_context) << "Vulkan: Configuring allocator with " << (uint32_t)config.maximum_block_size << " for maximum block size (in bytes)\n";
1083  }
1084  if (alloc_config_values.size() > 3) {
1085  config.maximum_block_count = atoi(alloc_config_values[3]);
1086  print(user_context) << "Vulkan: Configuring allocator with " << (uint32_t)config.maximum_block_count << " for maximum block count\n";
1087  }
1088  if (alloc_config_values.size() > 4) {
1089  config.nearest_multiple = atoi(alloc_config_values[4]);
1090  print(user_context) << "Vulkan: Configuring allocator with " << (uint32_t)config.nearest_multiple << " for nearest multiple\n";
1091  }
1092  }
1093 
1094  return VulkanMemoryAllocator::create(user_context,
1095  config, device, physical_device,
1096  system_allocator, alloc_callbacks);
1097 }
1098 
1099 int vk_destroy_memory_allocator(void *user_context, VulkanMemoryAllocator *allocator) {
1100  if (allocator != nullptr) {
1101  VulkanMemoryAllocator::destroy(user_context, allocator);
1102  allocator = nullptr;
1103  }
1105 }
1106 
1107 // --------------------------------------------------------------------------
1108 
1109 int vk_clear_device_buffer(void *user_context,
1110  VulkanMemoryAllocator *allocator,
1111  VkCommandPool command_pool,
1112  VkQueue command_queue,
1113  VkBuffer device_buffer) {
1114 
1115 #ifdef DEBUG_RUNTIME
1116  debug(user_context)
1117  << " vk_clear_device_buffer (user_context: " << user_context << ", "
1118  << "allocator: " << (void *)allocator << ", "
1119  << "command_pool: " << (void *)command_pool << ", "
1120  << "command_queue: " << (void *)command_queue << ", "
1121  << "device_buffer: " << (void *)device_buffer << ")\n";
1122 #endif
1123 
1124  // create a command buffer
1125  VkCommandBuffer command_buffer;
1126  int error_code = vk_create_command_buffer(user_context, allocator, command_pool, &command_buffer);
1127  if (error_code != halide_error_code_success) {
1128  error(user_context) << "Vulkan: Failed to create command buffer!\n";
1129  return error_code;
1130  }
1131 
1132  // begin the command buffer
1133  VkCommandBufferBeginInfo command_buffer_begin_info =
1134  {
1136  nullptr, // pointer to struct extending this
1138  nullptr // pointer to parent command buffer
1139  };
1140 
1141  VkResult result = vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info);
1142  if (result != VK_SUCCESS) {
1143  error(user_context) << "Vulkan: vkBeginCommandBuffer returned " << vk_get_error_name(result) << "\n";
1145  }
1146 
1147  // fill buffer with zero values up to the size of the buffer
1148  vkCmdFillBuffer(command_buffer, device_buffer, 0, VK_WHOLE_SIZE, 0);
1149 
1150  // end the command buffer
1151  result = vkEndCommandBuffer(command_buffer);
1152  if (result != VK_SUCCESS) {
1153  error(user_context) << "Vulkan: vkEndCommandBuffer returned " << vk_get_error_name(result) << "\n";
1155  }
1156 
1157  // submit the command buffer
1158  VkSubmitInfo submit_info =
1159  {
1160  VK_STRUCTURE_TYPE_SUBMIT_INFO, // struct type
1161  nullptr, // pointer to struct extending this
1162  0, // wait semaphore count
1163  nullptr, // semaphores
1164  nullptr, // pipeline stages where semaphore waits occur
1165  1, // how many command buffers to execute
1166  &command_buffer, // the command buffers
1167  0, // number of semaphores to signal
1168  nullptr // the semaphores to signal
1169  };
1170 
1171  result = vkQueueSubmit(command_queue, 1, &submit_info, 0);
1172  if (result != VK_SUCCESS) {
1173  error(user_context) << "Vulkan: vkQueueSubmit returned " << vk_get_error_name(result) << "\n";
1175  }
1176 
1177  // wait for memset to finish
1178  result = vkQueueWaitIdle(command_queue);
1179  if (result != VK_SUCCESS) {
1180  error(user_context) << "Vulkan: vkQueueWaitIdle returned " << vk_get_error_name(result) << "\n";
1182  }
1183 
1184  error_code = vk_destroy_command_buffer(user_context, allocator, command_pool, command_buffer);
1185  if (error_code != halide_error_code_success) {
1186  error(user_context) << "Vulkan: Failed to destroy command buffer!\n";
1187  return error_code;
1188  }
1189 
1191 }
1192 
1193 // --------------------------------------------------------------------------
1194 
1195 } // namespace
1196 } // namespace Vulkan
1197 } // namespace Internal
1198 } // namespace Runtime
1199 } // namespace Halide
1200 
1201 // --------------------------------------------------------------------------
1202 
1203 extern "C" {
1204 
1205 // --------------------------------------------------------------------------
1206 
1208  using namespace Halide::Runtime::Internal::Vulkan;
1210  custom_allocation_callbacks = callbacks;
1211 }
1212 
1214  using namespace Halide::Runtime::Internal::Vulkan;
1217 }
1218 
1219 // --------------------------------------------------------------------------
1220 
1221 } // extern "C"
1222 
1223 #endif // HALIDE_RUNTIME_VULKAN_MEMORY_H
Halide::Runtime::Internal::BlockAllocator::MemoryAllocators::block
MemoryBlockAllocatorFns block
Definition: block_allocator.h:38
vkBeginCommandBuffer
VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo)
Halide::Runtime::Internal::BlockAllocator::Config::nearest_multiple
size_t nearest_multiple
Definition: block_allocator.h:49
Halide::Runtime::Internal::MemoryRegion::range
MemoryRange range
Definition: memory_resources.h:83
Halide::Runtime::Internal::MemoryRegion::handle
void * handle
Definition: memory_resources.h:80
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::regions_allocated
size_t regions_allocated() const
Definition: vulkan_memory.h:976
block_allocator.h
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::default_config
static const VulkanMemoryConfig & default_config()
Definition: vulkan_memory.h:525
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig
Definition: vulkan_memory.h:25
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig::minimum_block_size
size_t minimum_block_size
Definition: vulkan_memory.h:27
VkBufferCreateInfo
Definition: mini_vulkan.h:1860
vkQueueWaitIdle
VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue)
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::create_crop
MemoryRegion * create_crop(void *user_context, MemoryRegion *region, uint64_t offset)
Definition: vulkan_memory.h:332
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::reclaim
int reclaim(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:443
Halide::Runtime::Internal::MemoryRegion::dedicated
bool dedicated
Definition: memory_resources.h:84
halide_error_code_internal_error
@ halide_error_code_internal_error
There is a bug in the Halide compiler.
Definition: HalideRuntime.h:1127
Halide::Runtime::Internal::RegionAllocator::release
int release(void *user_context, MemoryRegion *memory_region)
Definition: region_allocator.h:184
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator
Vulkan Memory Allocator class interface for managing large memory requests stored as contiguous block...
Definition: vulkan_memory.h:42
vkEndCommandBuffer
VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer)
Halide::Runtime::Internal::BlockAllocator::reclaim
int reclaim(void *user_context, MemoryRegion *region)
Definition: block_allocator.h:208
Halide::Runtime::Internal::MemoryUsage::StaticStorage
@ StaticStorage
Halide::Runtime::Internal::Vulkan::alloc_config
WEAK char alloc_config[1024]
Definition: vulkan_extensions.h:31
halide_error_code_success
@ halide_error_code_success
There was no error.
Definition: HalideRuntime.h:1039
VkPhysicalDeviceMemoryProperties
Definition: mini_vulkan.h:1682
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
@ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
Definition: mini_vulkan.h:1372
Halide::Runtime::Internal::BlockAllocator::create
static BlockAllocator * create(void *user_context, const Config &config, const MemoryAllocators &allocators)
Definition: block_allocator.h:123
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::owner_of
MemoryRegion * owner_of(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:415
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::allocate_region
static int allocate_region(void *instance_ptr, MemoryRegion *region)
Definition: vulkan_memory.h:813
vkQueueSubmit
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence)
Halide::Runtime::Internal::BlockAllocator::Config
Definition: block_allocator.h:43
Halide::Runtime::Internal::BlockAllocator::Config::minimum_block_size
size_t minimum_block_size
Definition: block_allocator.h:46
vkDestroyBuffer
VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator)
Halide::Runtime::Internal::MemoryVisibility::InvalidVisibility
@ InvalidVisibility
VK_SHARING_MODE_EXCLUSIVE
@ VK_SHARING_MODE_EXCLUSIVE
Definition: mini_vulkan.h:627
VkPhysicalDeviceMemoryProperties::memoryTypes
VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]
Definition: mini_vulkan.h:1684
Halide::Runtime::Internal::BlockAllocator::MemoryAllocators::region
MemoryRegionAllocatorFns region
Definition: block_allocator.h:39
Halide::Runtime::Internal::ScopedSpinLock::AtomicFlag
char AtomicFlag
Definition: scoped_spin_lock.h:11
Halide::Runtime::Internal::MemoryRequest::size
size_t size
Definition: memory_resources.h:92
Halide::Runtime::Internal::MemoryVisibility::DefaultVisibility
@ DefaultVisibility
Halide::Runtime::Internal::MemoryUsage::DynamicStorage
@ DynamicStorage
Halide::Runtime::Internal::MemoryRegion
Definition: memory_resources.h:79
halide_memory_caching_name
const WEAK char * halide_memory_caching_name(MemoryCaching value)
Definition: memory_resources.h:289
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::unmap
int unmap(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:293
halide_vulkan_get_allocation_callbacks
const WEAK VkAllocationCallbacks * halide_vulkan_get_allocation_callbacks(void *user_context)
Definition: vulkan_memory.h:1213
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::bytes_allocated_for_blocks
size_t bytes_allocated_for_blocks() const
Definition: vulkan_memory.h:711
Halide::Runtime::Internal::MemoryCaching::InvalidCaching
@ InvalidCaching
vkMapMemory
VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData)
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
@ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
Definition: mini_vulkan.h:1232
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::current_device
VkDevice current_device() const
Definition: vulkan_memory.h:75
Halide::Runtime::Internal::Vulkan::memory_allocator_config
WEAK VulkanMemoryConfig memory_allocator_config
Definition: vulkan_memory.h:32
Halide::Runtime::Internal::StringTable::size
size_t size() const
Definition: string_table.h:54
vkCreateBuffer
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer)
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
@ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
Definition: mini_vulkan.h:1121
Halide::Runtime::Internal::MemoryUsage::DefaultUsage
@ DefaultUsage
Halide::Runtime::Internal::BlockAllocator::reserve
MemoryRegion * reserve(void *user_context, const MemoryRequest &request)
Definition: block_allocator.h:154
Halide::Runtime::Internal::BlockAllocator
Allocator class interface for managing large contiguous blocks of memory, which are then sub-allocate...
Definition: block_allocator.h:25
VK_BUFFER_USAGE_TRANSFER_SRC_BIT
@ VK_BUFFER_USAGE_TRANSFER_SRC_BIT
Definition: mini_vulkan.h:1227
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::retain
int retain(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:462
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
@ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
Definition: mini_vulkan.h:215
vkGetPhysicalDeviceMemoryProperties
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties)
uint64_t
unsigned __INT64_TYPE__ uint64_t
Definition: runtime_internal.h:23
Halide::Runtime::Internal::SystemMemoryAllocatorFns::allocate
AllocateSystemFn allocate
Definition: memory_resources.h:194
malloc
void * malloc(size_t)
halide_error_code_generic_error
@ halide_error_code_generic_error
An uncategorized error occurred.
Definition: HalideRuntime.h:1042
Halide::Runtime::Internal::MemoryProperties::alignment
size_t alignment
Definition: memory_resources.h:60
Halide::Runtime::Internal::Vulkan::custom_allocation_callbacks_lock
WEAK ScopedSpinLock::AtomicFlag custom_allocation_callbacks_lock
Definition: vulkan_memory.h:19
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
@ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
Definition: mini_vulkan.h:185
halide_error_code_out_of_memory
@ halide_error_code_out_of_memory
A call to halide_malloc returned NULL.
Definition: HalideRuntime.h:1082
halide_vulkan_set_allocation_callbacks
WEAK void halide_vulkan_set_allocation_callbacks(const VkAllocationCallbacks *callbacks)
Definition: vulkan_memory.h:1207
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::allocate_block
static int allocate_block(void *instance_ptr, MemoryBlock *block)
Definition: vulkan_memory.h:532
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig::maximum_pool_size
size_t maximum_pool_size
Definition: vulkan_memory.h:26
VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment
VkDeviceSize minUniformBufferOffsetAlignment
Definition: mini_vulkan.h:1605
VkMemoryPropertyFlags
VkFlags VkMemoryPropertyFlags
Definition: mini_vulkan.h:1126
Halide::Runtime::Internal::Vulkan::custom_allocation_callbacks
const WEAK VkAllocationCallbacks * custom_allocation_callbacks
Definition: vulkan_memory.h:20
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig::maximum_block_count
size_t maximum_block_count
Definition: vulkan_memory.h:29
Halide::Runtime::Internal::BlockAllocator::destroy
static void destroy(void *user_context, BlockAllocator *block_allocator)
Definition: block_allocator.h:137
atoi
int atoi(const char *)
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
memset
void * memset(void *s, int val, size_t n)
Halide::Runtime::Internal::BlockAllocator::collect
bool collect(void *user_context)
Definition: block_allocator.h:230
Halide::print
Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
vkUnmapMemory
VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
Halide::Runtime::Internal::MemoryRange::head_offset
size_t head_offset
Definition: memory_resources.h:74
Halide::Runtime::Internal::MemoryBlock::dedicated
bool dedicated
Definition: memory_resources.h:68
Halide::Runtime::Internal::MemoryRange::tail_offset
size_t tail_offset
Definition: memory_resources.h:75
Halide::Runtime::Internal::BlockAllocator::MemoryAllocators::system
SystemMemoryAllocatorFns system
Definition: block_allocator.h:37
VkPhysicalDeviceLimits
Definition: mini_vulkan.h:1536
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
@ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
Definition: mini_vulkan.h:367
Halide::Runtime::Internal::MemoryCaching::UncachedCoherent
@ UncachedCoherent
VkResult
VkResult
Definition: mini_vulkan.h:138
Halide::Runtime::Internal::RegionAllocator::block_resource
BlockResource * block_resource() const
Definition: region_allocator.h:739
Halide::Runtime::Internal::MemoryUsage::UniformStorage
@ UniformStorage
Halide::Runtime::Internal::MemoryVisibility::HostOnly
@ HostOnly
Halide::Runtime::Internal::MemoryCaching::Uncached
@ Uncached
VkPhysicalDeviceMemoryProperties::memoryTypeCount
uint32_t memoryTypeCount
Definition: mini_vulkan.h:1683
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
@ VK_MEMORY_PROPERTY_HOST_CACHED_BIT
Definition: mini_vulkan.h:1122
Halide::Runtime::Internal::MemoryCaching::DefaultCaching
@ DefaultCaching
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::destroy
static int destroy(void *user_context, VulkanMemoryAllocator *allocator)
Definition: vulkan_memory.h:151
VkMemoryRequirements::alignment
VkDeviceSize alignment
Definition: mini_vulkan.h:1753
Halide::Runtime::Internal::SystemMemoryAllocatorFns::deallocate
DeallocateSystemFn deallocate
Definition: memory_resources.h:195
halide_error_code_device_malloc_failed
@ halide_error_code_device_malloc_failed
The Halide runtime encountered an error while trying to allocate memory on device.
Definition: HalideRuntime.h:1104
VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment
VkDeviceSize minStorageBufferOffsetAlignment
Definition: mini_vulkan.h:1606
Halide::Runtime::Internal::StringTable::parse
size_t parse(void *user_context, const char *str, const char *delim)
Definition: string_table.h:158
Halide::Runtime::Internal::BlockAllocator::release
int release(void *user_context, MemoryRegion *region)
Definition: block_allocator.h:197
Halide::Runtime::Internal::MemoryUsage::TransferSrcDst
@ TransferSrcDst
VkAllocationCallbacks::pfnAllocation
PFN_vkAllocationFunction pfnAllocation
Definition: mini_vulkan.h:1451
VkMemoryAllocateInfo
Definition: mini_vulkan.h:1736
VkSystemAllocationScope
VkSystemAllocationScope
Definition: mini_vulkan.h:365
VkMemoryRequirements
Definition: mini_vulkan.h:1751
VK_STRUCTURE_TYPE_SUBMIT_INFO
@ VK_STRUCTURE_TYPE_SUBMIT_INFO
Definition: mini_vulkan.h:177
Halide::Runtime::Internal::BlockAllocator::Config::maximum_block_count
size_t maximum_block_count
Definition: block_allocator.h:48
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::~VulkanMemoryAllocator
~VulkanMemoryAllocator()=delete
VK_WHOLE_SIZE
#define VK_WHOLE_SIZE
Definition: mini_vulkan.h:117
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:22
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::release
int release(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:424
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::deallocate_block
static int deallocate_block(void *instance_ptr, MemoryBlock *block)
Definition: vulkan_memory.h:639
halide_memory_visibility_name
const WEAK char * halide_memory_visibility_name(MemoryVisibility value)
Definition: memory_resources.h:229
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::create
static VulkanMemoryAllocator * create(void *user_context, const VulkanMemoryConfig &config, VkDevice dev, VkPhysicalDevice phys_dev, const SystemMemoryAllocatorFns &system_allocator, const VkAllocationCallbacks *alloc_callbacks=nullptr)
Definition: vulkan_memory.h:129
memory_resources.h
VkSubmitInfo
Definition: mini_vulkan.h:1724
Halide::Runtime::Internal::StringUtils::is_empty
static bool is_empty(const char *str)
Definition: string_storage.h:13
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
@ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
Definition: mini_vulkan.h:1120
Halide::Runtime::Internal::BlockAllocator::Config::maximum_pool_size
size_t maximum_pool_size
Definition: block_allocator.h:45
Halide::Runtime::Internal::MemoryProperties
Definition: memory_resources.h:56
Halide::Runtime::Internal::ScopedSpinLock
Definition: scoped_spin_lock.h:9
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::current_physical_device
VkPhysicalDevice current_physical_device() const
Definition: vulkan_memory.h:78
Halide::Runtime::Internal::MemoryCaching::Cached
@ Cached
vkAllocateMemory
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory)
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::collect
bool collect(void *user_context)
Definition: vulkan_memory.h:481
Halide::Runtime::Internal::BlockAllocator::current_allocators
const MemoryAllocators & current_allocators() const
Definition: block_allocator.h:586
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
@ VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
Definition: mini_vulkan.h:1231
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig::maximum_block_size
size_t maximum_block_size
Definition: vulkan_memory.h:28
Halide::Runtime::Internal::BlockResource::memory
MemoryBlock memory
Definition: memory_resources.h:104
Halide::Runtime::Internal::MemoryRegion::properties
MemoryProperties properties
Definition: memory_resources.h:86
Halide::Runtime::Internal::MemoryRegion::offset
size_t offset
Definition: memory_resources.h:81
Halide::Runtime::Internal::MemoryBlock::size
size_t size
Definition: memory_resources.h:67
Halide::Runtime::Internal::BlockAllocator::MemoryAllocators
Definition: block_allocator.h:36
Halide::Runtime::Internal::MemoryCaching::CachedCoherent
@ CachedCoherent
VkAllocationCallbacks
Definition: mini_vulkan.h:1449
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::operator=
VulkanMemoryAllocator & operator=(const VulkanMemoryAllocator &)=delete
Halide::Runtime::Internal::RegionAllocator
Allocator class interface for sub-allocating a contiguous memory block into smaller regions of memory...
Definition: region_allocator.h:24
VkPhysicalDeviceProperties::limits
VkPhysicalDeviceLimits limits
Definition: mini_vulkan.h:1661
VkMemoryType::propertyFlags
VkMemoryPropertyFlags propertyFlags
Definition: mini_vulkan.h:1673
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::deallocate_region
static int deallocate_region(void *instance_ptr, MemoryRegion *region)
Definition: vulkan_memory.h:907
Halide::Runtime::Internal::Vulkan
Definition: vulkan_context.h:17
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::VulkanMemoryAllocator
VulkanMemoryAllocator()=delete
halide_memory_usage_name
const WEAK char * halide_memory_usage_name(MemoryUsage value)
Definition: memory_resources.h:256
Halide::Runtime::Internal::Vulkan::VulkanMemoryConfig::nearest_multiple
size_t nearest_multiple
Definition: vulkan_memory.h:30
Halide::Runtime::Internal::MemoryProperties::caching
MemoryCaching caching
Definition: memory_resources.h:59
VkCommandBufferBeginInfo
Definition: mini_vulkan.h:2361
Halide::Runtime::Internal::MemoryVisibility::DeviceOnly
@ DeviceOnly
Halide::Runtime::Internal::BlockAllocator::Config::maximum_block_size
size_t maximum_block_size
Definition: block_allocator.h:47
Halide::Runtime::Internal::BlockResource
Definition: memory_resources.h:103
Halide::Runtime::Internal::MemoryProperties::visibility
MemoryVisibility visibility
Definition: memory_resources.h:57
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::reserve
MemoryRegion * reserve(void *user_context, MemoryRequest &request)
Definition: vulkan_memory.h:205
vkCmdFillBuffer
VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
vkBindBufferMemory
VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
vkFreeMemory
VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator)
Halide::Runtime::Internal::MemoryProperties::usage
MemoryUsage usage
Definition: memory_resources.h:58
Halide::Runtime::Internal::SystemMemoryAllocatorFns
Definition: memory_resources.h:193
vkGetBufferMemoryRequirements
VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements)
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::destroy_crop
int destroy_crop(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:385
Halide::Runtime::Internal::MemoryVisibility::DeviceToHost
@ DeviceToHost
free
void free(void *)
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
@ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
Definition: mini_vulkan.h:178
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::callbacks
const VkAllocationCallbacks * callbacks() const
Definition: vulkan_memory.h:81
Halide::DeviceAPI::Vulkan
@ Vulkan
VkDeviceSize
uint64_t VkDeviceSize
Definition: mini_vulkan.h:71
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
@ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
Definition: mini_vulkan.h:1119
vkGetPhysicalDeviceProperties
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::bytes_allocated_for_regions
size_t bytes_allocated_for_regions() const
Definition: vulkan_memory.h:980
VK_MAX_MEMORY_TYPES
#define VK_MAX_MEMORY_TYPES
Definition: mini_vulkan.h:125
VK_BUFFER_USAGE_TRANSFER_DST_BIT
@ VK_BUFFER_USAGE_TRANSFER_DST_BIT
Definition: mini_vulkan.h:1228
Halide::Runtime::Internal::MemoryBlock::handle
void * handle
Definition: memory_resources.h:66
VkPhysicalDeviceProperties
Definition: mini_vulkan.h:1653
vulkan_internal.h
Halide::Runtime::Internal::MemoryUsage::TransferDst
@ TransferDst
HL_VK_ENV_DELIM
#define HL_VK_ENV_DELIM
Definition: vulkan_interface.h:21
WEAK
#define WEAK
Definition: runtime_internal.h:52
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::map
void * map(void *user_context, MemoryRegion *region)
Definition: vulkan_memory.h:228
Halide::Runtime::Internal::MemoryRequest
Definition: memory_resources.h:90
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition: runtime_internal.h:25
Halide::Runtime::Internal::StringTable
Definition: string_table.h:15
Halide::Runtime::Internal::RegionAllocator::find_allocator
static RegionAllocator * find_allocator(void *user_context, MemoryRegion *memory_region)
Definition: region_allocator.h:217
Halide::Runtime::Internal::MemoryRegion::is_owner
bool is_owner
Definition: memory_resources.h:85
VkAllocationCallbacks::pfnFree
PFN_vkFreeFunction pfnFree
Definition: mini_vulkan.h:1453
Halide::Runtime::Internal::MemoryUsage::InvalidUsage
@ InvalidUsage
Halide::Runtime::Internal::MemoryRegion::size
size_t size
Definition: memory_resources.h:82
VK_SUCCESS
@ VK_SUCCESS
Definition: mini_vulkan.h:139
Halide::Runtime::Internal::Vulkan::VulkanMemoryAllocator::blocks_allocated
size_t blocks_allocated() const
Definition: vulkan_memory.h:707
Halide::Runtime::Internal::MemoryUsage::TransferSrc
@ TransferSrc
Halide::Runtime::Internal::MemoryBlock
Definition: memory_resources.h:65
Halide::Runtime::Internal::BlockAllocator::retain
int retain(void *user_context, MemoryRegion *region)
Definition: block_allocator.h:219
Halide::Runtime::Internal::MemoryBlock::properties
MemoryProperties properties
Definition: memory_resources.h:69
Halide::Runtime::Internal::MemoryVisibility::HostToDevice
@ HostToDevice
Halide::Runtime::Internal::RegionAllocator::retain
int retain(void *user_context, MemoryRegion *memory_region)
Definition: region_allocator.h:209