Changeset View
Changeset View
Standalone View
Standalone View
source/blender/compositor/intern/COM_WorkScheduler.cc
| Show All 33 Lines | |||||
| #include "BLI_threads.h" | #include "BLI_threads.h" | ||||
| #include "BLI_vector.hh" | #include "BLI_vector.hh" | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| namespace blender::compositor { | namespace blender::compositor { | ||||
| enum class ThreadingModel { | using ThreadingModel = WorkScheduler::ThreadingModel; | ||||
| /** Everything is executed in the caller thread. easy for debugging. */ | |||||
| SingleThreaded, | |||||
| /** Multi-threaded model, which uses the BLI_thread_queue pattern. */ | |||||
| Queue, | |||||
| /** Uses BLI_task as threading backend. */ | |||||
| Task | |||||
| }; | |||||
| /** | |||||
| * Returns the active threading model. | |||||
| * | |||||
| * Default is `ThreadingModel::Queue`. | |||||
| */ | |||||
| constexpr ThreadingModel COM_threading_model() | |||||
| { | |||||
| return ThreadingModel::Queue; | |||||
| } | |||||
| /** | |||||
| * Does the active threading model support opencl? | |||||
| */ | |||||
| constexpr bool COM_is_opencl_enabled() | |||||
| { | |||||
| return COM_threading_model() != ThreadingModel::SingleThreaded; | |||||
| } | |||||
| static ThreadLocal(CPUDevice *) g_thread_device; | static ThreadLocal(CPUDevice *) g_thread_device; | ||||
| static struct { | static struct { | ||||
| struct { | struct { | ||||
| /** \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is | /** \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is | ||||
| * created | * created | ||||
| */ | */ | ||||
| Vector<CPUDevice> devices; | Vector<CPUDevice> devices; | ||||
| Show All 17 Lines | struct { | ||||
| * is created. */ | * is created. */ | ||||
| Vector<OpenCLDevice> devices; | Vector<OpenCLDevice> devices; | ||||
| /** \brief list of all thread for every GPUDevice in cpudevices a thread exists. */ | /** \brief list of all thread for every GPUDevice in cpudevices a thread exists. */ | ||||
| ListBase threads; | ListBase threads; | ||||
| /** \brief all scheduled work for the GPU. */ | /** \brief all scheduled work for the GPU. */ | ||||
| bool active = false; | bool active = false; | ||||
| bool initialized = false; | bool initialized = false; | ||||
| } opencl; | } opencl; | ||||
| ThreadingModel threading_model; | |||||
| } g_work_scheduler; | } g_work_scheduler; | ||||
| static ThreadingModel COM_threading_model() | |||||
| { | |||||
| return g_work_scheduler.threading_model; | |||||
| } | |||||
| /** | |||||
| * Does the active threading model support opencl? | |||||
| */ | |||||
| static bool COM_is_opencl_enabled() | |||||
| { | |||||
| return COM_threading_model() != ThreadingModel::SingleThreaded; | |||||
| } | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name OpenCL Scheduling | /** \name OpenCL Scheduling | ||||
| * \{ */ | * \{ */ | ||||
| static void CL_CALLBACK clContextError(const char *errinfo, | static void CL_CALLBACK clContextError(const char *errinfo, | ||||
| const void * /*private_info*/, | const void * /*private_info*/, | ||||
| size_t /*cb*/, | size_t /*cb*/, | ||||
| void * /*user_data*/) | void * /*user_data*/) | ||||
| Show All 27 Lines | static void opencl_start(CompositorContext &context) | ||||
| } | } | ||||
| else { | else { | ||||
| g_work_scheduler.opencl.active = false; | g_work_scheduler.opencl.active = false; | ||||
| } | } | ||||
| } | } | ||||
| static bool opencl_schedule(WorkPackage *package) | static bool opencl_schedule(WorkPackage *package) | ||||
| { | { | ||||
| if (package->execution_group->get_flags().open_cl && g_work_scheduler.opencl.active) { | if (!package->execute_fn && package->execution_group->get_flags().open_cl && g_work_scheduler.opencl.active) { | ||||
| BLI_thread_queue_push(g_work_scheduler.opencl.queue, package); | BLI_thread_queue_push(g_work_scheduler.opencl.queue, package); | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static void opencl_finish() | static void opencl_finish() | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | |||||
| bool WorkScheduler::has_gpu_devices() | bool WorkScheduler::has_gpu_devices() | ||||
| { | { | ||||
| if (COM_is_opencl_enabled()) { | if (COM_is_opencl_enabled()) { | ||||
| return opencl_has_gpu_devices(); | return opencl_has_gpu_devices(); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads) | void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads, ThreadingModel model) | ||||
| { | { | ||||
| g_work_scheduler.threading_model = model; | |||||
| if (COM_is_opencl_enabled()) { | if (COM_is_opencl_enabled()) { | ||||
| opencl_initialize(use_opencl); | opencl_initialize(use_opencl); | ||||
| } | } | ||||
| switch (COM_threading_model()) { | switch (COM_threading_model()) { | ||||
| case ThreadingModel::SingleThreaded: | case ThreadingModel::SingleThreaded: | ||||
| /* Nothing to do. */ | /* Nothing to do. */ | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines | |||||