Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2020-10-02 01:48:01 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2020-10-02 20:26:35 +0300
commitcfa101c22871c3d115f854e23f8b656b1c58a304 (patch)
tree33051b28379c0e23d0948c61ee63d9a95dd45266 /intern/cycles
parent90a27d5aa91a1b6a25ea14e11c889d47f77f4cf7 (diff)
Cycles: Add command line option for overriding the compute device
The current way of setting the compute device makes sense for local use, but for headless rendering it it a massive pain to get Cycles to use the correct device, usually involving entire Python scripts. Therefore, this patch adds a simple command-line option to Blender for specifying the type of device that should be used. If the option is present, the settings in the user preferences and the scene are ignored, and instead all devices matching the specified type are used. Differential Revision: https://developer.blender.org/D9086
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/addon/engine.py9
-rw-r--r--intern/cycles/blender/blender_device.cpp13
-rw-r--r--intern/cycles/blender/blender_python.cpp39
-rw-r--r--intern/cycles/blender/blender_session.cpp1
-rw-r--r--intern/cycles/blender/blender_session.h1
-rw-r--r--intern/cycles/util/util_string.cpp6
-rw-r--r--intern/cycles/util/util_string.h2
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);