1#ifndef HALIDE_RUNTIME_VULKAN_RESOURCES_H
2#define HALIDE_RUNTIME_VULKAN_RESOURCES_H
79 <<
" vk_create_command_pool (user_context: " << user_context <<
", "
80 <<
"allocator: " << (
void *)allocator <<
", "
81 <<
"queue_index: " << queue_index <<
")\n";
84 if (allocator ==
nullptr) {
85 error(user_context) <<
"Vulkan: Failed to create command pool ... invalid allocator pointer!\n";
99 error(user_context) <<
"Vulkan: Failed to create command pool!\n";
105int vk_destroy_command_pool(
void *user_context,
VulkanMemoryAllocator *allocator, VkCommandPool command_pool) {
108 <<
" vk_destroy_command_pool (user_context: " << user_context <<
", "
109 <<
"allocator: " << (
void *)allocator <<
", "
110 <<
"command_pool: " << (
void *)command_pool <<
")\n";
112 if (allocator ==
nullptr) {
113 error(user_context) <<
"Vulkan: Failed to destroy command pool ... invalid allocator pointer!\n";
116 if (command_pool == VkInvalidCommandPool) {
117 debug(user_context) <<
"Vulkan: Command pool already destroyed.\n";
127int vk_create_command_buffer(
void *user_context,
VulkanMemoryAllocator *allocator, VkCommandPool command_pool, VkCommandBuffer *command_buffer) {
130 <<
" vk_create_command_buffer (user_context: " << user_context <<
", "
131 <<
"allocator: " << (
void *)allocator <<
", "
132 <<
"command_pool: " << (
void *)command_pool <<
")\n";
134 if (allocator ==
nullptr) {
135 error(user_context) <<
"Vulkan: Failed to create command buffer ... invalid allocator pointer!\n";
150 error(user_context) <<
"Vulkan: Failed to allocate command buffers!\n";
156int vk_destroy_command_buffer(
void *user_context,
VulkanMemoryAllocator *allocator, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
159 <<
" vk_destroy_command_buffer (user_context: " << user_context <<
", "
160 <<
"allocator: " << (
void *)allocator <<
", "
161 <<
"command_pool: " << (
void *)command_pool <<
", "
162 <<
"command_buffer: " << (
void *)command_buffer <<
")\n";
164 if (allocator ==
nullptr) {
165 error(user_context) <<
"Vulkan: Failed to destroy command buffer ... invalid allocator pointer!\n";
173int vk_fill_command_buffer_with_dispatch_call(
void *user_context,
175 VkCommandBuffer command_buffer,
176 VkPipeline compute_pipeline,
177 VkPipelineLayout pipeline_layout,
178 VkDescriptorSet descriptor_set,
180 int blocksX,
int blocksY,
int blocksZ) {
184 <<
" vk_fill_command_buffer_with_dispatch_call (user_context: " << user_context <<
", "
185 <<
"device: " << (
void *)device <<
", "
186 <<
"command_buffer: " << (
void *)command_buffer <<
", "
187 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
", "
188 <<
"descriptor_set: " << (
void *)descriptor_set <<
", "
189 <<
"descriptor_set_index: " << descriptor_set_index <<
", "
190 <<
"blocks: " << blocksX <<
", " << blocksY <<
", " << blocksZ <<
")\n";
202 error(user_context) <<
"vkBeginCommandBuffer returned " << vk_get_error_name(result) <<
"\n";
208 descriptor_set_index, 1, &descriptor_set, 0,
nullptr);
213 error(user_context) <<
"vkEndCommandBuffer returned " << vk_get_error_name(result) <<
"\n";
220int vk_submit_command_buffer(
void *user_context, VkQueue queue, VkCommandBuffer command_buffer) {
223 <<
" vk_submit_command_buffer (user_context: " << user_context <<
", "
224 <<
"queue: " << (
void *)queue <<
", "
225 <<
"command_buffer: " << (
void *)command_buffer <<
")\n";
243 error(user_context) <<
"Vulkan: vkQueueSubmit returned " << vk_get_error_name(result) <<
"\n";
251bool vk_needs_scalar_uniform_buffer(
void *user_context,
256 while (arg_sizes[i] > 0) {
257 if (!arg_is_buffer[i]) {
265uint32_t vk_count_bindings_for_descriptor_set(
void *user_context,
271 uint32_t bindings_count = vk_needs_scalar_uniform_buffer(user_context, arg_sizes, args, arg_is_buffer);
274 while (arg_sizes[i] > 0) {
275 if (arg_is_buffer[i]) {
280 return bindings_count;
285int vk_create_descriptor_pool(
void *user_context,
289 VkDescriptorPool *descriptor_pool) {
292 <<
" vk_create_descriptor_pool (user_context: " << user_context <<
", "
293 <<
"allocator: " << (
void *)allocator <<
", "
294 <<
"uniform_buffer_count: " << (
uint32_t)uniform_buffer_count <<
", "
295 <<
"storage_buffer_count: " << (
uint32_t)storage_buffer_count <<
")\n";
297 if (allocator ==
nullptr) {
298 error(user_context) <<
"Vulkan: Failed to create descriptor pool ... invalid allocator pointer!\n";
304 pool_config.
minimum_capacity = (uniform_buffer_count ? 1 : 0) + (storage_buffer_count ? 1 : 0);
308 if (uniform_buffer_count > 0) {
313 pool_sizes.
append(user_context, &uniform_buffer_size);
316 if (storage_buffer_count > 0) {
321 pool_sizes.
append(user_context, &storage_buffer_size);
335 error(user_context) <<
"Vulkan: Failed to create descriptor pool! vkCreateDescriptorPool returned " << vk_get_error_name(result) <<
"\n";
341int vk_destroy_descriptor_pool(
void *user_context,
343 VkDescriptorPool descriptor_pool) {
346 <<
" vk_destroy_descriptor_pool (user_context: " << user_context <<
", "
347 <<
"allocator: " << (
void *)allocator <<
", "
348 <<
"descriptor_pool: " << (
void *)descriptor_pool <<
")\n";
350 if (allocator ==
nullptr) {
351 error(user_context) <<
"Vulkan: Failed to destroy descriptor pool ... invalid allocator pointer!\n";
360int vk_create_descriptor_set_layout(
void *user_context,
364 VkDescriptorSetLayout *layout) {
368 <<
" vk_create_descriptor_set_layout (user_context: " << user_context <<
", "
369 <<
"allocator: " << (
void *)allocator <<
", "
370 <<
"uniform_buffer_count: " << uniform_buffer_count <<
", "
371 <<
"storage_buffer_count: " << storage_buffer_count <<
", "
372 <<
"layout: " << (
void *)layout <<
")\n";
374 if (allocator ==
nullptr) {
375 error(user_context) <<
"Vulkan: Failed to create descriptor set layout ... invalid allocator pointer!\n";
381 layout_config.
minimum_capacity = uniform_buffer_count + storage_buffer_count;
382 BlockStorage layout_bindings(user_context, layout_config);
385 for (
uint32_t n = 0; n < uniform_buffer_count; ++n) {
396 <<
" [" << (
uint32_t)layout_bindings.
size() <<
"] : UNIFORM_BUFFER\n";
399 layout_bindings.
append(user_context, &uniform_buffer_layout);
403 for (
uint32_t n = 0; n < storage_buffer_count; ++n) {
415 <<
" [" << (
uint32_t)layout_bindings.
size() <<
"] : STORAGE_BUFFER\n";
418 layout_bindings.
append(user_context, &storage_buffer_layout);
433 error(user_context) <<
"vkCreateDescriptorSetLayout returned " << vk_get_error_name(result) <<
"\n";
440int vk_destroy_descriptor_set_layout(
void *user_context,
442 VkDescriptorSetLayout descriptor_set_layout) {
446 <<
" vk_destroy_descriptor_set_layout (user_context: " << user_context <<
", "
447 <<
"allocator: " << (
void *)allocator <<
", "
448 <<
"layout: " << (
void *)descriptor_set_layout <<
")\n";
450 if (allocator ==
nullptr) {
451 error(user_context) <<
"Vulkan: Failed to destroy descriptor set layout ... invalid allocator pointer!\n";
460int vk_create_descriptor_set(
void *user_context,
462 VkDescriptorSetLayout descriptor_set_layout,
463 VkDescriptorPool descriptor_pool,
464 VkDescriptorSet *descriptor_set) {
467 <<
" vk_create_descriptor_set (user_context: " << user_context <<
", "
468 <<
"allocator: " << (
void *)allocator <<
", "
469 <<
"descriptor_set_layout: " << (
void *)descriptor_set_layout <<
", "
470 <<
"descriptor_pool: " << (
void *)descriptor_pool <<
")\n";
472 if (allocator ==
nullptr) {
473 error(user_context) <<
"Vulkan: Failed to create descriptor set ... invalid allocator pointer!\n";
483 &descriptor_set_layout
488 error(user_context) <<
"Vulkan: vkAllocateDescriptorSets returned " << vk_get_error_name(result) <<
"\n";
495int vk_update_descriptor_set(
void *user_context,
497 VkBuffer *scalar_args_buffer,
498 size_t uniform_buffer_count,
499 size_t storage_buffer_count,
503 VkDescriptorSet descriptor_set) {
506 <<
" vk_update_descriptor_set (user_context: " << user_context <<
", "
507 <<
"allocator: " << (
void *)allocator <<
", "
508 <<
"scalar_args_buffer: " << (
void *)scalar_args_buffer <<
", "
509 <<
"uniform_buffer_count: " << (
uint32_t)uniform_buffer_count <<
", "
510 <<
"storage_buffer_count: " << (
uint32_t)storage_buffer_count <<
", "
511 <<
"descriptor_set: " << (
void *)descriptor_set <<
")\n";
513 if (allocator ==
nullptr) {
514 error(user_context) <<
"Vulkan: Failed to create descriptor set ... invalid allocator pointer!\n";
521 BlockStorage descriptor_buffer_info(user_context, dbi_config);
526 BlockStorage write_descriptor_set(user_context, wds_config);
530 if (scalar_args_buffer !=
nullptr) {
536 descriptor_buffer_info.
append(user_context, &scalar_args_descriptor_buffer_info);
540 debug(user_context) <<
" [" << (
uint32_t)write_descriptor_set.
size() <<
"] UNIFORM_BUFFER : "
541 <<
"buffer=" << (
void *)scalar_args_buffer <<
" "
542 <<
"offset=" << (
uint32_t)(0) <<
" "
543 <<
"size=VK_WHOLE_SIZE\n";
557 write_descriptor_set.
append(user_context, &uniform_buffer_write_descriptor_set);
561 for (
size_t i = 0; arg_sizes[i] > 0; i++) {
562 if (arg_is_buffer[i]) {
569 VkBuffer *device_buffer =
reinterpret_cast<VkBuffer *
>(owner->
handle);
570 if (device_buffer ==
nullptr) {
571 error(user_context) <<
"Vulkan: Failed to retrieve buffer for device memory!\n";
583 descriptor_buffer_info.
append(user_context, &device_buffer_info);
587 debug(user_context) <<
" [" << (
uint32_t)write_descriptor_set.
size() <<
"] STORAGE_BUFFER : "
588 <<
"region=" << (
void *)device_region <<
" "
589 <<
"buffer=" << (
void *)device_buffer <<
" "
590 <<
"offset=" << (
uint32_t)(range_offset) <<
" "
591 <<
"size=" << (
uint32_t)(range_size) <<
"\n";
606 write_descriptor_set.
append(user_context, &storage_buffer_write_descriptor_set);
617size_t vk_estimate_scalar_uniform_buffer_size(
void *user_context,
622 int scalar_uniform_buffer_size = 0;
623 while (arg_sizes[i] > 0) {
624 if (!arg_is_buffer[i]) {
625 scalar_uniform_buffer_size += arg_sizes[i];
629 return scalar_uniform_buffer_size;
632MemoryRegion *vk_create_scalar_uniform_buffer(
void *user_context,
634 size_t scalar_buffer_size) {
638 <<
" vk_create_scalar_uniform_buffer (user_context: " << user_context <<
", "
639 <<
"allocator: " << (
void *)allocator <<
", "
640 <<
"scalar_buffer_size: " << (
uint32_t)scalar_buffer_size <<
")\n";
643 if (allocator ==
nullptr) {
644 error(user_context) <<
"Vulkan: Failed to create scalar uniform buffer ... invalid allocator pointer!\n";
649 request.
size = scalar_buffer_size;
656 if ((region ==
nullptr) || (region->
handle ==
nullptr)) {
657 error(user_context) <<
"Vulkan: Failed to create scalar uniform buffer ... unable to allocate device memory!\n";
665int vk_update_scalar_uniform_buffer(
void *user_context,
674 <<
" vk_update_scalar_uniform_buffer (user_context: " << user_context <<
", "
675 <<
"region: " << (
void *)region <<
")\n";
678 if (allocator ==
nullptr) {
679 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... invalid allocator pointer!\n";
683 if ((region ==
nullptr) || (region->
handle ==
nullptr)) {
684 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... invalid memory region!\n";
690 if (host_ptr ==
nullptr) {
691 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... unable to map host pointer to device memory!\n";
696 size_t arg_offset = 0;
697 for (
size_t i = 0; arg_sizes[i] > 0; i++) {
698 if (!arg_is_buffer[i]) {
699 memcpy(host_ptr + arg_offset, args[i], arg_sizes[i]);
700 arg_offset += arg_sizes[i];
705 allocator->
unmap(user_context, region);
714 <<
" vk_destroy_scalar_uniform_buffer (user_context: " << user_context <<
", "
715 <<
"allocator: " << (
void *)allocator <<
", "
716 <<
"scalar_args_region: " << (
void *)scalar_args_region <<
")\n";
718 if (allocator ==
nullptr) {
719 error(user_context) <<
"Vulkan: Failed to destroy scalar uniform buffer ... invalid allocator pointer!\n";
723 if (!scalar_args_region) {
729 error_code = allocator->
release(user_context, scalar_args_region);
731 error_code = allocator->
reclaim(user_context, scalar_args_region);
738int vk_create_pipeline_layout(
void *user_context,
741 VkDescriptorSetLayout *descriptor_set_layouts,
742 VkPipelineLayout *pipeline_layout) {
746 <<
" vk_create_pipeline_layout (user_context: " << user_context <<
", "
747 <<
"allocator: " << (
void *)allocator <<
", "
748 <<
"descriptor_set_count: " << descriptor_set_count <<
", "
749 <<
"descriptor_set_layouts: " << (
void *)descriptor_set_layouts <<
", "
750 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
752 if (allocator ==
nullptr) {
753 error(user_context) <<
"Vulkan: Failed to create pipeline layout ... invalid allocator pointer!\n";
759 if (descriptor_set_count > max_bound_descriptor_sets) {
760 error(user_context) <<
"Vulkan: Number of descriptor sets for pipeline layout exceeds the number that can be bound by device!\n"
761 <<
" requested: " << descriptor_set_count <<
","
762 <<
" available: " << max_bound_descriptor_sets <<
"\n";
771 descriptor_set_count,
772 descriptor_set_layouts,
779 error(user_context) <<
"Vulkan: vkCreatePipelineLayout returned " << vk_get_error_name(result) <<
"\n";
785int vk_destroy_pipeline_layout(
void *user_context,
787 VkPipelineLayout pipeline_layout) {
791 <<
" vk_destroy_pipeline_layout (user_context: " << user_context <<
", "
792 <<
"allocator: " << (
void *)allocator <<
", "
793 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
796 if (allocator ==
nullptr) {
797 error(user_context) <<
"Vulkan: Failed to destroy pipeline layout ... invalid allocator pointer!\n";
807int vk_create_compute_pipeline(
void *user_context,
809 const char *pipeline_name,
810 VkShaderModule shader_module,
811 VkPipelineLayout pipeline_layout,
813 VkPipeline *compute_pipeline) {
817 <<
" vk_create_compute_pipeline (user_context: " << user_context <<
", "
818 <<
"allocator: " << (
void *)allocator <<
", "
819 <<
"shader_module: " << (
void *)shader_module <<
", "
820 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
822 if (allocator ==
nullptr) {
823 error(user_context) <<
"Vulkan: Failed to create compute pipeline ... invalid allocator pointer!\n";
849 error(user_context) <<
"Vulkan: Failed to create compute pipeline! vkCreateComputePipelines returned " << vk_get_error_name(result) <<
"\n";
856int vk_setup_compute_pipeline(
void *user_context,
860 VkShaderModule shader_module,
861 VkPipelineLayout pipeline_layout,
862 VkPipeline *compute_pipeline) {
866 <<
" vk_setup_compute_pipeline (user_context: " << user_context <<
", "
868 <<
"allocator: " << (
void *)allocator <<
", "
869 <<
"shader_bindings: " << (
void *)shader_bindings <<
", "
870 <<
"dispatch_data: " << (
void *)dispatch_data <<
", "
871 <<
"shader_module: " << (
void *)shader_module <<
", "
872 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
875 if (allocator ==
nullptr) {
876 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid allocator pointer!\n";
880 if (shader_bindings ==
nullptr) {
881 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid shader bindings!\n";
885 if (shader_bindings ==
nullptr) {
886 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid dispatch data!\n";
892 if (entry_point_name ==
nullptr) {
893 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... missing entry point name!\n";
897 uint32_t dispatch_constant_index = 0;
898 uint32_t dispatch_constant_ids[4] = {0, 0, 0, 0};
899 uint32_t dispatch_constant_values[4] = {0, 0, 0, 0};
904 uint32_t shared_mem_constant_id = 0;
905 uint32_t static_shared_mem_bytes = 0;
915 if (shared_mem_constant_id > 0) {
916 error(user_context) <<
"Vulkan: Multiple dynamic shared memory allocations found! Only one is suported!!\n";
921 shared_mem_type_size = allocation->
type_size;
926 debug(user_context) <<
" pipeline uses " << static_shared_mem_bytes <<
" bytes of static shared memory\n";
927 debug(user_context) <<
" dispatch requests " << dispatch_data->
shared_mem_bytes <<
" bytes of shared memory\n";
928 debug(user_context) <<
" dynamic shared memory " << shared_mem_bytes_avail <<
" bytes available\n";
931 if ((shared_mem_constant_id > 0) && (shared_mem_bytes_avail > 0)) {
932 uint32_t dynamic_array_size = (
uint32_t)shared_mem_bytes_avail / shared_mem_type_size;
934 debug(user_context) <<
" setting shared memory to " << (
uint32_t)dynamic_array_size <<
" elements "
935 <<
"(or " << (
uint32_t)shared_mem_bytes_avail <<
" bytes)\n";
938 dispatch_constant_ids[dispatch_constant_index] = shared_mem_constant_id;
939 dispatch_constant_values[dispatch_constant_index] = dynamic_array_size;
940 dispatch_constant_index++;
946 if (static_shared_mem_bytes > device_shared_mem_size) {
947 error(user_context) <<
"Vulkan: Amount of static shared memory used exceeds device limit!\n"
948 <<
" requested: " << static_shared_mem_bytes <<
" bytes,"
949 <<
" available: " << device_shared_mem_size <<
" bytes\n";
953 error(user_context) <<
"Vulkan: Amount of dynamic shared memory used exceeds device limit!\n"
955 <<
" available: " << device_shared_mem_size <<
" bytes\n";
963 for (
uint32_t dim = 0; dim < 3; dim++) {
965 dispatch_constant_values[dispatch_constant_index] = dispatch_data->
local_size[dim];
966 dispatch_constant_index++;
971 for (
uint32_t dc = 0; dc < dispatch_constant_index; dc++) {
973 uint32_t found_index = invalid_index;
977 debug(user_context) <<
" binding specialization constant [" << dispatch_constant_ids[dc] <<
"] "
979 <<
" => " << dispatch_constant_values[dc] <<
"\n";
985 if (found_index == invalid_index) {
986 error(user_context) <<
"Vulkan: Failed to locate dispatch constant index for shader binding!\n";
993 error(user_context) <<
"Vulkan: Failed to decode shader bindings! " << vk_get_error_name(result) <<
"\n";
998 uint32_t dispatch_constant_count = 0;
1001 for (
uint32_t dc = 0; dc < dispatch_constant_index && dc < 4; dc++) {
1002 specialization_map_entries[dc].
constantID = dispatch_constant_ids[dc];
1003 specialization_map_entries[dc].
size =
sizeof(
uint32_t);
1005 dispatch_constant_count++;
1008 if (dispatch_constant_count > 0) {
1013 specialization_info.
mapEntryCount = dispatch_constant_count;
1014 specialization_info.
pMapEntries = specialization_map_entries;
1015 specialization_info.
pData = dispatch_constant_values;
1019 int error_code = vk_destroy_compute_pipeline(user_context, allocator, shader_bindings->
compute_pipeline);
1021 error(user_context) <<
"Vulkan: Failed to destroy compute pipeline!\n";
1027 int error_code = vk_create_compute_pipeline(user_context, allocator, entry_point_name, shader_module, pipeline_layout, &specialization_info, &(shader_bindings->
compute_pipeline));
1029 error(user_context) <<
"Vulkan: Failed to create compute pipeline!\n";
1037 int error_code = vk_create_compute_pipeline(user_context, allocator, entry_point_name, shader_module, pipeline_layout,
nullptr, &(shader_bindings->
compute_pipeline));
1039 error(user_context) <<
"Vulkan: Failed to create compute pipeline!\n";
1048int vk_destroy_compute_pipeline(
void *user_context,
1050 VkPipeline compute_pipeline) {
1053 <<
" vk_destroy_compute_pipeline (user_context: " << user_context <<
", "
1054 <<
"allocator: " << (
void *)allocator <<
", "
1056 <<
"compute_pipeline: " << (
void *)compute_pipeline <<
")\n";
1058 if (allocator ==
nullptr) {
1059 error(user_context) <<
"Vulkan: Failed to destroy compute pipeline ... invalid allocator pointer!\n";
1072 <<
" vk_decode_shader_bindings (user_context: " << user_context <<
", "
1073 <<
"allocator: " << (
void *)allocator <<
", "
1074 <<
"module_ptr: " << (
void *)module_ptr <<
", "
1075 <<
"module_size: " << module_size <<
")\n";
1080 if (allocator ==
nullptr) {
1081 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... invalid allocator pointer!\n";
1085 if ((module_ptr ==
nullptr) || (module_size < (2 *
sizeof(
uint32_t)))) {
1086 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... invalid module buffer!\n";
1132 uint32_t shader_count = module_ptr[idx++];
1133 if (shader_count < 1) {
1134 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... no descriptors found!\n";
1142 if (shader_bindings ==
nullptr) {
1143 error(user_context) <<
"Vulkan: Failed to allocate shader_bindings! Out of memory!\n";
1146 memset(shader_bindings, 0, shader_bindings_size);
1149 for (
uint32_t n = 0; (n < shader_count) && (idx < module_entries); n++) {
1153 uint32_t entry_point_name_length = module_ptr[idx++];
1156 const char *entry_point_name = (
const char *)(module_ptr + idx);
1157 idx += entry_point_name_length;
1160 uint32_t uniform_buffer_count = module_ptr[idx++];
1163 uint32_t storage_buffer_count = module_ptr[idx++];
1166 uint32_t specialization_constants_count = module_ptr[idx++];
1170 if (specialization_constants_count > 0) {
1175 if (specialization_constants ==
nullptr) {
1176 error(user_context) <<
"Vulkan: Failed to allocate specialization_constants! Out of memory!\n";
1179 memset(specialization_constants, 0, specialization_constants_size);
1182 for (
uint32_t sc = 0; sc < specialization_constants_count; sc++) {
1186 uint32_t constant_name_length = module_ptr[idx++];
1189 const char *constant_name = (
const char *)(module_ptr + idx);
1190 specialization_constants[sc].constant_name = constant_name;
1191 idx += constant_name_length;
1194 specialization_constants[sc].constant_id = module_ptr[idx++];
1197 specialization_constants[sc].type_size = module_ptr[idx++];
1202 uint32_t shared_memory_allocations_count = module_ptr[idx++];
1206 if (shared_memory_allocations_count > 0) {
1211 if (shared_memory_allocations ==
nullptr) {
1212 error(user_context) <<
"Vulkan: Failed to allocate shared_memory_allocations! Out of memory!\n";
1215 memset(shared_memory_allocations, 0, shared_memory_allocations_size);
1218 for (
uint32_t sm = 0; sm < shared_memory_allocations_count && (idx < module_entries); sm++) {
1222 uint32_t variable_name_length = module_ptr[idx++];
1225 const char *variable_name = (
const char *)(module_ptr + idx);
1226 shared_memory_allocations[sm].variable_name = variable_name;
1227 idx += variable_name_length;
1230 shared_memory_allocations[sm].constant_id = module_ptr[idx++];
1233 shared_memory_allocations[sm].type_size = module_ptr[idx++];
1236 shared_memory_allocations[sm].array_size = module_ptr[idx++];
1242 for (
uint32_t dim = 0; dim < 3 && (idx < module_entries); dim++) {
1243 shader_bindings[n].dispatch_data.local_size_binding.constant_id[dim] = module_ptr[idx++];
1248 debug(user_context) <<
" [" << n <<
"] '" << (
const char *)entry_point_name <<
"'\n";
1250 debug(user_context) <<
" uniform_buffer_count=" << uniform_buffer_count <<
"\n"
1251 <<
" storage_buffer_count=" << storage_buffer_count <<
"\n";
1253 debug(user_context) <<
" specialization_constants_count=" << specialization_constants_count <<
"\n";
1254 for (
uint32_t sc = 0; sc < specialization_constants_count; sc++) {
1255 debug(user_context) <<
" [" << sc <<
"] "
1256 <<
"constant_name='" << (
const char *)specialization_constants[sc].constant_name <<
"' "
1257 <<
"constant_id=" << specialization_constants[sc].constant_id <<
" "
1258 <<
"type_size=" << specialization_constants[sc].type_size <<
"\n";
1261 debug(user_context) <<
" shared_memory_allocations_count=" << shared_memory_allocations_count <<
"\n";
1262 for (
uint32_t sm = 0; sm < shared_memory_allocations_count; sm++) {
1263 debug(user_context) <<
" [" << sm <<
"] "
1264 <<
"variable_name='" << (
const char *)shared_memory_allocations[sm].variable_name <<
"' "
1265 <<
"constant_id=" << shared_memory_allocations[sm].constant_id <<
" "
1266 <<
"type_size=" << shared_memory_allocations[sm].type_size <<
" "
1267 <<
"array_size=" << shared_memory_allocations[sm].array_size <<
"\n";
1269 debug(user_context) <<
" local_size_binding=[";
1270 for (
uint32_t dim = 0; dim < 3 && (idx < module_entries); dim++) {
1271 debug(user_context) << shader_bindings[n].dispatch_data.local_size_binding.constant_id[dim] <<
" ";
1273 debug(user_context) <<
"]\n";
1275 shader_bindings[n].entry_point_name = entry_point_name;
1276 shader_bindings[n].uniform_buffer_count = uniform_buffer_count;
1277 shader_bindings[n].storage_buffer_count = storage_buffer_count;
1278 shader_bindings[n].specialization_constants_count = specialization_constants_count;
1279 shader_bindings[n].specialization_constants = specialization_constants;
1280 shader_bindings[n].shared_memory_allocations_count = shared_memory_allocations_count;
1281 shader_bindings[n].shared_memory_allocations = shared_memory_allocations;
1286 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1289 return shader_bindings;
1296 <<
" vk_validate_shader_for_device (user_context: " << user_context <<
", "
1297 <<
"allocator: " << (
void *)allocator <<
", "
1298 <<
"shader_bindings: " << (
void *)shader_bindings <<
", "
1299 <<
"shader_count: " << shader_count <<
")\n";
1305 uint32_t static_shared_mem_bytes = 0;
1320 if (static_shared_mem_bytes > device_shared_mem_size) {
1321 error(user_context) <<
"Vulkan: Amount of static shared memory used exceeds device limit!\n"
1322 <<
" requested: " << static_shared_mem_bytes <<
" bytes,"
1323 <<
" available: " << device_shared_mem_size <<
" bytes\n";
1332 if (shader_count > max_descriptors) {
1333 error(user_context) <<
"Vulkan: Number of required descriptor sets exceeds the amount available for device!\n"
1334 <<
" requested: " << shader_count <<
","
1335 <<
" available: " << max_descriptors <<
"\n";
1343 const char *ptr,
int size) {
1346 <<
" vk_compile_shader_module (user_context: " << user_context <<
", "
1347 <<
"allocator: " << (
void *)allocator <<
", "
1349 <<
"module: " << (
void *)ptr <<
", "
1350 <<
"size: " << size <<
")\n";
1355 if (allocator ==
nullptr) {
1356 error(user_context) <<
"Vulkan: Failed to compile shader modules ... invalid allocator pointer!\n";
1360 if ((ptr ==
nullptr) || (size <= 0)) {
1361 error(user_context) <<
"Vulkan: Failed to compile shader modules ... invalid program source buffer!\n";
1371 uint32_t header_word_count = module_ptr[0];
1372 uint32_t shader_count = module_ptr[1];
1376 const uint32_t *binary_ptr = (module_ptr + header_word_count);
1377 size_t binary_size = (size - header_size);
1380 debug(user_context) <<
"Vulkan: Decoding module ("
1381 <<
"module_ptr: " << (
void *)module_ptr <<
", "
1382 <<
"header_word_count: " << header_word_count <<
", "
1383 <<
"header_size: " << header_size <<
", "
1384 <<
"binar_ptr: " << (
void *)binary_ptr <<
", "
1385 <<
"binary_size: " << (
uint32_t)binary_size <<
")\n";
1398 if (cache_entry ==
nullptr) {
1399 error(user_context) <<
"Vulkan: Failed to allocate compilation cache entry! Out of memory!\n";
1405 VulkanShaderBinding *decoded_bindings = vk_decode_shader_bindings(user_context, allocator, module_ptr, module_size);
1406 if (decoded_bindings ==
nullptr) {
1407 error(user_context) <<
"Vulkan: Failed to decode shader bindings!\n";
1412 int valid_status = vk_validate_shader_for_device(user_context, allocator, decoded_bindings, shader_count);
1415 vk_host_free(user_context, cache_entry, allocator->
callbacks());
1425 error(user_context) <<
"Vulkan: vkCreateShaderModule Failed! Error returned: " << vk_get_error_name(result) <<
"\n";
1427 vk_host_free(user_context, cache_entry, allocator->
callbacks());
1435 error(user_context) <<
"Vulkan: Failed to allocate descriptor set layouts for cache entry! Out of memory!\n";
1443 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1453 <<
" vk_destroy_shader_modules (user_context: " << user_context <<
", "
1454 <<
"allocator: " << (
void *)allocator <<
", "
1460 if (allocator ==
nullptr) {
1461 error(user_context) <<
"Vulkan: Failed to destroy shader modules ... invalid allocator pointer!\n";
1466 struct DestroyShaderModule {
1467 void *user_context =
nullptr;
1471 : user_context(ctx), allocator(allocator) {
1475 if (cache_entry !=
nullptr) {
1486 debug(user_context) <<
" destroying pipeline layout " << (
void *)cache_entry->
pipeline_layout <<
"\n";
1487 vk_destroy_pipeline_layout(user_context, allocator, cache_entry->
pipeline_layout);
1518 debug(user_context) <<
" . destroying shader module " << (
void *)cache_entry->
shader_module <<
"\n";
1523 vk_host_free(user_context, cache_entry, allocator->
callbacks());
1524 cache_entry =
nullptr;
1529 DestroyShaderModule module_destructor(user_context, allocator);
1534 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1541int vk_do_multidimensional_copy(
void *user_context, VkCommandBuffer command_buffer,
1543 int d,
bool from_host,
bool to_host) {
1546 if ((!from_host && to_host) ||
1547 (from_host && !to_host) ||
1548 (!from_host && !to_host)) {
1556 VkBuffer *src_buffer =
reinterpret_cast<VkBuffer *
>(c.
src);
1557 VkBuffer *dst_buffer =
reinterpret_cast<VkBuffer *
>(c.
dst);
1558 if (!src_buffer || !dst_buffer) {
1559 error(user_context) <<
"Vulkan: Failed to retrieve buffer for device memory!\n";
1563 vkCmdCopyBuffer(command_buffer, *src_buffer, *dst_buffer, 1, &buffer_copy);
1565 }
else if ((c.
dst + dst_offset) != (c.
src + src_offset)) {
1576 int err = vk_do_multidimensional_copy(user_context, command_buffer, c,
1577 src_offset + src_off,
1578 dst_offset + dst_off,
1579 d - 1, from_host, to_host);
1590int vk_device_crop_from_offset(
void *user_context,
1597 error(user_context) <<
"Vulkan: Failed to acquire context!\n";
1606 error(user_context) <<
"Vulkan: Invalid offset for device crop!\n";
1612 if (device_region ==
nullptr) {
1613 error(user_context) <<
"Vulkan: Failed to crop region! Invalide device region!\n";
1619 if ((cropped_region ==
nullptr) || (cropped_region->
handle ==
nullptr)) {
1620 error(user_context) <<
"Vulkan: Failed to crop region! Unable to create memory region!\n";
1630 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
bool halide_can_reuse_device_allocations(void *user_context)
Determines whether on device_free the memory is returned immediately to the device API,...
@ halide_error_code_incompatible_device_interface
An operation on a buffer required an allocation on a particular device interface, but a device alloca...
@ halide_error_code_internal_error
There is a bug in the Halide compiler.
@ halide_error_code_generic_error
An uncategorized error occurred.
@ halide_error_code_device_crop_failed
Cropping/slicing a buffer failed for some other reason.
@ halide_error_code_success
There was no error.
void append(void *user_context, const void *entry_ptr)
VulkanMemoryAllocator * allocator
halide_error_code_t error
Vulkan Memory Allocator class interface for managing large memory requests stored as contiguous block...
int reclaim(void *user_context, MemoryRegion *region)
MemoryRegion * reserve(void *user_context, const MemoryRequest &request)
int release(void *user_context, MemoryRegion *region)
int unmap(void *user_context, MemoryRegion *region)
MemoryRegion * create_crop(void *user_context, MemoryRegion *region, uint64_t offset)
MemoryRegion * owner_of(void *user_context, MemoryRegion *region)
VkDevice current_device() const
VkPhysicalDeviceLimits current_physical_device_limits() const
const VkAllocationCallbacks * callbacks() const
void * map(void *user_context, MemoryRegion *region)
VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
@ VK_COMMAND_BUFFER_LEVEL_PRIMARY
VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator)
@ VK_SHADER_STAGE_COMPUTE_BIT
VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
struct VkDescriptorSetLayoutBinding VkDescriptorSetLayoutBinding
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool)
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout)
@ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
@ VK_PIPELINE_BIND_POINT_COMPUTE
VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions)
VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator)
@ VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT
VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool)
VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines)
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence)
VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets)
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers)
@ VK_ERROR_INITIALIZATION_FAILED
@ VK_ERROR_TOO_MANY_OBJECTS
@ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
@ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
struct VkDescriptorPoolSize VkDescriptorPoolSize
VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule)
struct VkDescriptorBufferInfo VkDescriptorBufferInfo
VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies)
@ VK_COMMAND_POOL_CREATE_TRANSIENT_BIT
VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer)
struct VkWriteDescriptorSet VkWriteDescriptorSet
VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout)
@ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
@ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
@ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
@ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
@ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
@ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
@ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO
@ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
@ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
@ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO
@ VK_STRUCTURE_TYPE_SUBMIT_INFO
@ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo)
WEAK Halide::Internal::GPUCompilationCache< VkDevice, VulkanCompilationCacheEntry * > compilation_cache
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
unsigned __INT64_TYPE__ uint64_t
signed __INT64_TYPE__ int64_t
#define halide_debug_assert(user_context, cond)
halide_debug_assert() is like halide_assert(), but only expands into a check when DEBUG_RUNTIME is de...
unsigned __INT8_TYPE__ uint8_t
void * memcpy(void *s1, const void *s2, size_t n)
void * memset(void *s, int val, size_t n)
unsigned __INT32_TYPE__ uint32_t
#define halide_abort_if_false(user_context, cond)
WEAK int64_t halide_current_time_ns(void *user_context)
signed __INT8_TYPE__ int8_t
uint32_t minimum_capacity
MemoryVisibility visibility
MemoryProperties properties
VkDescriptorSetLayout * descriptor_set_layouts
VulkanShaderBinding * shader_bindings
VkPipelineLayout pipeline_layout
VkShaderModule shader_module
uint32_t shared_mem_bytes
VulkanWorkgroupSizeBinding local_size_binding
VulkanSpecializationConstant * specialization_constants
VulkanSharedMemoryAllocation * shared_memory_allocations
uint32_t shared_memory_allocations_count
uint32_t storage_buffer_count
uint32_t uniform_buffer_count
VulkanDispatchData dispatch_data
VkDescriptorSet descriptor_set
uint32_t specialization_constants_count
VkPipeline compute_pipeline
VkDescriptorPool descriptor_pool
const char * entry_point_name
MemoryRegion * args_region
const char * variable_name
const char * constant_name
uint64_t src_stride_bytes[MAX_COPY_DIMS]
uint64_t extent[MAX_COPY_DIMS]
uint64_t dst_stride_bytes[MAX_COPY_DIMS]
uint32_t maxPerStageDescriptorStorageBuffers
uint32_t maxBoundDescriptorSets
uint32_t maxComputeSharedMemorySize
const VkSpecializationMapEntry * pMapEntries
The raw representation of an image passed around by generated Halide code.
uint64_t device
A device-handle for e.g.
const struct halide_device_interface_t * device_interface
The interface used to interpret the above handle.