[Bf-blender-cvs] [1e8b3a8d7b3] cycles-x: Fix Cycles X shadow catcher pass possible buffer overrun

Sergey Sharybin noreply at git.blender.org
Wed Jul 28 16:56:41 CEST 2021


Commit: 1e8b3a8d7b30e576ea911bb6716a3c1b20e83538
Author: Sergey Sharybin
Date:   Wed Jul 28 16:35:40 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB1e8b3a8d7b30e576ea911bb6716a3c1b20e83538

Fix Cycles X shadow catcher pass possible buffer overrun

Split the sample count part of the shadow catcher into a separate pass,
which avoids exceptions in how to treat a pass.

Would be nice to avoid this pass entirely, but not yet sure how.

Differential Revision: https://developer.blender.org/D12058

===================================================================

M	intern/cycles/integrator/pass_accessor.cpp
M	intern/cycles/integrator/pass_accessor.h
M	intern/cycles/integrator/pass_accessor_cpu.cpp
M	intern/cycles/integrator/pass_accessor_cpu.h
M	intern/cycles/kernel/kernel_film.h
M	intern/cycles/kernel/kernel_passes.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/film.cpp
M	intern/cycles/render/pass.cpp
M	intern/cycles/render/scene.cpp

===================================================================

diff --git a/intern/cycles/integrator/pass_accessor.cpp b/intern/cycles/integrator/pass_accessor.cpp
index 9d38f0137f5..051ac2e4bd0 100644
--- a/intern/cycles/integrator/pass_accessor.cpp
+++ b/intern/cycles/integrator/pass_accessor.cpp
@@ -212,9 +212,6 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
     else if (type == PASS_CRYPTOMATTE) {
       get_pass_cryptomatte(render_buffers, buffer_params, destination);
     }
-    else if (type == PASS_SHADOW_CATCHER) {
-      get_pass_shadow_catcher(render_buffers, buffer_params, destination);
-    }
     else if (type == PASS_COMBINED || type == PASS_SHADOW_CATCHER_MATTE) {
       get_pass_combined(render_buffers, buffer_params, destination);
     }
@@ -251,6 +248,8 @@ void PassAccessor::init_kernel_film_convert(KernelFilmConvert *kfilm_convert,
       PASS_ADAPTIVE_AUX_BUFFER);
   kfilm_convert->pass_motion_weight = buffer_params.get_pass_offset(PASS_MOTION_WEIGHT);
   kfilm_convert->pass_shadow_catcher = buffer_params.get_pass_offset(PASS_SHADOW_CATCHER, mode);
+  kfilm_convert->pass_shadow_catcher_sample_count = buffer_params.get_pass_offset(
+      PASS_SHADOW_CATCHER_SAMPLE_COUNT);
   kfilm_convert->pass_shadow_catcher_matte = buffer_params.get_pass_offset(
       PASS_SHADOW_CATCHER_MATTE, mode);
 
