Merge branch 'blender-v4.1-release'

This commit is contained in:
Brecht Van Lommel 2024-03-08 22:54:36 +01:00
commit 2e8e2be0af
8 changed files with 102 additions and 38 deletions

@ -144,17 +144,20 @@ def show_device_active(context):
return backend_has_active_gpu(context)
def get_effective_preview_denoiser(context):
def get_effective_preview_denoiser(context, has_oidn_gpu):
scene = context.scene
cscene = scene.cycles
if cscene.preview_denoiser != "AUTO":
return cscene.preview_denoiser
if has_oidn_gpu:
return 'OPENIMAGEDENOISE'
if context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX'):
return 'OPTIX'
return 'OIDN'
return 'OPENIMAGEDENOISE'
def has_oidn_gpu_devices(context):
@ -234,7 +237,9 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
col.prop(cscene, "preview_denoiser", text="Denoiser")
col.prop(cscene, "preview_denoising_input_passes", text="Passes")
effective_preview_denoiser = get_effective_preview_denoiser(context)
has_oidn_gpu = has_oidn_gpu_devices(context)
effective_preview_denoiser = get_effective_preview_denoiser(context, has_oidn_gpu)
print(has_oidn_gpu, effective_preview_denoiser)
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
@ -242,7 +247,7 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
row = col.row()
row.active = not use_cpu(context) and has_oidn_gpu_devices(context)
row.active = not use_cpu(context) and has_oidn_gpu
row.prop(cscene, "preview_denoising_use_gpu", text="Use GPU")

@ -758,7 +758,7 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
(ID *)PyLong_AsVoidPtr(pyscene), &RNA_ViewLayer, PyLong_AsVoidPtr(pyviewlayer));
BL::ViewLayer b_view_layer(viewlayerptr);
DenoiseParams params = BlenderSync::get_denoise_params(b_scene, b_view_layer, true);
DenoiseParams params = BlenderSync::get_denoise_params(b_scene, b_view_layer, true, device);
params.use = true;
/* Parse file paths list. */

