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";
105 int 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";
123 int vk_create_command_buffer(
void *user_context,
VulkanMemoryAllocator *allocator, VkCommandPool command_pool, VkCommandBuffer *command_buffer) {
126 <<
" vk_create_command_buffer (user_context: " << user_context <<
", "
127 <<
"allocator: " << (
void *)allocator <<
", "
128 <<
"command_pool: " << (
void *)command_pool <<
")\n";
130 if (allocator ==
nullptr) {
131 error(user_context) <<
"Vulkan: Failed to create command buffer ... invalid allocator pointer!\n";
146 error(user_context) <<
"Vulkan: Failed to allocate command buffers!\n";
152 int vk_destroy_command_buffer(
void *user_context,
VulkanMemoryAllocator *allocator, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
155 <<
" vk_destroy_command_buffer (user_context: " << user_context <<
", "
156 <<
"allocator: " << (
void *)allocator <<
", "
157 <<
"command_pool: " << (
void *)command_pool <<
", "
158 <<
"command_buffer: " << (
void *)command_buffer <<
")\n";
160 if (allocator ==
nullptr) {
161 error(user_context) <<
"Vulkan: Failed to destroy command buffer ... invalid allocator pointer!\n";
169 int vk_fill_command_buffer_with_dispatch_call(
void *user_context,
171 VkCommandBuffer command_buffer,
172 VkPipeline compute_pipeline,
173 VkPipelineLayout pipeline_layout,
174 VkDescriptorSet descriptor_set,
176 int blocksX,
int blocksY,
int blocksZ) {
180 <<
" vk_fill_command_buffer_with_dispatch_call (user_context: " << user_context <<
", "
181 <<
"device: " << (
void *)device <<
", "
182 <<
"command_buffer: " << (
void *)command_buffer <<
", "
183 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
", "
184 <<
"descriptor_set: " << (
void *)descriptor_set <<
", "
185 <<
"descriptor_set_index: " << descriptor_set_index <<
", "
186 <<
"blocks: " << blocksX <<
", " << blocksY <<
", " << blocksZ <<
")\n";
198 error(user_context) <<
"vkBeginCommandBuffer returned " << vk_get_error_name(result) <<
"\n";
204 descriptor_set_index, 1, &descriptor_set, 0,
nullptr);
209 error(user_context) <<
"vkEndCommandBuffer returned " << vk_get_error_name(result) <<
"\n";
216 int vk_submit_command_buffer(
void *user_context, VkQueue queue, VkCommandBuffer command_buffer) {
219 <<
" vk_submit_command_buffer (user_context: " << user_context <<
", "
220 <<
"queue: " << (
void *)queue <<
", "
221 <<
"command_buffer: " << (
void *)command_buffer <<
")\n";
239 error(user_context) <<
"Vulkan: vkQueueSubmit returned " << vk_get_error_name(result) <<
"\n";
247 bool vk_needs_scalar_uniform_buffer(
void *user_context,
252 while (arg_sizes[i] > 0) {
253 if (!arg_is_buffer[i]) {
261 uint32_t vk_count_bindings_for_descriptor_set(
void *user_context,
267 uint32_t bindings_count = vk_needs_scalar_uniform_buffer(user_context, arg_sizes, args, arg_is_buffer);
270 while (arg_sizes[i] > 0) {
271 if (arg_is_buffer[i]) {
276 return bindings_count;
281 int vk_create_descriptor_pool(
void *user_context,
285 VkDescriptorPool *descriptor_pool) {
288 <<
" vk_create_descriptor_pool (user_context: " << user_context <<
", "
289 <<
"allocator: " << (
void *)allocator <<
", "
290 <<
"uniform_buffer_count: " << (
uint32_t)uniform_buffer_count <<
", "
291 <<
"storage_buffer_count: " << (
uint32_t)storage_buffer_count <<
")\n";
293 if (allocator ==
nullptr) {
294 error(user_context) <<
"Vulkan: Failed to create descriptor pool ... invalid allocator pointer!\n";
300 pool_config.
minimum_capacity = (uniform_buffer_count ? 1 : 0) + (storage_buffer_count ? 1 : 0);
304 if (uniform_buffer_count > 0) {
309 pool_sizes.
append(user_context, &uniform_buffer_size);
312 if (storage_buffer_count > 0) {
317 pool_sizes.
append(user_context, &storage_buffer_size);
331 error(user_context) <<
"Vulkan: Failed to create descriptor pool! vkCreateDescriptorPool returned " << vk_get_error_name(result) <<
"\n";
337 int vk_destroy_descriptor_pool(
void *user_context,
339 VkDescriptorPool descriptor_pool) {
342 <<
" vk_destroy_descriptor_pool (user_context: " << user_context <<
", "
343 <<
"allocator: " << (
void *)allocator <<
", "
344 <<
"descriptor_pool: " << (
void *)descriptor_pool <<
")\n";
346 if (allocator ==
nullptr) {
347 error(user_context) <<
"Vulkan: Failed to destroy descriptor pool ... invalid allocator pointer!\n";
356 int vk_create_descriptor_set_layout(
void *user_context,
360 VkDescriptorSetLayout *layout) {
364 <<
" vk_create_descriptor_set_layout (user_context: " << user_context <<
", "
365 <<
"allocator: " << (
void *)allocator <<
", "
366 <<
"uniform_buffer_count: " << uniform_buffer_count <<
", "
367 <<
"storage_buffer_count: " << storage_buffer_count <<
", "
368 <<
"layout: " << (
void *)layout <<
")\n";
370 if (allocator ==
nullptr) {
371 error(user_context) <<
"Vulkan: Failed to create descriptor set layout ... invalid allocator pointer!\n";
377 layout_config.
minimum_capacity = uniform_buffer_count + storage_buffer_count;
378 BlockStorage layout_bindings(user_context, layout_config);
381 for (
uint32_t n = 0; n < uniform_buffer_count; ++n) {
392 <<
" [" << (
uint32_t)layout_bindings.
size() <<
"] : UNIFORM_BUFFER\n";
395 layout_bindings.
append(user_context, &uniform_buffer_layout);
399 for (
uint32_t n = 0; n < storage_buffer_count; ++n) {
411 <<
" [" << (
uint32_t)layout_bindings.
size() <<
"] : STORAGE_BUFFER\n";
414 layout_bindings.
append(user_context, &storage_buffer_layout);
429 error(user_context) <<
"vkCreateDescriptorSetLayout returned " << vk_get_error_name(result) <<
"\n";
436 int vk_destroy_descriptor_set_layout(
void *user_context,
438 VkDescriptorSetLayout descriptor_set_layout) {
442 <<
" vk_destroy_descriptor_set_layout (user_context: " << user_context <<
", "
443 <<
"allocator: " << (
void *)allocator <<
", "
444 <<
"layout: " << (
void *)descriptor_set_layout <<
")\n";
446 if (allocator ==
nullptr) {
447 error(user_context) <<
"Vulkan: Failed to destroy descriptor set layout ... invalid allocator pointer!\n";
456 int vk_create_descriptor_set(
void *user_context,
458 VkDescriptorSetLayout descriptor_set_layout,
459 VkDescriptorPool descriptor_pool,
460 VkDescriptorSet *descriptor_set) {
463 <<
" vk_create_descriptor_set (user_context: " << user_context <<
", "
464 <<
"allocator: " << (
void *)allocator <<
", "
465 <<
"descriptor_set_layout: " << (
void *)descriptor_set_layout <<
", "
466 <<
"descriptor_pool: " << (
void *)descriptor_pool <<
")\n";
468 if (allocator ==
nullptr) {
469 error(user_context) <<
"Vulkan: Failed to create descriptor set ... invalid allocator pointer!\n";
479 &descriptor_set_layout
484 error(user_context) <<
"Vulkan: vkAllocateDescriptorSets returned " << vk_get_error_name(result) <<
"\n";
491 int vk_update_descriptor_set(
void *user_context,
493 VkBuffer *scalar_args_buffer,
494 size_t uniform_buffer_count,
495 size_t storage_buffer_count,
499 VkDescriptorSet descriptor_set) {
502 <<
" vk_update_descriptor_set (user_context: " << user_context <<
", "
503 <<
"allocator: " << (
void *)allocator <<
", "
504 <<
"scalar_args_buffer: " << (
void *)scalar_args_buffer <<
", "
505 <<
"uniform_buffer_count: " << (
uint32_t)uniform_buffer_count <<
", "
506 <<
"storage_buffer_count: " << (
uint32_t)storage_buffer_count <<
", "
507 <<
"descriptor_set: " << (
void *)descriptor_set <<
")\n";
509 if (allocator ==
nullptr) {
510 error(user_context) <<
"Vulkan: Failed to create descriptor set ... invalid allocator pointer!\n";
517 BlockStorage descriptor_buffer_info(user_context, dbi_config);
522 BlockStorage write_descriptor_set(user_context, wds_config);
526 if (scalar_args_buffer !=
nullptr) {
532 descriptor_buffer_info.
append(user_context, &scalar_args_descriptor_buffer_info);
536 debug(user_context) <<
" [" << (
uint32_t)write_descriptor_set.
size() <<
"] UNIFORM_BUFFER : "
537 <<
"buffer=" << (
void *)scalar_args_buffer <<
" "
538 <<
"offset=" << (
uint32_t)(0) <<
" "
539 <<
"size=VK_WHOLE_SIZE\n";
553 write_descriptor_set.
append(user_context, &uniform_buffer_write_descriptor_set);
557 for (
size_t i = 0; arg_sizes[i] > 0; i++) {
558 if (arg_is_buffer[i]) {
565 VkBuffer *device_buffer =
reinterpret_cast<VkBuffer *
>(owner->
handle);
566 if (device_buffer ==
nullptr) {
567 error(user_context) <<
"Vulkan: Failed to retrieve buffer for device memory!\n";
579 descriptor_buffer_info.
append(user_context, &device_buffer_info);
583 debug(user_context) <<
" [" << (
uint32_t)write_descriptor_set.
size() <<
"] STORAGE_BUFFER : "
584 <<
"region=" << (
void *)device_region <<
" "
585 <<
"buffer=" << (
void *)device_buffer <<
" "
586 <<
"offset=" << (
uint32_t)(range_offset) <<
" "
587 <<
"size=" << (
uint32_t)(range_size) <<
"\n";
602 write_descriptor_set.
append(user_context, &storage_buffer_write_descriptor_set);
613 size_t vk_estimate_scalar_uniform_buffer_size(
void *user_context,
618 int scalar_uniform_buffer_size = 0;
619 while (arg_sizes[i] > 0) {
620 if (!arg_is_buffer[i]) {
621 scalar_uniform_buffer_size += arg_sizes[i];
625 return scalar_uniform_buffer_size;
628 MemoryRegion *vk_create_scalar_uniform_buffer(
void *user_context,
630 size_t scalar_buffer_size) {
634 <<
" vk_create_scalar_uniform_buffer (user_context: " << user_context <<
", "
635 <<
"allocator: " << (
void *)allocator <<
", "
636 <<
"scalar_buffer_size: " << (
uint32_t)scalar_buffer_size <<
")\n";
639 if (allocator ==
nullptr) {
640 error(user_context) <<
"Vulkan: Failed to create scalar uniform buffer ... invalid allocator pointer!\n";
645 request.
size = scalar_buffer_size;
652 if ((region ==
nullptr) || (region->
handle ==
nullptr)) {
653 error(user_context) <<
"Vulkan: Failed to create scalar uniform buffer ... unable to allocate device memory!\n";
661 int vk_update_scalar_uniform_buffer(
void *user_context,
670 <<
" vk_update_scalar_uniform_buffer (user_context: " << user_context <<
", "
671 <<
"region: " << (
void *)region <<
")\n";
674 if (allocator ==
nullptr) {
675 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... invalid allocator pointer!\n";
679 if ((region ==
nullptr) || (region->
handle ==
nullptr)) {
680 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... invalid memory region!\n";
686 if (host_ptr ==
nullptr) {
687 error(user_context) <<
"Vulkan: Failed to update scalar uniform buffer ... unable to map host pointer to device memory!\n";
692 size_t arg_offset = 0;
693 for (
size_t i = 0; arg_sizes[i] > 0; i++) {
694 if (!arg_is_buffer[i]) {
695 memcpy(host_ptr + arg_offset, args[i], arg_sizes[i]);
696 arg_offset += arg_sizes[i];
701 allocator->
unmap(user_context, region);
710 <<
" vk_destroy_scalar_uniform_buffer (user_context: " << user_context <<
", "
711 <<
"allocator: " << (
void *)allocator <<
", "
712 <<
"scalar_args_region: " << (
void *)scalar_args_region <<
")\n";
714 if (allocator ==
nullptr) {
715 error(user_context) <<
"Vulkan: Failed to destroy scalar uniform buffer ... invalid allocator pointer!\n";
719 if (!scalar_args_region) {
725 error_code = allocator->
release(user_context, scalar_args_region);
727 error_code = allocator->
reclaim(user_context, scalar_args_region);
734 int vk_create_pipeline_layout(
void *user_context,
737 VkDescriptorSetLayout *descriptor_set_layouts,
738 VkPipelineLayout *pipeline_layout) {
742 <<
" vk_create_pipeline_layout (user_context: " << user_context <<
", "
743 <<
"allocator: " << (
void *)allocator <<
", "
744 <<
"descriptor_set_count: " << descriptor_set_count <<
", "
745 <<
"descriptor_set_layouts: " << (
void *)descriptor_set_layouts <<
", "
746 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
748 if (allocator ==
nullptr) {
749 error(user_context) <<
"Vulkan: Failed to create pipeline layout ... invalid allocator pointer!\n";
757 descriptor_set_count,
758 descriptor_set_layouts,
765 error(user_context) <<
"Vulkan: vkCreatePipelineLayout returned " << vk_get_error_name(result) <<
"\n";
771 int vk_destroy_pipeline_layout(
void *user_context,
773 VkPipelineLayout pipeline_layout) {
777 <<
" vk_destroy_pipeline_layout (user_context: " << user_context <<
", "
778 <<
"allocator: " << (
void *)allocator <<
", "
779 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
782 if (allocator ==
nullptr) {
783 error(user_context) <<
"Vulkan: Failed to destroy pipeline layout ... invalid allocator pointer!\n";
793 int vk_create_compute_pipeline(
void *user_context,
795 const char *pipeline_name,
796 VkShaderModule shader_module,
797 VkPipelineLayout pipeline_layout,
799 VkPipeline *compute_pipeline) {
803 <<
" vk_create_compute_pipeline (user_context: " << user_context <<
", "
804 <<
"allocator: " << (
void *)allocator <<
", "
805 <<
"shader_module: " << (
void *)shader_module <<
", "
806 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
808 if (allocator ==
nullptr) {
809 error(user_context) <<
"Vulkan: Failed to create compute pipeline ... invalid allocator pointer!\n";
835 error(user_context) <<
"Vulkan: Failed to create compute pipeline! vkCreateComputePipelines returned " << vk_get_error_name(result) <<
"\n";
842 int vk_setup_compute_pipeline(
void *user_context,
846 VkShaderModule shader_module,
847 VkPipelineLayout pipeline_layout,
848 VkPipeline *compute_pipeline) {
852 <<
" vk_setup_compute_pipeline (user_context: " << user_context <<
", "
854 <<
"allocator: " << (
void *)allocator <<
", "
855 <<
"shader_bindings: " << (
void *)shader_bindings <<
", "
856 <<
"dispatch_data: " << (
void *)dispatch_data <<
", "
857 <<
"shader_module: " << (
void *)shader_module <<
", "
858 <<
"pipeline_layout: " << (
void *)pipeline_layout <<
")\n";
861 if (allocator ==
nullptr) {
862 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid allocator pointer!\n";
866 if (shader_bindings ==
nullptr) {
867 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid shader bindings!\n";
871 if (shader_bindings ==
nullptr) {
872 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... invalid dispatch data!\n";
878 if (entry_point_name ==
nullptr) {
879 error(user_context) <<
"Vulkan: Failed to setup compute pipeline ... missing entry point name!\n";
883 uint32_t dispatch_constant_index = 0;
884 uint32_t dispatch_constant_ids[4] = {0, 0, 0, 0};
885 uint32_t dispatch_constant_values[4] = {0, 0, 0, 0};
890 uint32_t shared_mem_constant_id = 0;
891 uint32_t static_shared_mem_bytes = 0;
901 if (shared_mem_constant_id > 0) {
902 error(user_context) <<
"Vulkan: Multiple dynamic shared memory allocations found! Only one is suported!!\n";
907 shared_mem_type_size = allocation->
type_size;
911 debug(user_context) <<
" pipeline uses " << static_shared_mem_bytes <<
" bytes of static shared memory\n";
912 debug(user_context) <<
" dispatch requests " << dispatch_data->
shared_mem_bytes <<
" bytes of shared memory\n";
913 debug(user_context) <<
" dynamic shared memory " << shared_mem_bytes_avail <<
" bytes available\n";
916 if ((shared_mem_constant_id > 0) && (shared_mem_bytes_avail > 0)) {
917 uint32_t dynamic_array_size = (
uint32_t)shared_mem_bytes_avail / shared_mem_type_size;
918 debug(user_context) <<
" setting shared memory to " << (
uint32_t)dynamic_array_size <<
" elements "
919 <<
"(or " << (
uint32_t)shared_mem_bytes_avail <<
" bytes)\n";
922 dispatch_constant_ids[dispatch_constant_index] = shared_mem_constant_id;
923 dispatch_constant_values[dispatch_constant_index] = dynamic_array_size;
924 dispatch_constant_index++;
930 for (
uint32_t dim = 0; dim < 3; dim++) {
932 dispatch_constant_values[dispatch_constant_index] = dispatch_data->
local_size[dim];
933 dispatch_constant_index++;
938 for (
uint32_t dc = 0; dc < dispatch_constant_index; dc++) {
940 uint32_t found_index = invalid_index;
943 debug(user_context) <<
" binding specialization constant [" << dispatch_constant_ids[dc] <<
"] "
945 <<
" => " << dispatch_constant_values[dc] <<
"\n";
950 if (found_index == invalid_index) {
951 error(user_context) <<
"Vulkan: Failed to locate dispatch constant index for shader binding!\n";
958 error(user_context) <<
"Vulkan: Failed to decode shader bindings! " << vk_get_error_name(result) <<
"\n";
963 uint32_t dispatch_constant_count = 0;
966 for (
uint32_t dc = 0; dc < dispatch_constant_index && dc < 4; dc++) {
967 specialization_map_entries[dc].
constantID = dispatch_constant_ids[dc];
970 dispatch_constant_count++;
973 if (dispatch_constant_count > 0) {
979 specialization_info.
pMapEntries = specialization_map_entries;
980 specialization_info.
pData = dispatch_constant_values;
984 int error_code = vk_destroy_compute_pipeline(user_context, allocator, shader_bindings->
compute_pipeline);
986 error(user_context) <<
"Vulkan: Failed to destroy compute pipeline!\n";
992 int error_code = vk_create_compute_pipeline(user_context, allocator, entry_point_name, shader_module, pipeline_layout, &specialization_info, &(shader_bindings->
compute_pipeline));
994 error(user_context) <<
"Vulkan: Failed to create compute pipeline!\n";
1002 int error_code = vk_create_compute_pipeline(user_context, allocator, entry_point_name, shader_module, pipeline_layout,
nullptr, &(shader_bindings->
compute_pipeline));
1004 error(user_context) <<
"Vulkan: Failed to create compute pipeline!\n";
1013 int vk_destroy_compute_pipeline(
void *user_context,
1015 VkPipeline compute_pipeline) {
1016 #ifdef DEBUG_RUNTIME
1018 <<
" vk_destroy_compute_pipeline (user_context: " << user_context <<
", "
1019 <<
"allocator: " << (
void *)allocator <<
", "
1021 <<
"compute_pipeline: " << (
void *)compute_pipeline <<
")\n";
1023 if (allocator ==
nullptr) {
1024 error(user_context) <<
"Vulkan: Failed to destroy compute pipeline ... invalid allocator pointer!\n";
1035 #ifdef DEBUG_RUNTIME
1037 <<
" vk_decode_shader_bindings (user_context: " << user_context <<
", "
1038 <<
"allocator: " << (
void *)allocator <<
", "
1039 <<
"module_ptr: " << (
void *)module_ptr <<
", "
1040 <<
"module_size: " << module_size <<
")\n";
1045 if (allocator ==
nullptr) {
1046 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... invalid allocator pointer!\n";
1050 if ((module_ptr ==
nullptr) || (module_size < (2 *
sizeof(
uint32_t)))) {
1051 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... invalid module buffer!\n";
1097 uint32_t shader_count = module_ptr[idx++];
1098 if (shader_count < 1) {
1099 error(user_context) <<
"Vulkan: Failed to decode shader bindings ... no descriptors found!\n";
1107 if (shader_bindings ==
nullptr) {
1108 error(user_context) <<
"Vulkan: Failed to allocate shader_bindings! Out of memory!\n";
1111 memset(shader_bindings, 0, shader_bindings_size);
1114 for (
uint32_t n = 0; (n < shader_count) && (idx < module_entries); n++) {
1118 uint32_t entry_point_name_length = module_ptr[idx++];
1121 const char *entry_point_name = (
const char *)(module_ptr + idx);
1122 idx += entry_point_name_length;
1125 uint32_t uniform_buffer_count = module_ptr[idx++];
1128 uint32_t storage_buffer_count = module_ptr[idx++];
1131 uint32_t specialization_constants_count = module_ptr[idx++];
1135 if (specialization_constants_count > 0) {
1140 if (specialization_constants ==
nullptr) {
1141 error(user_context) <<
"Vulkan: Failed to allocate specialization_constants! Out of memory!\n";
1144 memset(specialization_constants, 0, specialization_constants_size);
1147 for (
uint32_t sc = 0; sc < specialization_constants_count; sc++) {
1151 uint32_t constant_name_length = module_ptr[idx++];
1154 const char *constant_name = (
const char *)(module_ptr + idx);
1155 specialization_constants[sc].constant_name = constant_name;
1156 idx += constant_name_length;
1159 specialization_constants[sc].constant_id = module_ptr[idx++];
1162 specialization_constants[sc].type_size = module_ptr[idx++];
1167 uint32_t shared_memory_allocations_count = module_ptr[idx++];
1171 if (shared_memory_allocations_count > 0) {
1176 if (shared_memory_allocations ==
nullptr) {
1177 error(user_context) <<
"Vulkan: Failed to allocate shared_memory_allocations! Out of memory!\n";
1180 memset(shared_memory_allocations, 0, shared_memory_allocations_size);
1183 for (
uint32_t sm = 0; sm < shared_memory_allocations_count && (idx < module_entries); sm++) {
1187 uint32_t variable_name_length = module_ptr[idx++];
1190 const char *variable_name = (
const char *)(module_ptr + idx);
1191 shared_memory_allocations[sm].variable_name = variable_name;
1192 idx += variable_name_length;
1195 shared_memory_allocations[sm].constant_id = module_ptr[idx++];
1198 shared_memory_allocations[sm].type_size = module_ptr[idx++];
1201 shared_memory_allocations[sm].array_size = module_ptr[idx++];
1207 for (
uint32_t dim = 0; dim < 3 && (idx < module_entries); dim++) {
1208 shader_bindings[n].dispatch_data.local_size_binding.constant_id[dim] = module_ptr[idx++];
1211 #ifdef DEBUG_RUNTIME
1213 debug(user_context) <<
" [" << n <<
"] '" << (
const char *)entry_point_name <<
"'\n";
1215 debug(user_context) <<
" uniform_buffer_count=" << uniform_buffer_count <<
"\n"
1216 <<
" storage_buffer_count=" << storage_buffer_count <<
"\n";
1218 debug(user_context) <<
" specialization_constants_count=" << specialization_constants_count <<
"\n";
1219 for (
uint32_t sc = 0; sc < specialization_constants_count; sc++) {
1220 debug(user_context) <<
" [" << sc <<
"] "
1221 <<
"constant_name='" << (
const char *)specialization_constants[sc].constant_name <<
"' "
1222 <<
"constant_id=" << specialization_constants[sc].constant_id <<
" "
1223 <<
"type_size=" << specialization_constants[sc].type_size <<
"\n";
1226 debug(user_context) <<
" shared_memory_allocations_count=" << shared_memory_allocations_count <<
"\n";
1227 for (
uint32_t sm = 0; sm < shared_memory_allocations_count; sm++) {
1228 debug(user_context) <<
" [" << sm <<
"] "
1229 <<
"variable_name='" << (
const char *)shared_memory_allocations[sm].variable_name <<
"' "
1230 <<
"constant_id=" << shared_memory_allocations[sm].constant_id <<
" "
1231 <<
"type_size=" << shared_memory_allocations[sm].type_size <<
" "
1232 <<
"array_size=" << shared_memory_allocations[sm].array_size <<
"\n";
1234 debug(user_context) <<
" local_size_binding=[";
1235 for (
uint32_t dim = 0; dim < 3 && (idx < module_entries); dim++) {
1236 debug(user_context) << shader_bindings[n].dispatch_data.local_size_binding.
constant_id[dim] <<
" ";
1238 debug(user_context) <<
"]\n";
1240 shader_bindings[n].entry_point_name = entry_point_name;
1241 shader_bindings[n].uniform_buffer_count = uniform_buffer_count;
1242 shader_bindings[n].storage_buffer_count = storage_buffer_count;
1243 shader_bindings[n].specialization_constants_count = specialization_constants_count;
1244 shader_bindings[n].specialization_constants = specialization_constants;
1245 shader_bindings[n].shared_memory_allocations_count = shared_memory_allocations_count;
1246 shader_bindings[n].shared_memory_allocations = shared_memory_allocations;
1249 #ifdef DEBUG_RUNTIME
1251 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1254 return shader_bindings;
1258 const char *ptr,
int size) {
1259 #ifdef DEBUG_RUNTIME
1261 <<
" vk_compile_shader_module (user_context: " << user_context <<
", "
1262 <<
"allocator: " << (
void *)allocator <<
", "
1264 <<
"module: " << (
void *)ptr <<
", "
1265 <<
"size: " << size <<
")\n";
1270 if (allocator ==
nullptr) {
1271 error(user_context) <<
"Vulkan: Failed to compile shader modules ... invalid allocator pointer!\n";
1275 if ((ptr ==
nullptr) || (size <= 0)) {
1276 error(user_context) <<
"Vulkan: Failed to compile shader modules ... invalid program source buffer!\n";
1286 uint32_t header_word_count = module_ptr[0];
1287 uint32_t shader_count = module_ptr[1];
1291 const uint32_t *binary_ptr = (module_ptr + header_word_count);
1292 size_t binary_size = (size - header_size);
1294 #ifdef DEBUG_RUNTIME
1295 debug(user_context) <<
"Vulkan: Decoding module ("
1296 <<
"module_ptr: " << (
void *)module_ptr <<
", "
1297 <<
"header_word_count: " << header_word_count <<
", "
1298 <<
"header_size: " << header_size <<
", "
1299 <<
"binar_ptr: " << (
void *)binary_ptr <<
", "
1300 <<
"binary_size: " << (
uint32_t)binary_size <<
")\n";
1313 if (cache_entry ==
nullptr) {
1314 error(user_context) <<
"Vulkan: Failed to allocate compilation cache entry! Out of memory!\n";
1320 VulkanShaderBinding *decoded_bindings = vk_decode_shader_bindings(user_context, allocator, module_ptr, module_size);
1321 if (decoded_bindings ==
nullptr) {
1322 error(user_context) <<
"Vulkan: Failed to decode shader bindings!\n";
1332 error(user_context) <<
"Vulkan: vkCreateShaderModule Failed! Error returned: " << vk_get_error_name(result) <<
"\n";
1334 vk_host_free(user_context, cache_entry, allocator->
callbacks());
1342 error(user_context) <<
"Vulkan: Failed to allocate descriptor set layouts for cache entry! Out of memory!\n";
1348 #ifdef DEBUG_RUNTIME
1350 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1358 #ifdef DEBUG_RUNTIME
1360 <<
" vk_destroy_shader_modules (user_context: " << user_context <<
", "
1361 <<
"allocator: " << (
void *)allocator <<
", "
1367 if (allocator ==
nullptr) {
1368 error(user_context) <<
"Vulkan: Failed to destroy shader modules ... invalid allocator pointer!\n";
1373 struct DestroyShaderModule {
1374 void *user_context =
nullptr;
1378 : user_context(ctx), allocator(allocator) {
1382 if (cache_entry !=
nullptr) {
1393 debug(user_context) <<
" destroying pipeline layout " << (
void *)cache_entry->
pipeline_layout <<
"\n";
1394 vk_destroy_pipeline_layout(user_context, allocator, cache_entry->
pipeline_layout);
1425 debug(user_context) <<
" . destroying shader module " << (
void *)cache_entry->
shader_module <<
"\n";
1430 vk_host_free(user_context, cache_entry, allocator->
callbacks());
1431 cache_entry =
nullptr;
1436 DestroyShaderModule module_destructor(user_context, allocator);
1439 #ifdef DEBUG_RUNTIME
1441 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1448 int vk_do_multidimensional_copy(
void *user_context, VkCommandBuffer command_buffer,
1450 int d,
bool from_host,
bool to_host) {
1453 if ((!from_host && to_host) ||
1454 (from_host && !to_host) ||
1455 (!from_host && !to_host)) {
1463 VkBuffer *src_buffer =
reinterpret_cast<VkBuffer *
>(c.
src);
1464 VkBuffer *dst_buffer =
reinterpret_cast<VkBuffer *
>(c.
dst);
1465 if (!src_buffer || !dst_buffer) {
1466 error(user_context) <<
"Vulkan: Failed to retrieve buffer for device memory!\n";
1470 vkCmdCopyBuffer(command_buffer, *src_buffer, *dst_buffer, 1, &buffer_copy);
1472 }
else if ((c.
dst + dst_offset) != (c.
src + src_offset)) {
1483 int err = vk_do_multidimensional_copy(user_context, command_buffer, c,
1484 src_offset + src_off,
1485 dst_offset + dst_off,
1486 d - 1, from_host, to_host);
1497 int vk_device_crop_from_offset(
void *user_context,
1504 error(user_context) <<
"Vulkan: Failed to acquire context!\n";
1508 #ifdef DEBUG_RUNTIME
1513 error(user_context) <<
"Vulkan: Invalid offset for device crop!\n";
1519 if (device_region ==
nullptr) {
1520 error(user_context) <<
"Vulkan: Failed to crop region! Invalide device region!\n";
1526 if ((cropped_region ==
nullptr) || (cropped_region->
handle ==
nullptr)) {
1527 error(user_context) <<
"Vulkan: Failed to crop region! Unable to create memory region!\n";
1532 dst->device = (
uint64_t)cropped_region;
1535 #ifdef DEBUG_RUNTIME
1537 debug(user_context) <<
" Time: " << (t_after - t_before) / 1.0e6 <<
" ms\n";
1551 #endif // HALIDE_RUNTIME_VULKAN_RESOURCES_H