diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index 2df605fa047..4e2d4b5fe17 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -88,18 +88,26 @@ BVHLayoutMask OneapiDevice::get_bvh_layout_mask() const bool OneapiDevice::load_kernels(const uint requested_features) { assert(device_queue_); - /* NOTE(@nsirgien): oneAPI can support compilation of kernel code with certain feature set - * with specialization constants, but it hasn't been implemented yet. */ - (void)requested_features; bool is_finished_ok = oneapi_run_test_kernel(device_queue_); if (is_finished_ok == false) { - set_error("oneAPI kernel load: got runtime exception \"" + oneapi_error_string_ + "\""); + set_error("oneAPI test kernel execution: got a runtime exception \"" + oneapi_error_string_ + + "\""); + return false; } else { - VLOG_INFO << "Runtime compilation done for \"" << info.description << "\""; + VLOG_INFO << "Test kernel has been executed successfully for \"" << info.description << "\""; assert(device_queue_); } + + is_finished_ok = oneapi_load_kernels(device_queue_, (const unsigned int)requested_features); + if (is_finished_ok == false) { + set_error("oneAPI kernels loading: got a runtime exception \"" + oneapi_error_string_ + "\""); + } + else { + VLOG_INFO << "Kernels loading (compilation) has been done for \"" << info.description << "\""; + } + return is_finished_ok; } diff --git a/intern/cycles/kernel/device/oneapi/kernel.cpp b/intern/cycles/kernel/device/oneapi/kernel.cpp index 1d1700f036d..7e41f14481b 100644 --- a/intern/cycles/kernel/device/oneapi/kernel.cpp +++ b/intern/cycles/kernel/device/oneapi/kernel.cpp @@ -123,6 +123,52 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue, return std::min(limit_work_group_size, preferred_work_group_size); } +bool oneapi_load_kernels(SyclQueue *queue_, const uint requested_features) +{ + assert(queue_); + sycl::queue *queue = reinterpret_cast(queue_); + + try { + sycl::kernel_bundle all_kernels_bundle = + sycl::get_kernel_bundle(queue->get_context(), + {queue->get_device()}); + + for (const sycl::kernel_id &kernel_id : all_kernels_bundle.get_kernel_ids()) { + const std::string &kernel_name = kernel_id.get_name(); + + /* NOTE(@nsirgien): Names in this conditions below should match names from + * oneapi_call macro in oneapi_enqueue_kernel below */ + if (((requested_features & KERNEL_FEATURE_VOLUME) == 0) && + kernel_name.find("oneapi_kernel_integrator_shade_volume") != std::string::npos) { + continue; + } + + if (((requested_features & KERNEL_FEATURE_MNEE) == 0) && + kernel_name.find("oneapi_kernel_integrator_shade_surface_mnee") != std::string::npos) { + continue; + } + + if (((requested_features & KERNEL_FEATURE_NODE_RAYTRACE) == 0) && + kernel_name.find("oneapi_kernel_integrator_shade_surface_raytrace") != + std::string::npos) { + continue; + } + + sycl::kernel_bundle one_kernel_bundle = + sycl::get_kernel_bundle(queue->get_context(), {kernel_id}); + sycl::build(one_kernel_bundle, {queue->get_device()}, sycl::property::queue::in_order()); + } + } + catch (sycl::exception const &e) { + if (s_error_cb) { + s_error_cb(e.what(), s_error_user_ptr); + } + return false; + } + + return true; +} + bool oneapi_enqueue_kernel(KernelContext *kernel_context, int kernel, size_t global_size, diff --git a/intern/cycles/kernel/device/oneapi/kernel.h b/intern/cycles/kernel/device/oneapi/kernel.h index 7456d0e4902..2bfc0b89c87 100644 --- a/intern/cycles/kernel/device/oneapi/kernel.h +++ b/intern/cycles/kernel/device/oneapi/kernel.h @@ -48,6 +48,8 @@ CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_enqueue_kernel(KernelContext *context, int kernel, size_t global_size, void **args); +CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_load_kernels(SyclQueue *queue, + const unsigned int requested_features); # ifdef __cplusplus } # endif