34 const int num_samples,
35 bool allow_inplace_modification)
38 if (!denoiser_device) {
49 bool local_buffer_used =
false;
53 local_buffer_used =
false;
57 LOG_DEBUG <<
"Creating temporary buffer on denoiser device.";
64 local_buffer_used =
true;
68 local_render_buffers.
reset(buffer_params);
75 sizeof(
float) * local_render_buffers.
buffer.
size());
85 if (local_buffer_used) {
89 render_buffers, buffer_params, &local_render_buffers, local_render_buffers.
params);
94 return denoise_result;
106 LOG_ERROR <<
"Error preprocessing guiding passes.";
123 LOG_ERROR <<
"GPU denoiser creation has failed.";
128 LOG_ERROR <<
"GPU denoiser configuration has failed.";
137 const BufferParams &buffer_params = context.buffer_params;
142 &context.guiding_params.pass_stride,
143 &context.guiding_params.pass_albedo,
144 &context.guiding_params.pass_normal,
145 &context.guiding_params.pass_flow,
146 &context.render_buffers->buffer.device_pointer,
150 &context.pass_sample_count,
151 &context.pass_denoising_albedo,
152 &context.pass_denoising_normal,
153 &context.pass_motion,
156 &buffer_params.
width,
158 &context.num_samples);
173 num_input_passes += 1;
174 use_pass_albedo = true;
175 pass_denoising_albedo = buffer_params.get_pass_offset(PASS_DENOISING_ALBEDO);
176 if (denoise_params.use_pass_normal) {
177 num_input_passes += 1;
178 use_pass_normal = true;
179 pass_denoising_normal = buffer_params.get_pass_offset(PASS_DENOISING_NORMAL);
183 if (denoise_params.temporally_stable) {
184 prev_output.device_pointer = render_buffers->buffer.device_pointer;
186 prev_output.offset = buffer_params.get_pass_offset(PASS_DENOISING_PREVIOUS);
188 prev_output.stride = buffer_params.stride;
189 prev_output.pass_stride = buffer_params.pass_stride;
191 num_input_passes += 1;
192 use_pass_motion = true;
193 pass_motion = buffer_params.get_pass_offset(PASS_MOTION);
196 use_guiding_passes = (num_input_passes - 1) > 0;
198 if (use_guiding_passes) {
199 if (task.allow_inplace_modification) {
200 guiding_params.device_pointer = render_buffers->buffer.device_pointer;
202 guiding_params.pass_albedo = pass_denoising_albedo;
203 guiding_params.pass_normal = pass_denoising_normal;
204 guiding_params.pass_flow = pass_motion;
206 guiding_params.stride = buffer_params.stride;
207 guiding_params.pass_stride = buffer_params.pass_stride;
210 guiding_params.pass_stride = 0;
211 if (use_pass_albedo) {
212 guiding_params.pass_albedo = guiding_params.pass_stride;
213 guiding_params.pass_stride += 3;
215 if (use_pass_normal) {
216 guiding_params.pass_normal = guiding_params.pass_stride;
217 guiding_params.pass_stride += 3;
219 if (use_pass_motion) {
220 guiding_params.pass_flow = guiding_params.pass_stride;
221 guiding_params.pass_stride += 2;
224 guiding_params.stride = buffer_params.width;
226 guiding_buffer.alloc_to_device(buffer_params.width * buffer_params.height *
227 guiding_params.pass_stride);
228 guiding_params.device_pointer = guiding_buffer.device_pointer;
242 const BufferParams &buffer_params = context.buffer_params;
249 &buffer_params.
width,
254 &context.num_samples,
257 &context.pass_sample_count,
277 const BufferParams &buffer_params = context.buffer_params;
284 &buffer_params.
width,
297 if (context.denoise_params.type !=
DENOISER_OPTIX || context.denoise_params.temporally_stable) {
303 const BufferParams &buffer_params = context.buffer_params;
310 &buffer_params.
width,
322 if (context.denoise_params.type !=
DENOISER_OPTIX || context.denoise_params.temporally_stable) {
328 const BufferParams &buffer_params = context.buffer_params;
330 const int guiding_offset = 0;
334 const int guiding_passes[] = {context.guiding_params.pass_albedo,
335 context.guiding_params.pass_normal};
336 for (
const int guiding_pass : guiding_passes) {
344 &buffer_params.
width,
347 &context.guiding_params.stride,
348 &context.guiding_params.pass_stride,
360 const BufferParams &buffer_params = context.buffer_params;
365 &context.guiding_params.pass_stride,
366 &context.guiding_params.pass_albedo,
367 &buffer_params.
width,
393 destination.
d_pixels = context.render_buffers->buffer.device_pointer;
396 destination.
pixel_stride = context.buffer_params.pass_stride;
409 const BufferParams &buffer_params = context.buffer_params;
422 if (context.albedo_replaced_with_fake) {
423 LOG_ERROR <<
"Pass which requires albedo is denoised after fake albedo has been set.";
427 else if (context.use_guiding_passes && !context.albedo_replaced_with_fake) {
428 context.albedo_replaced_with_fake =
true;
430 LOG_ERROR <<
"Error replacing real albedo with the fake one.";
438 LOG_ERROR <<
"Error converting denoising passes to RGB buffer.";
451 LOG_ERROR <<
"Error copying denoiser result to the denoised pass.";
void render_buffers_host_copy_denoised(RenderBuffers *dst, const BufferParams &dst_params, const RenderBuffers *src, const BufferParams &src_params, const size_t src_offset)
DenoiseContext(Device *device, const DenoiseTask &task)
const BufferParams & buffer_params
const DenoiseParams & denoise_params
device_only_memory< float > guiding_buffer
RenderBuffers * render_buffers
bool use_denoising_albedo
BufferParams buffer_params
RenderBuffers * render_buffers
bool allow_inplace_modification
bool denoise_filter_guiding_set_fake_albedo(const DenoiseContext &context)
virtual bool denoise_run(const DenoiseContext &context, const DenoisePass &pass)=0
DenoiserGPU(Device *denoiser_device, const DenoiseParams ¶ms)
virtual bool denoise_ensure(DenoiseContext &context)
bool denoise_filter_color_postprocess(const DenoiseContext &context, const DenoisePass &pass)
bool denoise_filter_color_preprocess(const DenoiseContext &context, const DenoisePass &pass)
bool denoise_filter_guiding_preprocess(const DenoiseContext &context)
virtual bool denoise_create_if_needed(DenoiseContext &context)=0
bool denoise_filter_color_flip_y(const DenoiseContext &context, const DenoisePass &pass)
bool denoise_buffer(const BufferParams &buffer_params, RenderBuffers *render_buffers, const int num_samples, bool allow_inplace_modification) override
unique_ptr< DeviceQueue > denoiser_queue_
bool denoise_filter_guiding_flip_y(const DenoiseContext &context)
void denoise_pass(DenoiseContext &context, PassType pass_type)
void denoise_color_read(const DenoiseContext &context, const DenoisePass &pass)
virtual bool denoise_configure_if_needed(DenoiseContext &context)=0
Denoiser(Device *denoiser_device, const DenoiseParams ¶ms)
Device * get_denoiser_device() const
Device * denoiser_device_
virtual unique_ptr< DeviceQueue > gpu_queue_create()
bool use_approximate_shadow_catcher
bool use_approximate_shadow_catcher_background
bool get_render_tile_pixels(const RenderBuffers *render_buffers, const Destination &destination) const
device_vector< float > buffer
void reset(const BufferParams ¶ms)
#define CCL_NAMESPACE_END
ccl_gpu_kernel_postfix const ccl_global int ccl_global float const int work_size
@ PASS_SHADOW_CATCHER_MATTE
@ DEVICE_KERNEL_FILTER_COLOR_PREPROCESS
@ DEVICE_KERNEL_FILTER_GUIDING_SET_FAKE_ALBEDO
@ DEVICE_KERNEL_FILTER_COLOR_FLIP_Y
@ DEVICE_KERNEL_FILTER_COLOR_POSTPROCESS
@ DEVICE_KERNEL_FILTER_GUIDING_PREPROCESS
#define DCHECK(expression)
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)