@ -398,8 +398,14 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* update scene */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
sync->sync_data(b_render,
b_depsgraph,
b_v3d,
b_camera_override,
width,
height,
&python_thread_state,
session_params.device);
builtin_images_load();
/* Attempt to free all data which is held by Blender side, since at this
@ -669,6 +675,10 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
{
b_depsgraph = b_depsgraph_;
/* Get session parameters. */
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
/* Initialize bake manager, before we load the baking kernels. */
scene->bake_manager->set(scene, b_object.name());
@ -679,8 +689,14 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
/* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
sync->sync_data(b_render,
b_depsgraph,
b_v3d,
b_camera_override,
width,
height,
&python_thread_state,
session_params.device);
/* Save the current state of the denoiser, as it might be disabled by the pass configuration (for
* passed which do not support denoising). */
@ -720,10 +736,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
}
if (bake_object && !session->progress.get_cancel()) {
/* Get session and buffer parameters. */
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
/* Get buffer parameters. */
BufferParams buffer_params;
buffer_params.width = bake_width;
buffer_params.height = bake_height;
@ -801,8 +814,14 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
b_depsgraph = b_depsgraph_;
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
sync->sync_data(b_render,
b_depsgraph,
b_v3d,
b_camera_override,
width,
height,
&python_thread_state,
session_params.device);
if (b_rv3d) {
sync->sync_view(b_v3d, b_rv3d, width, height);

@ -23,6 +23,8 @@
#include "blender/sync.h"
#include "blender/util.h"
#include "integrator/denoiser.h"
#include "util/debug.h"
#include "util/foreach.h"
#include "util/hash.h"
@ -251,7 +253,8 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
BL::Object &b_override,
int width,
int height,
void **python_thread_state)
void **python_thread_state,
const DeviceInfo &device_info)
{
/* For auto refresh images. */
ImageManager *image_manager = scene->image_manager;
@ -271,7 +274,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
const bool background = !b_v3d;
sync_view_layer(b_view_layer);
sync_integrator(b_view_layer, background);
sync_integrator(b_view_layer, background, device_info);
sync_film(b_view_layer, b_v3d);
sync_shaders(b_depsgraph, b_v3d, auto_refresh_update);
sync_images();
@ -300,7 +303,9 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
/* Integrator */
void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer,
bool background,
const DeviceInfo &device_info)
{
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@ -457,7 +462,8 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
integrator->set_guiding_roughness_threshold(get_float(cscene, "guiding_roughness_threshold"));
}
DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
DenoiseParams denoise_params = get_denoise_params(
b_scene, b_view_layer, background, device_info);
/* No denoising support for vertex color baking, vertices packed into image
* buffer have no relation to neighbors. */
@ -955,7 +961,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer,
bool background)
bool background,
const DeviceInfo &device_info)
{
enum DenoiserInput {
DENOISER_INPUT_RGB = 1,
@ -1009,13 +1016,8 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
/* Auto select fastest denoiser. */
if (denoising.type == DENOISER_NONE) {
if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) {
denoising.type = DENOISER_OPTIX;
}
else if (openimagedenoise_supported()) {
denoising.type = DENOISER_OPENIMAGEDENOISE;
}
else {
denoising.type = Denoiser::automatic_viewport_denoiser_type(device_info);
if (denoising.type == DENOISER_NONE) {
denoising.use = false;
}
}

@ -65,10 +65,13 @@ class BlenderSync {
BL::Object &b_override,
int width,
int height,
void **python_thread_state);
void **python_thread_state,
const DeviceInfo &device_info);
void sync_view_layer(BL::ViewLayer &b_view_layer);
void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
void sync_integrator(BL::ViewLayer &b_view_layer, bool background);
void sync_integrator(BL::ViewLayer &b_view_layer,
bool background,
const DeviceInfo &device_info);
void sync_camera(BL::RenderSettings &b_render,
BL::Object &b_override,
int width,
@ -98,7 +101,8 @@ class BlenderSync {
static DenoiseParams get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer,
bool background);
bool background,
const DeviceInfo &device);
private:
/* sync */

@ -5,13 +5,16 @@
#include "integrator/denoiser.h"
#include "device/device.h"
#include "integrator/denoiser_oidn.h"
#ifdef WITH_OPENIMAGEDENOISE
# include "integrator/denoiser_oidn_gpu.h"
#endif
#include "integrator/denoiser_optix.h"
#include "session/buffers.h"
#include "util/log.h"
#include "util/openimagedenoise.h"
#include "util/progress.h"
CCL_NAMESPACE_BEGIN
@ -20,14 +23,8 @@ unique_ptr<Denoiser> Denoiser::create(Device *path_trace_device, const DenoisePa
{
DCHECK(params.use);
#ifdef WITH_OPTIX
if (params.type == DENOISER_OPTIX && Device::available_devices(DEVICE_MASK_OPTIX).size()) {
return make_unique<OptiXDenoiser>(path_trace_device, params);
}
#endif
#ifdef WITH_OPENIMAGEDENOISE
/* If available and allowed, then we will use OpenImageDenoise on GPU, otherwise on CPU. */
/* If available and allowed, then we will use OpenImageDenoise on GPU. */
if (params.type == DENOISER_OPENIMAGEDENOISE && params.use_gpu &&
path_trace_device->info.type != DEVICE_CPU &&
OIDNDenoiserGPU::is_device_supported(path_trace_device->info))
@ -36,12 +33,35 @@ unique_ptr<Denoiser> Denoiser::create(Device *path_trace_device, const DenoisePa
}
#endif
/* Always fallback to OIDN. */
#ifdef WITH_OPTIX
/* Use OptiX on GPU if supported. */
if (params.type == DENOISER_OPTIX && Device::available_devices(DEVICE_MASK_OPTIX).size()) {
return make_unique<OptiXDenoiser>(path_trace_device, params);
}
#endif
/* Always fallback to OIDN on CPU. */
DenoiseParams oidn_params = params;
oidn_params.type = DENOISER_OPENIMAGEDENOISE;
return make_unique<OIDNDenoiser>(path_trace_device, oidn_params);
}
DenoiserType Denoiser::automatic_viewport_denoiser_type(const DeviceInfo &path_trace_device_info)
{
if (OIDNDenoiserGPU::is_device_supported(path_trace_device_info)) {
return DENOISER_OPENIMAGEDENOISE;
}
else if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) {
return DENOISER_OPTIX;
}
else if (openimagedenoise_supported()) {
return DENOISER_OPENIMAGEDENOISE;
}
else {
return DENOISER_NONE;
}
}
Denoiser::Denoiser(Device *path_trace_device, const DenoiseParams &params)
: path_trace_device_(path_trace_device), params_(params)
{

@ -40,6 +40,9 @@ class Denoiser {
void set_params(const DenoiseParams &params);
const DenoiseParams &get_params() const;
/* Recommended type for viewport denoising. */
static DenoiserType automatic_viewport_denoiser_type(const DeviceInfo &path_trace_device_info);
/* Create devices and load kernels needed for denoising.
* The progress is used to communicate state when kernels actually needs to be loaded.
*

@ -57,6 +57,16 @@ static const char *oidn_device_type_to_string(const OIDNDeviceType type)
bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
{
if (device.type == DEVICE_MULTI) {
for (const DeviceInfo &multi_device : device.multi_devices) {
if (multi_device.type != DEVICE_CPU && is_device_supported(multi_device)) {
return true;
}
}
return false;
}
VLOG_DEBUG << "Checking device " << device.description << " (" << device.id
<< ") for OIDN GPU support";
@ -517,3 +527,4 @@ void OIDNDenoiserGPU::release_all_resources()
CCL_NAMESPACE_END
#endif