diff --git a/intern/cycles/integrator/pass_accessor.h b/intern/cycles/integrator/pass_accessor.h
index 3a17402bb95..0bc68988cfe 100644
--- a/intern/cycles/integrator/pass_accessor.h
+++ b/intern/cycles/integrator/pass_accessor.h
@@ -136,12 +136,12 @@ class PassAccessor {
 
   /* Float3 passes. */
   DECLARE_PASS_ACCESSOR(divide_even_color)
+  DECLARE_PASS_ACCESSOR(shadow_catcher)
   DECLARE_PASS_ACCESSOR(float3)
 
   /* Float4 passes. */
   DECLARE_PASS_ACCESSOR(motion)
   DECLARE_PASS_ACCESSOR(cryptomatte)
-  DECLARE_PASS_ACCESSOR(shadow_catcher)
   DECLARE_PASS_ACCESSOR(shadow_catcher_matte_with_shadow)
   DECLARE_PASS_ACCESSOR(combined)
   DECLARE_PASS_ACCESSOR(float4)
diff --git a/intern/cycles/integrator/pass_accessor_cpu.cpp b/intern/cycles/integrator/pass_accessor_cpu.cpp
index b81ec79bb91..7ddc5cac139 100644
--- a/intern/cycles/integrator/pass_accessor_cpu.cpp
+++ b/intern/cycles/integrator/pass_accessor_cpu.cpp
@@ -161,12 +161,12 @@ DEFINE_PASS_ACCESSOR(float)
 
 /* Float3 passes. */
 DEFINE_PASS_ACCESSOR(divide_even_color)
+DEFINE_PASS_ACCESSOR(shadow_catcher)
 DEFINE_PASS_ACCESSOR(float3)
 
 /* Float4 passes. */
 DEFINE_PASS_ACCESSOR(motion)
 DEFINE_PASS_ACCESSOR(cryptomatte)
-DEFINE_PASS_ACCESSOR(shadow_catcher)
 DEFINE_PASS_ACCESSOR(shadow_catcher_matte_with_shadow)
 DEFINE_PASS_ACCESSOR(combined)
 DEFINE_PASS_ACCESSOR(float4)
diff --git a/intern/cycles/integrator/pass_accessor_cpu.h b/intern/cycles/integrator/pass_accessor_cpu.h
index 4862fee0082..c4768e8ee95 100644
--- a/intern/cycles/integrator/pass_accessor_cpu.h
+++ b/intern/cycles/integrator/pass_accessor_cpu.h
@@ -61,12 +61,12 @@ class PassAccessorCPU : public PassAccessor {
 
   /* Float3 passes. */
   DECLARE_PASS_ACCESSOR(divide_even_color)
+  DECLARE_PASS_ACCESSOR(shadow_catcher)
   DECLARE_PASS_ACCESSOR(float3)
 
   /* Float4 passes. */
   DECLARE_PASS_ACCESSOR(motion)
   DECLARE_PASS_ACCESSOR(cryptomatte)
-  DECLARE_PASS_ACCESSOR(shadow_catcher)
   DECLARE_PASS_ACCESSOR(shadow_catcher_matte_with_shadow)
   DECLARE_PASS_ACCESSOR(combined)
   DECLARE_PASS_ACCESSOR(float4)
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index 233b38b99a0..bada8b1eec4 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -321,17 +321,20 @@ film_calculate_shadow_catcher(const KernelFilmConvert *ccl_restrict kfilm_conver
     return film_calculate_shadow_catcher_denoised(kfilm_convert, buffer);
   }
 
-  kernel_assert(kfilm_convert->pass_shadow_catcher != PASS_UNUSED);
-
-  ccl_global const float *in_catcher = buffer + kfilm_convert->pass_shadow_catcher;
+  kernel_assert(kfilm_convert->pass_shadow_catcher_sample_count != PASS_UNUSED);
 
   /* If there is no shadow catcher object in this pixel, there is no modification of the light
    * needed, so return one. */
-  const float num_samples = in_catcher[3];
+  ccl_global const float *in_catcher_sample_count =
+      buffer + kfilm_convert->pass_shadow_catcher_sample_count;
+  const float num_samples = in_catcher_sample_count[0];
   if (num_samples == 0.0f) {
     return one_float3();
   }
 
+  kernel_assert(kfilm_convert->pass_shadow_catcher != PASS_UNUSED);
+  ccl_global const float *in_catcher = buffer + kfilm_convert->pass_shadow_catcher;
+
   /* NOTE: It is possible that the Shadow Catcher pass is requested as an output without actual
    * shadow catcher objects in the scene. In this case there will be no auxillary passes required
    * for the devision (to save up memory). So delay the asserts to this point so that the number of
@@ -421,9 +424,6 @@ ccl_device_inline void film_get_pass_pixel_shadow_catcher(
   pixel[0] = pixel_value.x;
   pixel[1] = pixel_value.y;
   pixel[2] = pixel_value.z;
-  if (kfilm_convert->num_components == 4) {
-    pixel[3] = 1.0f;
-  }
 }
 
 ccl_device_inline void film_get_pass_pixel_shadow_catcher_matte_with_shadow(
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 325ea07218b..c3ccadccbcd 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -132,7 +132,7 @@ ccl_device_forceinline void kernel_write_shadow_catcher_bounce_data(
     return;
   }
 
-  kernel_assert(kernel_data.film.pass_shadow_catcher != PASS_UNUSED);
+  kernel_assert(kernel_data.film.pass_shadow_catcher_sample_count != PASS_UNUSED);
   kernel_assert(kernel_data.film.pass_shadow_catcher_matte != PASS_UNUSED);
 
   if (!kernel_shadow_catcher_is_path_split_bounce(INTEGRATOR_STATE_PASS, sd->object_flag)) {
@@ -142,7 +142,7 @@ ccl_device_forceinline void kernel_write_shadow_catcher_bounce_data(
   ccl_global float *buffer = kernel_pass_pixel_render_buffer(INTEGRATOR_STATE_PASS, render_buffer);
 
   /* Count sample for the shadow catcher object. */
-  kernel_write_pass_float(buffer + kernel_data.film.pass_shadow_catcher + 3, 1.0f);
+  kernel_write_pass_float(buffer + kernel_data.film.pass_shadow_catcher_sample_count, 1.0f);
 
   /* Since the split is done, the sample does not contribute to the matte, so accumulate it as
    * transparency to the matte. */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 0f0011af9aa..4a1a4c6eb4f 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -370,9 +370,13 @@ typedef enum PassType {
    * result of this division is then to be multiplied with the backdrop. The alpha channel of this
    * pass contains number of samples which contributed to the color components of the pass.
    *
+   * PASS_SHADOW_CATCHER_SAMPLE_COUNT contains number of samples for which the path split
+   * happenned.
+   *
    * PASS_SHADOW_CATCHER_MATTE contains pass which contains non-catcher objects. This pass is to be
    * alpha-overed onto the backdrop (after multiplication). */
   PASS_SHADOW_CATCHER,
+  PASS_SHADOW_CATCHER_SAMPLE_COUNT,
   PASS_SHADOW_CATCHER_MATTE,
 
   PASS_CATEGORY_DATA_END = 63,
@@ -981,6 +985,7 @@ typedef struct KernelFilm {
   float pass_shadow_scale;
 
   int pass_shadow_catcher;
+  int pass_shadow_catcher_sample_count;
   int pass_shadow_catcher_matte;
 
   int filter_table_offset;
@@ -1019,9 +1024,6 @@ typedef struct KernelFilm {
   int display_pass_denoised_offset;
   int show_active_pixels;
   int use_approximate_shadow_catcher;
-
-  /* padding */
-  int pad1;
 } KernelFilm;
 static_assert_align(KernelFilm, 16);
 
@@ -1039,6 +1041,7 @@ typedef struct KernelFilmConvert {
   int pass_adaptive_aux_buffer;
   int pass_motion_weight;
   int pass_shadow_catcher;
+  int pass_shadow_catcher_sample_count;
   int pass_shadow_catcher_matte;
   int pass_background;
 
@@ -1060,7 +1063,7 @@ typedef struct KernelFilmConvert {
   int is_denoised;
 
   /* Padding. */
-  int pad1, pad2, pad3;
+  int pad1, pad2;
 } KernelFilmConvert;
 static_assert_align(KernelFilmConvert, 16);
 
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 7c409f67901..87565f403ad 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -208,6 +208,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
   kfilm->pass_sample_count = PASS_UNUSED;
   kfilm->pass_adaptive_aux_buffer = PASS_UNUSED;
   kfilm->pass_shadow_catcher = PASS_UNUSED;
+  kfilm->pass_shadow_catcher_sample_count = PASS_UNUSED;
   kfilm->pass_shadow_catcher_matte = PASS_UNUSED;
 
   bool have_cryptomatte = false;
@@ -359,6 +360,9 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
       case PASS_SHADOW_CATCHER:
         kfilm->pass_shadow_catcher = kfilm->pass_stride;
         break;
+      case PASS_SHADOW_CATCHER_SAMPLE_COUNT:
+        kfilm->pass_shadow_catcher_sample_count = kfilm->pass_stride;
+        break;
       case PASS_SHADOW_CATCHER_MATTE:
         kfilm->pass_shadow_catcher_matte = kfilm->pass_stride;
         break;
diff --git a/intern/cycles/render/pass.cpp b/intern/cycles/render/pass.cpp
index 6cbcd5257ab..7c706e0f5b9 100644
--- a/intern/cycles/render/pass.cpp
+++ b/intern/cycles/render/pass.cpp
@@ -110,6 +110,7 @@ const NodeEnum *Pass::get_type_enum()
     pass_type_enum.insert("denoising_albedo", PASS_DENOISING_ALBEDO);
 
     pass_type_enum.insert("shadow_catcher", PASS_SHADOW_CATCHER);
+    pass_type_enum.insert("shadow_catcher_sample_count", PASS_SHADOW_CATCHER_SAMPLE_COUNT);
     pass_type_enum.insert("shadow_catcher_matte", PASS_SHADOW_CATCHER_MATTE);
 
     pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
@@ -264,11 +265,14 @@ PassInfo Pass::get_info(PassType type)
       break;
 
     case PASS_SHADOW_CATCHER:
-      pass_info.num_components = 4;
+      pass_info.num_components = 3;
       pass_info.use_exposure = true;
       pass_info.use_compositing = true;
       pass_info.use_denoising_albedo = false;
       break;
+    case PASS_SHADOW_CATCHER_SAMPLE_COUNT:
+      pass_info.num_components = 1;
+      break;
     ca

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list