[Bf-blender-cvs] [bc77184563a] temp-gpu-image-engine: Added support for 1, 2 and 3 channel float buffers.

Jeroen Bakker noreply at git.blender.org
Mon Dec 13 12:47:44 CET 2021


Commit: bc77184563ae6a704fa4f3d48382b506f30067aa
Author: Jeroen Bakker
Date:   Mon Dec 13 12:11:25 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rBbc77184563ae6a704fa4f3d48382b506f30067aa

Added support for 1, 2 and 3 channel float buffers.

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

M	source/blender/draw/engines/image/image_drawing_mode.hh
M	source/blender/imbuf/intern/transform.cc

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

diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index 0328bcc70a2..940ecd7b72b 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -377,8 +377,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
 
     rctf crop_rect;
     rctf *crop_rect_ptr = nullptr;
-    /* TODO: use regular when drawing none repeating single tile buffers. */
-    eIMBTransformMode transform_mode;  // = IMB_TRANSFORM_MODE_REGULAR;
+    eIMBTransformMode transform_mode;
     if (instance_data.flags.do_tile_drawing) {
       transform_mode = IMB_TRANSFORM_MODE_WRAP_REPEAT;
     }
diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index a62e65b7a7d..922e313bada 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -115,8 +115,8 @@ class CropSource : public BaseDiscard {
    */
   virtual bool should_discard(const TransformUserData &user_data, const float uv[2])
   {
-    return uv[0] < user_data.src_crop.xmin && uv[0] >= user_data.src_crop.xmax &&
-           uv[1] < user_data.src_crop.ymin && uv[1] >= user_data.src_crop.ymax;
+    return uv[0] < user_data.src_crop.xmin || uv[0] >= user_data.src_crop.xmax ||
+           uv[1] < user_data.src_crop.ymin || uv[1] >= user_data.src_crop.ymax;
   }
 };
 
@@ -196,32 +196,55 @@ template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChanne
   static const int ChannelLen = NumChannels;
   using SampleType = std::array<StorageType, NumChannels>;
 
-  virtual void sample(const ImBuf *source,
-                      const float u,
-                      const float v,
-                      StorageType r_sample[NumChannels])
+  void sample(const ImBuf *source, const float u, const float v, SampleType &r_sample)
   {
-    if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float> &&
+    if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
                   NumChannels == 4) {
-      nearest_interpolation_color_fl(source, nullptr, r_sample, u, v);
-    }
-    else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
-                       NumChannels == 4) {
-      bilinear_interpolation_color_fl(source, nullptr, r_sample, u, v);
+      bilinear_interpolation_color_fl(source, nullptr, r_sample.begin(), u, v);
     }
     else if constexpr (Filter == IMB_FILTER_NEAREST &&
                        std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
-      nearest_interpolation_color_char(source, r_sample, nullptr, u, v);
+      nearest_interpolation_color_char(source, r_sample.begin(), nullptr, u, v);
     }
     else if constexpr (Filter == IMB_FILTER_BILINEAR &&
                        std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
-      bilinear_interpolation_color_char(source, r_sample, nullptr, u, v);
+      bilinear_interpolation_color_char(source, r_sample.begin(), nullptr, u, v);
+    }
+    else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float>) {
+      sample_nearest_float(source, u, v, r_sample);
     }
     else {
       /* Unsupported sampler. */
       BLI_assert_unreachable();
     }
   }
+
+ private:
+  void sample_nearest_float(const ImBuf *source,
+                            const float u,
+                            const float v,
+                            SampleType &r_sample)
+  {
+    BLI_STATIC_ASSERT(std::is_same_v<StorageType, float>);
+
+    /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+    int x1 = (int)(u);
+    int y1 = (int)(v);
+
+    /* Break when sample outside image is requested. */
+    if (x1 < 0 || x1 >= source->x || y1 < 0 || y1 >= source->y) {
+      for (int i = 0; i < NumChannels; i++) {
+        r_sample[i] = 0.0f;
+      }
+      return;
+    }
+
+    const size_t offset = ((size_t)source->x * y1 + x1) * NumChannels;
+    const float *dataF = source->rect_float + offset;
+    for (int i = 0; i < NumChannels; i++) {
+      r_sample[i] = dataF[i];
+    }
+  }
 };
 
 /**
@@ -232,6 +255,8 @@ template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChanne
  * - 4 channel unsigned char -> 4 channel unsigned char.
  * - 4 channel float -> 4 channel float.
  * - 3 channel float -> 4 channel float.
+ * - 2 channel float -> 4 channel float.
+ * - 1 channel float -> 4 channel float.
  */
 template<typename StorageType, int SourceNumChannels, int DestinationNumChannels>
 class ChannelConverter {
@@ -259,6 +284,17 @@ class ChannelConverter {
                        DestinationNumChannels == 4) {
       copy_v4_fl4(texel_pointer.get_pointer(), sample[0], sample[1], sample[2], 1.0f);
     }
+    else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 2 &&
+                       DestinationNumChannels == 4) {
+      copy_v4_fl4(texel_pointer.get_pointer(), sample[0], sample[1], 0.0f, 1.0f);
+    }
+    else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 1 &&
+                       DestinationNumChannels == 4) {
+      copy_v4_fl4(texel_pointer.get_pointer(), sample[0], 0.0f, 0.0f, 1.0f);
+    }
+    else {
+      BLI_assert_unreachable();
+    }
   }
 };
 
@@ -373,7 +409,7 @@ class ScanlineProcessor {
         sampler.sample(user_data->src,
                        uv_wrapping.modify_u(*user_data, uv[0]),
                        uv_wrapping.modify_v(*user_data, uv[1]),
-                       &sample[0]);
+                       sample);
         channel_converter.convert_and_store(sample, output);
       }
 
@@ -435,8 +471,11 @@ ScanlineThreadFunc get_scanline_function(const TransformUserData *user_data,
   if (src->channels == 3 && dst->channels == 4) {
     return get_scanline_function<Filter, float, 3, 4>(mode);
   }
-  if (src->channels == 3 && dst->channels == 4) {
-    return get_scanline_function<Filter, float, 3, 4>(mode);
+  if (src->channels == 2 && dst->channels == 4) {
+    return get_scanline_function<Filter, float, 2, 4>(mode);
+  }
+  if (src->channels == 1 && dst->channels == 4) {
+    return get_scanline_function<Filter, float, 1, 4>(mode);
   }
   return nullptr;
 }
@@ -446,10 +485,10 @@ static void transform(TransformUserData *user_data, const eIMBTransformMode mode
 {
   ScanlineThreadFunc scanline_func = nullptr;
 
-  if (user_data->dst->rect_float) {
+  if (user_data->dst->rect_float && user_data->src->rect_float) {
     scanline_func = get_scanline_function<Filter>(user_data, mode);
   }
-  else if (user_data->dst->rect) {
+  else if (user_data->dst->rect && user_data->src->rect) {
     /* Number of channels is always 4 when using unsigned char buffers (sRGB + straight alpha). */
     scanline_func = get_scanline_function<Filter, unsigned char, 4, 4>(mode);
   }



More information about the Bf-blender-cvs mailing list