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:
authorPatrick Mours <pmours@nvidia.com>2021-11-09 14:17:09 +0300
committerPatrick Mours <pmours@nvidia.com>2021-11-09 16:49:00 +0300
commit440a3475b8f5410e5c41bfbed5ce82771b41356f (patch)
treee48fb3451b3aa3a119858dd2c52165ef3bb0dede
parent9daf6a69a6acd95f0b46bc45e5f3ae27d0904764 (diff)
Cycles: Improve OptiX denoising with dark images and fix crash when denoiser is destroyed
Adds a pass before denoising that calculates the intensity of the image, which can be passed into the OptiX denoiser for more optimal results for very dark or very bright images. In addition this also fixes a crash that sometimes occurred on exit. The OptiX denoiser object has to be destroyed before the OptiX device context object (since it references that). But in C++ the destructor function of a class is called before its fields are destructed, so "~OptiXDevice" was always called before "OptiXDevice::~Denoiser" and therefore "optixDeviceContextDestroy" was called before "optixDenoiserDestroy", hence the crash. Differential Revision: https://developer.blender.org/D13160
-rw-r--r--intern/cycles/device/optix/device_impl.cpp32
-rw-r--r--intern/cycles/device/optix/device_impl.h1
-rw-r--r--intern/cycles/kernel/device/gpu/kernel.h2
3 files changed, 21 insertions, 14 deletions
diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp
index 7f94212f383..8e554d0ba2f 100644
--- a/intern/cycles/device/optix/device_impl.cpp
+++ b/intern/cycles/device/optix/device_impl.cpp
@@ -48,14 +48,6 @@ OptiXDevice::Denoiser::Denoiser(OptiXDevice *device)
{
}
-OptiXDevice::Denoiser::~Denoiser()
-{
- const CUDAContextScope scope(device);
- if (optix_denoiser != nullptr) {
- optixDenoiserDestroy(optix_denoiser);
- }
-}
-
OptiXDevice::OptiXDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
: CUDADevice(info, stats, profiler),
sbt_data(this, "__sbt", MEM_READ_ONLY),
@@ -133,6 +125,11 @@ OptiXDevice::~OptiXDevice()
}
}
+ /* Make sure denoiser is destroyed before device context! */
+ if (denoiser_.optix_denoiser != nullptr) {
+ optixDenoiserDestroy(denoiser_.optix_denoiser);
+ }
+
optixDeviceContextDestroy(context);
}
@@ -884,11 +881,13 @@ bool OptiXDevice::denoise_configure_if_needed(DenoiseContext &context)
optix_assert(optixDenoiserComputeMemoryResources(
denoiser_.optix_denoiser, buffer_params.width, buffer_params.height, &sizes));
- denoiser_.scratch_size = sizes.withOverlapScratchSizeInBytes;
+ /* Denoiser is invoked on whole images only, so no overlap needed (would be used for tiling). */
+ denoiser_.scratch_size = sizes.withoutOverlapScratchSizeInBytes;
denoiser_.scratch_offset = sizes.stateSizeInBytes;
/* Allocate denoiser state if tile size has changed since last setup. */
- denoiser_.state.alloc_to_device(denoiser_.scratch_offset + denoiser_.scratch_size);
+ denoiser_.state.alloc_to_device(denoiser_.scratch_offset + denoiser_.scratch_size +
+ sizeof(float));
/* Initialize denoiser state for the current tile size. */
const OptixResult result = optixDenoiserSetup(
@@ -942,8 +941,6 @@ bool OptiXDevice::denoise_run(DenoiseContext &context, const DenoisePass &pass)
color_layer.format = OPTIX_PIXEL_FORMAT_FLOAT3;
}
- device_vector<float> fake_albedo(this, "fake_albedo", MEM_READ_WRITE);
-
/* Optional albedo and color passes. */
if (context.num_input_passes > 1) {
const device_ptr d_guiding_buffer = context.guiding_params.device_pointer;
@@ -974,6 +971,17 @@ bool OptiXDevice::denoise_run(DenoiseContext &context, const DenoisePass &pass)
/* Finally run denoising. */
OptixDenoiserParams params = {}; /* All parameters are disabled/zero. */
+ params.hdrIntensity = denoiser_.state.device_pointer + denoiser_.scratch_offset +
+ denoiser_.scratch_size;
+
+ optix_assert(
+ optixDenoiserComputeIntensity(denoiser_.optix_denoiser,
+ denoiser_.queue.stream(),
+ &color_layer,
+ params.hdrIntensity,
+ denoiser_.state.device_pointer + denoiser_.scratch_offset,
+ denoiser_.scratch_size));
+
OptixDenoiserLayer image_layers = {};
image_layers.input = color_layer;
image_layers.output = output_layer;
diff --git a/intern/cycles/device/optix/device_impl.h b/intern/cycles/device/optix/device_impl.h
index 3ec98098eb7..5cfc249b430 100644
--- a/intern/cycles/device/optix/device_impl.h
+++ b/intern/cycles/device/optix/device_impl.h
@@ -82,7 +82,6 @@ class OptiXDevice : public CUDADevice {
class Denoiser {
public:
explicit Denoiser(OptiXDevice *device);
- ~Denoiser();
OptiXDevice *device;
OptiXDeviceQueue queue;
diff --git a/intern/cycles/kernel/device/gpu/kernel.h b/intern/cycles/kernel/device/gpu/kernel.h
index f86a8c692aa..5848ba5df9d 100644
--- a/intern/cycles/kernel/device/gpu/kernel.h
+++ b/intern/cycles/kernel/device/gpu/kernel.h
@@ -788,7 +788,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
}
/* Normal pass. */
- if (render_pass_denoising_normal != PASS_UNUSED) {
+ if (guiding_pass_normal != PASS_UNUSED) {
kernel_assert(render_pass_denoising_normal != PASS_UNUSED);
const float *normal_in = buffer + render_pass_denoising_normal;