diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 9 | ||||
-rw-r--r-- | intern/cycles/blender/blender_device.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 39 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.h | 1 | ||||
-rw-r--r-- | intern/cycles/util/util_string.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/util/util_string.h | 2 |
7 files changed, 67 insertions, 4 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 54221d3f1e0..807dcaf7f43 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -70,6 +70,11 @@ def _configure_argument_parser(): parser.add_argument("--cycles-print-stats", help="Print rendering statistics to stderr", action='store_true') + parser.add_argument("--cycles-device", + help="Set the device to use for Cycles, overriding user preferences and the scene setting." + "Valid options are 'CPU', 'CUDA', 'OPTIX' or 'OPENCL'." + "Additionally, you can append '+CPU' to any GPU type for hybrid rendering.", + default=None) return parser @@ -102,6 +107,10 @@ def _parse_command_line(): import _cycles _cycles.enable_print_stats() + if args.cycles_device: + import _cycles + _cycles.set_device_override(args.cycles_device) + def init(): import bpy diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp index fb9ab9e8c97..0293223864d 100644 --- a/intern/cycles/blender/blender_device.cpp +++ b/intern/cycles/blender/blender_device.cpp @@ -15,6 +15,7 @@ */ #include "blender/blender_device.h" +#include "blender/blender_session.h" #include "blender/blender_util.h" #include "util/util_foreach.h" @@ -42,6 +43,18 @@ int blender_device_threads(BL::Scene &b_scene) DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background) { + if (BlenderSession::device_override != DEVICE_MASK_ALL) { + vector<DeviceInfo> devices = Device::available_devices(BlenderSession::device_override); + + if (devices.empty()) { + printf("Found no Cycles device of the specified type, falling back to CPU...\n"); + return Device::available_devices(DEVICE_MASK_CPU).front(); + } + + int threads = blender_device_threads(b_scene); + return Device::get_multi_device(devices, threads, background); + } + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); /* Default to CPU device. */ diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 25c77b74ce3..65337d1ba4f 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -968,6 +968,44 @@ static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/) return list; } +static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg) +{ + PyObject *override_string = PyObject_Str(arg); + string override = PyUnicode_AsUTF8(override_string); + Py_DECREF(override_string); + + bool include_cpu = false; + const string cpu_suffix = "+CPU"; + if (string_endswith(override, cpu_suffix)) { + include_cpu = true; + override = override.substr(0, override.length() - cpu_suffix.length()); + } + + if (override == "CPU") { + BlenderSession::device_override = DEVICE_MASK_CPU; + } + else if (override == "OPENCL") { + BlenderSession::device_override = DEVICE_MASK_OPENCL; + } + else if (override == "CUDA") { + BlenderSession::device_override = DEVICE_MASK_CUDA; + } + else if (override == "OPTIX") { + BlenderSession::device_override = DEVICE_MASK_OPTIX; + } + else { + printf("\nError: %s is not a valid Cycles device.\n", override.c_str()); + Py_RETURN_FALSE; + } + + if (include_cpu) { + BlenderSession::device_override = (DeviceTypeMask)(BlenderSession::device_override | + DEVICE_MASK_CPU); + } + + Py_RETURN_TRUE; +} + static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, {"exit", exit_func, METH_VARARGS, ""}, @@ -1007,6 +1045,7 @@ static PyMethodDef methods[] = { /* Compute Device selection */ {"get_device_types", get_device_types_func, METH_VARARGS, ""}, + {"set_device_override", set_device_override_func, METH_O, ""}, {NULL, NULL, 0, NULL}, }; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 8e962f17f56..c2bdec0e53d 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -47,6 +47,7 @@ CCL_NAMESPACE_BEGIN +DeviceTypeMask BlenderSession::device_override = DEVICE_MASK_ALL; bool BlenderSession::headless = false; int BlenderSession::num_resumable_chunks = 0; int BlenderSession::current_resumable_chunk = 0; diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 34e952e312b..68db8a2fb58 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -126,6 +126,7 @@ class BlenderSession { /* Global state which is common for all render sessions created from Blender. * Usually denotes command line arguments. */ + static DeviceTypeMask device_override; /* Blender is running from the command line, no windows are shown and some * extra render optimization is possible (possible to free draw-only data and diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index afcca7e0411..4dfebf14923 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -117,14 +117,14 @@ bool string_startswith(const string &s, const char *start) return strncmp(s.c_str(), start, len) == 0; } -bool string_endswith(const string &s, const char *end) +bool string_endswith(const string &s, const string &end) { - size_t len = strlen(end); + size_t len = end.length(); if (len > s.size()) return 0; else - return strncmp(s.c_str() + s.size() - len, end, len) == 0; + return s.compare(s.length() - len, len, end) == 0; } string string_strip(const string &s) diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h index ce2d4acdde4..f51aa7111e8 100644 --- a/intern/cycles/util/util_string.h +++ b/intern/cycles/util/util_string.h @@ -46,7 +46,7 @@ void string_split(vector<string> &tokens, bool skip_empty_tokens = true); void string_replace(string &haystack, const string &needle, const string &other); bool string_startswith(const string &s, const char *start); -bool string_endswith(const string &s, const char *end); +bool string_endswith(const string &s, const string &end); string string_strip(const string &s); string string_remove_trademark(const string &s); string string_from_bool(const bool var); |