Cycles: abort rendering when --cycles-device not found

Rather than just printing a message and falling back to the CPU. For render
farms it's better to avoid a potentially slow render on the CPU if the intent
was to render on the GPU.

Ref T82193, D9086
This commit is contained in:
Brecht Van Lommel 2020-10-28 19:55:41 +01:00
parent 09be2a8358
commit f75b09e7e6
Notes: blender-bot 2023-02-14 06:23:08 +01:00
Referenced by issue #82193, Cycles regression testing for GPU devices
8 changed files with 129 additions and 27 deletions

View File

@ -47,8 +47,7 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
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();
return Device::dummy_device("Found no Cycles device of the specified type");
}
int threads = blender_device_threads(b_scene);

View File

@ -472,6 +472,11 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
{
b_depsgraph = b_depsgraph_;
if (session->progress.get_cancel()) {
update_status_progress();
return;
}
/* set callback to write out render results */
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
session->update_render_tile_cb = function_bind(

View File

@ -39,6 +39,7 @@ set(SRC
device_cpu.cpp
device_cuda.cpp
device_denoising.cpp
device_dummy.cpp
device_memory.cpp
device_multi.cpp
device_opencl.cpp

View File

@ -375,7 +375,7 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool
}
#endif
Device *device;
Device *device = NULL;
switch (info.type) {
case DEVICE_CPU:
@ -385,16 +385,12 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool
case DEVICE_CUDA:
if (device_cuda_init())
device = device_cuda_create(info, stats, profiler, background);
else
device = NULL;
break;
#endif
#ifdef WITH_OPTIX
case DEVICE_OPTIX:
if (device_optix_init())
device = device_optix_create(info, stats, profiler, background);
else
device = NULL;
break;
#endif
#ifdef WITH_NETWORK
@ -406,12 +402,14 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool
case DEVICE_OPENCL:
if (device_opencl_init())
device = device_opencl_create(info, stats, profiler, background);
else
device = NULL;
break;
#endif
default:
return NULL;
break;
}
if (device == NULL) {
device = device_dummy_create(info, stats, profiler, background);
}
return device;
@ -549,6 +547,14 @@ vector<DeviceInfo> Device::available_devices(uint mask)
return devices;
}
DeviceInfo Device::dummy_device(const string &error_msg)
{
DeviceInfo info;
info.type = DEVICE_DUMMY;
info.error_msg = error_msg;
return info;
}
string Device::device_capabilities(uint mask)
{
thread_scoped_lock lock(device_mutex);

View File

@ -48,6 +48,7 @@ enum DeviceType {
DEVICE_NETWORK,
DEVICE_MULTI,
DEVICE_OPTIX,
DEVICE_DUMMY,
};
enum DeviceTypeMask {
@ -87,6 +88,7 @@ class DeviceInfo {
int cpu_threads;
vector<DeviceInfo> multi_devices;
vector<DeviceInfo> denoising_devices;
string error_msg;
DeviceInfo()
{
@ -471,6 +473,7 @@ class Device {
static string string_from_type(DeviceType type);
static vector<DeviceType> available_types();
static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
static DeviceInfo dummy_device(const string &error_msg = "");
static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices,
int threads,

View File

@ -0,0 +1,83 @@
/*
* Copyright 2011-2020 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device/device.h"
#include "device/device_intern.h"
CCL_NAMESPACE_BEGIN
/* Dummy device for when creating an appropriate rendering device fails. */
class DummyDevice : public Device {
public:
DummyDevice(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background_)
: Device(info_, stats_, profiler_, background_)
{
error_msg = info.error_msg;
}
~DummyDevice()
{
}
virtual BVHLayoutMask get_bvh_layout_mask() const override
{
return 0;
}
virtual void mem_alloc(device_memory &) override
{
}
virtual void mem_copy_to(device_memory &) override
{
}
virtual void mem_copy_from(device_memory &, int, int, int, int) override
{
}
virtual void mem_zero(device_memory &) override
{
}
virtual void mem_free(device_memory &) override
{
}
virtual void const_copy_to(const char *, void *, size_t) override
{
}
virtual void task_add(DeviceTask &) override
{
}
virtual void task_wait() override
{
}
virtual void task_cancel() override
{
}
};
Device *device_dummy_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background)
{
return new DummyDevice(info, stats, profiler, background);
}
CCL_NAMESPACE_END

View File

@ -35,6 +35,7 @@ bool device_cuda_init();
Device *device_cuda_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
bool device_optix_init();
Device *device_optix_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
Device *device_dummy_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
Device *device_network_create(DeviceInfo &info,
Stats &stats,

View File

@ -61,22 +61,6 @@ Session::Session(const SessionParams &params_)
TaskScheduler::init(params.threads);
/* Create CPU/GPU devices. */
device = Device::create(params.device, stats, profiler, params.background);
/* Create buffers for interactive rendering. */
if (params.background && !params.write_render_cb) {
buffers = NULL;
display = NULL;
}
else {
buffers = new RenderBuffers(device);
display = new DisplayBuffer(device, params.display_buffer_linear);
}
/* Validate denoising parameters. */
set_denoising(params.denoising);
session_thread = NULL;
scene = NULL;
@ -90,6 +74,26 @@ Session::Session(const SessionParams &params_)
gpu_draw_ready = false;
gpu_need_display_buffer_update = false;
pause = false;
buffers = NULL;
display = NULL;
/* Validate denoising parameters. */
set_denoising(params.denoising);
/* Create CPU/GPU devices. */
device = Device::create(params.device, stats, profiler, params.background);
if (!device->error_message().empty()) {
progress.set_error(device->error_message());
return;
}
/* Create buffers for interactive rendering. */
if (!(params.background && !params.write_render_cb)) {
buffers = new RenderBuffers(device);
display = new DisplayBuffer(device, params.display_buffer_linear);
}
}
Session::~Session()
@ -110,7 +114,7 @@ Session::~Session()
wait();
}
if (params.write_render_cb) {
if (buffers && params.write_render_cb) {
/* Copy to display buffer and write out image if requested */
delete display;