[Bf-blender-cvs] [c193800a603] cycles-x: Refactor CYcles X OptiX denoiser preparing for in-place operation
Sergey Sharybin
noreply at git.blender.org
Fri Jul 9 17:32:18 CEST 2021
Commit: c193800a603d8c225769a104d96a1e4c0a37ae9c
Author: Sergey Sharybin
Date: Fri Jul 9 14:34:53 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBc193800a603d8c225769a104d96a1e4c0a37ae9c
Refactor CYcles X OptiX denoiser preparing for in-place operation
Currently no functional changes are expected. Making code ready for
re-using storage of the render buffers to store guiding passes when
this is possible.
===================================================================
M intern/cycles/device/device_kernel.cpp
M intern/cycles/device/optix/device_impl.cpp
M intern/cycles/device/optix/device_impl.h
M intern/cycles/kernel/device/cuda/kernel.cu
M intern/cycles/kernel/kernel_types.h
===================================================================
diff --git a/intern/cycles/device/device_kernel.cpp b/intern/cycles/device/device_kernel.cpp
index 648ee090ce7..ca918c2f853 100644
--- a/intern/cycles/device/device_kernel.cpp
+++ b/intern/cycles/device/device_kernel.cpp
@@ -106,10 +106,14 @@ const char *device_kernel_as_string(DeviceKernel kernel)
return "adaptive_sampling_filter_y";
/* Denoising. */
- case DEVICE_KERNEL_FILTER_CONVERT_TO_RGB:
- return "filter_convert_to_rgb";
- case DEVICE_KERNEL_FILTER_CONVERT_FROM_RGB:
- return "filter_convert_from_rgb";
+ case DEVICE_KERNEL_FILTER_GUIDING_PREPROCESS:
+ return "filter_guiding_preprocess";
+ case DEVICE_KERNEL_FILTER_GUIDING_SET_FAKE_ALBEDO:
+ return "filter_guiding_set_fake_albedo";
+ case DEVICE_KERNEL_FILTER_COLOR_PREPROCESS:
+ return "filter_color_preprocess";
+ case DEVICE_KERNEL_FILTER_COLOR_POSTPROCESS:
+ return "filter_color_postprocess";
/* Generic */
case DEVICE_KERNEL_PREFIX_SUM:
diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp
index 298b384797e..9bda428c462 100644
--- a/intern/cycles/device/optix/device_impl.cpp
+++ b/intern/cycles/device/optix/device_impl.cpp
@@ -531,25 +531,39 @@ class OptiXDevice::DenoiseContext {
: denoise_params(task.params),
render_buffers(task.render_buffers),
buffer_params(task.buffer_params),
- input_buffer(device, "denoiser input buffer"),
+ guiding_buffer(device, "denoiser guiding passes buffer"),
num_samples(task.num_samples)
{
num_input_passes = 1;
if (denoise_params.use_pass_albedo) {
num_input_passes += 1;
use_pass_albedo = true;
+ pass_denoising_albedo = buffer_params.get_pass_offset(PASS_DENOISING_ALBEDO);
if (denoise_params.use_pass_normal) {
num_input_passes += 1;
use_pass_normal = true;
+ pass_denoising_normal = buffer_params.get_pass_offset(PASS_DENOISING_NORMAL);
}
}
- /* Don't allocate color pass: denoised pass storage from the render buffers is used for both
- * noisy pass input at a proper scale and result of the denoiser. */
- const int input_buffer_stride = (num_input_passes - 1) * 3;
- if (input_buffer_stride) {
- input_buffer.alloc_to_device(buffer_params.width * buffer_params.height *
- input_buffer_stride);
+ const int num_guiding_passes = num_input_passes - 1;
+
+ if (num_guiding_passes) {
+ guiding_params.pass_stride = 0;
+ if (use_pass_albedo) {
+ guiding_params.pass_albedo = guiding_params.pass_stride;
+ guiding_params.pass_stride += 3;
+ }
+ if (use_pass_normal) {
+ guiding_params.pass_normal = guiding_params.pass_stride;
+ guiding_params.pass_stride += 3;
+ }
+
+ guiding_params.stride = buffer_params.width;
+
+ guiding_buffer.alloc_to_device(buffer_params.width * buffer_params.height *
+ guiding_params.pass_stride);
+ guiding_params.device_pointer = guiding_buffer.device_pointer;
}
pass_sample_count = buffer_params.get_pass_offset(PASS_SAMPLE_COUNT);
@@ -560,9 +574,19 @@ class OptiXDevice::DenoiseContext {
RenderBuffers *render_buffers = nullptr;
const BufferParams &buffer_params;
- /* Device-side storage of the input passes.
- * Start with the input color pass, followed with optional albedo and normal passes. */
- device_only_memory<float> input_buffer;
+ /* Device-side storage of the guiding passes. */
+ device_only_memory<float> guiding_buffer;
+
+ struct {
+ device_ptr device_pointer = 0;
+
+ /* NOTE: Are only initialized when the corresponding guiding pass is enabled. */
+ int pass_albedo = PASS_UNUSED;
+ int pass_normal = PASS_UNUSED;
+
+ int stride = -1;
+ int pass_stride = -1;
+ } guiding_params;
/* Number of input passes. Including the color and extra auxillary passes. */
int num_input_passes = 0;
@@ -570,15 +594,38 @@ class OptiXDevice::DenoiseContext {
bool use_pass_normal = false;
int num_samples = 0;
+
int pass_sample_count = PASS_UNUSED;
+
+ /* NOTE: Are only initialized when the corresponding guiding pass is enabled. */
+ int pass_denoising_albedo = PASS_UNUSED;
+ int pass_denoising_normal = PASS_UNUSED;
+
+ /* For passes which don't need albedo channel for denoising we replace the actual albedo with
+ * the (0.5, 0.5, 0.5). This flag indicates that the real albedo pass has been replaced with
+ * the fake values and denoising of passes which do need albedo can no longer happen. */
+ bool albedo_replaced_with_fake = false;
};
class OptiXDevice::DenoisePass {
public:
+ DenoisePass(const PassType type, const BufferParams &buffer_params) : type(type)
+ {
+ noisy_offset = buffer_params.get_pass_offset(type, PassMode::NOISY);
+ denoised_offset = buffer_params.get_pass_offset(type, PassMode::DENOISED);
+
+ const PassInfo pass_info = Pass::get_info(type);
+ use_compositing = pass_info.use_compositing;
+ use_denoising_albedo = pass_info.use_denoising_albedo;
+ }
+
PassType type;
int noisy_offset;
int denoised_offset;
+
+ bool use_compositing;
+ bool use_denoising_albedo;
};
void OptiXDevice::denoise_buffer(const DeviceDenoiseTask &task)
@@ -591,9 +638,17 @@ void OptiXDevice::denoise_buffer(const DeviceDenoiseTask &task)
return;
}
+ if (!denoise_filter_guiding_preprocess(context)) {
+ LOG(ERROR) << "Error preprocessing guiding passes.";
+ return;
+ }
+
+ /* Passes which will use real albedo when it is available. */
denoise_pass(context, PASS_COMBINED);
- denoise_pass(context, PASS_SHADOW_CATCHER);
denoise_pass(context, PASS_SHADOW_CATCHER_MATTE);
+
+ /* Passes which do not need albedo and hence if real is present it needs to become fake. */
+ denoise_pass(context, PASS_SHADOW_CATCHER);
}
DeviceQueue *OptiXDevice::get_denoise_queue()
@@ -601,14 +656,52 @@ DeviceQueue *OptiXDevice::get_denoise_queue()
return &denoiser_.queue;
}
+bool OptiXDevice::denoise_filter_guiding_preprocess(DenoiseContext &context)
+{
+ const BufferParams &buffer_params = context.buffer_params;
+
+ const int work_size = buffer_params.width * buffer_params.height;
+
+ void *args[] = {const_cast<device_ptr *>(&context.guiding_params.device_pointer),
+ const_cast<int *>(&context.guiding_params.pass_stride),
+ const_cast<int *>(&context.guiding_params.pass_albedo),
+ const_cast<int *>(&context.guiding_params.pass_normal),
+ &context.render_buffers->buffer.device_pointer,
+ const_cast<int *>(&buffer_params.offset),
+ const_cast<int *>(&buffer_params.stride),
+ const_cast<int *>(&buffer_params.pass_stride),
+ const_cast<int *>(&context.pass_sample_count),
+ const_cast<int *>(&context.pass_denoising_albedo),
+ const_cast<int *>(&context.pass_denoising_normal),
+ const_cast<int *>(&buffer_params.full_x),
+ const_cast<int *>(&buffer_params.full_y),
+ const_cast<int *>(&buffer_params.width),
+ const_cast<int *>(&buffer_params.height),
+ const_cast<int *>(&context.num_samples)};
+
+ return denoiser_.queue.enqueue(DEVICE_KERNEL_FILTER_GUIDING_PREPROCESS, work_size, args);
+}
+
+bool OptiXDevice::denoise_filter_guiding_set_fake_albedo(DenoiseContext &context)
+{
+ const BufferParams &buffer_params = context.buffer_params;
+
+ const int work_size = buffer_params.width * buffer_params.height;
+
+ void *args[] = {const_cast<device_ptr *>(&context.guiding_params.device_pointer),
+ const_cast<int *>(&context.guiding_params.pass_stride),
+ const_cast<int *>(&context.guiding_params.pass_albedo),
+ const_cast<int *>(&buffer_params.width),
+ const_cast<int *>(&buffer_params.height)};
+
+ return denoiser_.queue.enqueue(DEVICE_KERNEL_FILTER_GUIDING_SET_FAKE_ALBEDO, work_size, args);
+}
+
void OptiXDevice::denoise_pass(DenoiseContext &context, PassType pass_type)
{
const BufferParams &buffer_params = context.buffer_params;
- DenoisePass pass;
- pass.type = pass_type;
- pass.noisy_offset = buffer_params.get_pass_offset(pass_type, PassMode::NOISY);
- pass.denoised_offset = buffer_params.get_pass_offset(pass_type, PassMode::DENOISED);
+ const DenoisePass pass(pass_type, buffer_params);
if (pass.noisy_offset == PASS_UNUSED) {
return;
@@ -618,14 +711,23 @@ void OptiXDevice::denoise_pass(DenoiseContext &context, PassType pass_type)
return;
}
- /* Read pixels from the noisy input pass, store them in the temporary buffer for further
- * clamping. */
- denoise_read_input_pixels(context, pass);
+ if (pass.use_denoising_albedo) {
+ if (context.albedo_replaced_with_fake) {
+ LOG(ERROR) << "Pass which requires albedo is denoised after fake albedo has been set.";
+ return;
+ }
+ }
+ else if (!context.albedo_replaced_with_fake) {
+ context.albedo_replaced_with_fake = true;
+ if (!denoise_filter_guiding_set_fake_albedo(context)) {
+ LOG(ERROR) << "Error replacing real albedo with the fake one.";
+ return;
+ }
+ }
- /* Make sure input data is in [0 .. 10000] range by scaling the input buffer by the number of
- * samples in the buffer. Additionally, fill in the auxillary passes needed by the denoiser which
- * were not provided by the pass accessor. */
- if (!denoise_filter_convert_to_rgb(context, pass)) {
+ /* Read and preprocess noisy color input pass. */
+ denoise_color_read(context, pass);
+ if (!denoise_filter_color_preprocess(context, pass)) {
LOG(ERROR) << "Error connverting denoising passes to RGB buffer.";
return;
}
@@ -638,7 +740,7 @@ void OptiXDevice::denoise_pass(DenoiseContext &context, PassType pass_type)
/* Store result in the combined pass of the render buffer.
*
* This will scale the denoiser result up to match the number of, possibly per-pixel, samples. */
- if (!denoise_filter_convert_from_rgb(context, pass)) {
+ if (!denoise_filter_c
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list