| 343 | } |
| 344 | |
| 345 | vulkan_program::vulkan_program(program_map_type&& programs_) : |
| 346 | device_program(retrieve_unique_function_names(programs_)), programs(std::move(programs_)) { |
| 347 | if (programs.empty()) { |
| 348 | return; |
| 349 | } |
| 350 | |
| 351 | // create all functions of all device programs |
| 352 | // note that this essentially reshuffles the program "device -> functions" data to "functions -> devices" |
| 353 | functions.reserve(function_names.size()); |
| 354 | for (const auto& func_name : function_names) { |
| 355 | vulkan_function::function_map_type function_map; |
| 356 | for (auto&& prog : programs) { |
| 357 | if (!prog.second.valid) continue; |
| 358 | |
| 359 | for (const auto& info : prog.second.functions) { |
| 360 | if (info.name == func_name) { |
| 361 | if (should_ignore_function_for_device(*prog.first, info)) { |
| 362 | continue; |
| 363 | } |
| 364 | |
| 365 | auto entry = std::make_shared<vulkan_function_entry>(); |
| 366 | entry->info = &info; |
| 367 | |
| 368 | auto& prog_entry = prog.second; |
| 369 | const auto dev = prog.first; |
| 370 | const auto& vk_dev = (const vulkan_device&)*dev; |
| 371 | |
| 372 | const VkShaderStageFlagBits stage = (info.type == FUNCTION_TYPE::VERTEX ? VK_SHADER_STAGE_VERTEX_BIT : |
| 373 | info.type == FUNCTION_TYPE::FRAGMENT ? VK_SHADER_STAGE_FRAGMENT_BIT : |
| 374 | VK_SHADER_STAGE_COMPUTE_BIT /* should notice anything else earlier */); |
| 375 | |
| 376 | if (!info.has_valid_required_local_size()) { |
| 377 | entry->max_local_size = vk_dev.max_local_size; |
| 378 | |
| 379 | // always assume that we can execute this with the max possible work-group size, |
| 380 | // i.e. use this as the initial default |
| 381 | entry->max_total_local_size = vk_dev.max_total_local_size; |
| 382 | } else { |
| 383 | // a required local size/dim is specified -> use it |
| 384 | entry->max_local_size = info.required_local_size; |
| 385 | entry->max_total_local_size = info.required_local_size.extent(); |
| 386 | } |
| 387 | |
| 388 | if (info.has_valid_required_simd_width()) { |
| 389 | entry->required_simd_width = info.required_simd_width; |
| 390 | } |
| 391 | |
| 392 | // TODO: make sure that _all_ of this is synchronized |
| 393 | if (!create_function_entry_descriptor_buffer(*entry, *dev, stage, func_name, info)) { |
| 394 | continue; |
| 395 | } |
| 396 | |
| 397 | // find SPIR-V module index for this function |
| 398 | const auto mod_iter = prog_entry.func_to_mod_map.find(func_name); |
| 399 | if (mod_iter == prog_entry.func_to_mod_map.end()) { |
| 400 | log_error("did not find a module mapping for function \"$\"", func_name); |
| 401 | continue; |
| 402 | } |
nothing calls this directly
no test coverage detected