[Bf-blender-cvs] [e13b1bb524b] temp-texture-painting-gpu: Merge paint image with canvas.

Jeroen Bakker noreply at git.blender.org
Fri Sep 30 15:50:29 CEST 2022


Commit: e13b1bb524b7db03e3552d3d8fd9d28989fdeb38
Author: Jeroen Bakker
Date:   Wed Sep 28 14:11:54 2022 +0200
Branches: temp-texture-painting-gpu
https://developer.blender.org/rBe13b1bb524b7db03e3552d3d8fd9d28989fdeb38

Merge paint image with canvas.

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

M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_paint_image.cc
M	source/blender/editors/sculpt_paint/sculpt_shaders.cc
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_sculpt_shader_shared.h
M	source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
A	source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl

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

diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index ae0bc8cfb92..1dee48d9330 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1825,6 +1825,7 @@ void SCULPT_bmesh_topology_rake(
 /* sculpt_shaders.cc */
 
 struct GPUShader *SCULPT_shader_paint_image_get(void);
+struct GPUShader *SCULPT_shader_paint_image_merge_get(void);
 void SCULPT_shader_free(void);
 
 /* end sculpt_shadders.cc */
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 0fdfc3ebdc4..e6e8a8148e7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -487,11 +487,73 @@ static void ensure_gpu_buffers(TexturePaintingUserData &data)
   }
 }
 
-static void dispatch_gpu_painting(TexturePaintingUserData &data)
+static void gpu_painting_paint_step(TexturePaintingUserData &data,
+                                    ImageTileWrapper &image_tile,
+                                    ImBuf *image_buffer,
+                                    GPUTexture **tex_ptr)
 {
   GPUShader *shader = SCULPT_shader_paint_image_get();
+  bool texture_needs_clearing = true;
+
+  GPUTexture *tex = *tex_ptr;
+
+  /* Ensure that texture size is same as tile size. */
+  if (tex == nullptr || GPU_texture_width(tex) != image_buffer->x ||
+      GPU_texture_height(tex) != image_buffer->y) {
+    if (tex) {
+      GPU_texture_free(tex);
+      tex = nullptr;
+    }
+    tex = GPU_texture_create_2d(
+        __func__, image_buffer->x, image_buffer->y, 1, GPU_RGBA32F, nullptr);
+    *tex_ptr = tex;
+  }
+
+  /* Dispatch all nodes that paint on the active tile. */
+  for (PBVHNode *node : MutableSpan<PBVHNode *>(data.nodes, data.nodes_len)) {
+    NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
+
+    for (UDIMTilePixels &tile_pixels : node_data.tiles) {
+      if (tile_pixels.tile_number != image_tile.get_tile_number()) {
+        continue;
+      }
+
+      /* Only clear the texture when it is used for the first time. */
+      if (texture_needs_clearing) {
+        GPU_texture_clear(tex, GPU_DATA_FLOAT, float4(0.0f, 0.0f, 0.0f, 0.0f));
+        texture_needs_clearing = false;
+      }
+
+      GPU_shader_bind(shader);
+      GPU_texture_image_bind(tex, GPU_shader_get_texture_binding(shader, "out_img"));
+      GPU_storagebuf_bind(node_data.triangles.gpu_buffer,
+                          GPU_shader_get_ssbo(shader, "paint_input"));
+      GPU_storagebuf_bind(node_data.gpu_buffers.pixels,
+                          GPU_shader_get_ssbo(shader, "pixel_row_buf"));
+      GPU_shader_uniform_1i(shader, "pixel_row_offset", tile_pixels.gpu_buffer_offset);
+
+      GPU_compute_dispatch(shader, tile_pixels.pixel_rows.size(), 1, 1);
+    }
+    node_data.ensure_gpu_buffers();
+  }
+}
+
+static void gpu_painting_image_merge(TexturePaintingUserData &UNUSED(data),
+                                     Image &image,
+                                     ImageUser &image_user,
+                                     ImBuf &image_buffer,
+                                     GPUTexture *paint_tex)
+{
+  GPUTexture *canvas_tex = BKE_image_get_gpu_texture(&image, &image_user, &image_buffer);
+  GPUShader *shader = SCULPT_shader_paint_image_merge_get();
   GPU_shader_bind(shader);
+  GPU_texture_image_bind(paint_tex, GPU_shader_get_texture_binding(shader, "in_paint_img"));
+  GPU_texture_image_bind(canvas_tex, GPU_shader_get_texture_binding(shader, "out_img"));
+  GPU_compute_dispatch(shader, image_buffer.x, image_buffer.y, 1);
+}
 
+static void dispatch_gpu_painting(TexturePaintingUserData &data)
+{
   ImageUser local_image_user = *data.image_data.image_user;
   GPUTexture *tex = nullptr;
 
@@ -505,58 +567,8 @@ static void dispatch_gpu_painting(TexturePaintingUserData &data)
       continue;
     }
 
-    bool texture_needs_clearing = true;
-
-    /* Ensure that texture size is same as tile size. */
-    if (tex == nullptr || GPU_texture_width(tex) != image_buffer->x ||
-        GPU_texture_height(tex) != image_buffer->y) {
-      if (tex) {
-        GPU_texture_free(tex);
-        tex = nullptr;
-      }
-      tex = GPU_texture_create_2d(
-          __func__, image_buffer->x, image_buffer->y, 1, GPU_RGBA32F, nullptr);
-    }
-
-    /* Dispatch all nodes that paint on the active tile. */
-    for (PBVHNode *node : MutableSpan<PBVHNode *>(data.nodes, data.nodes_len)) {
-      NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
-
-      for (UDIMTilePixels &tile_pixels : node_data.tiles) {
-        if (tile_pixels.tile_number != image_tile.get_tile_number()) {
-          continue;
-        }
-
-        /* Only clear the texture when it is used for the first time. */
-        if (texture_needs_clearing) {
-          GPU_texture_clear(tex, GPU_DATA_FLOAT, float4(0.0f, 0.0f, 0.0f, 0.0f));
-          texture_needs_clearing = false;
-        }
-
-        GPU_shader_bind(shader);
-        GPU_texture_image_bind(tex, GPU_shader_get_texture_binding(shader, "out_img"));
-        GPU_storagebuf_bind(node_data.triangles.gpu_buffer,
-                            GPU_shader_get_ssbo(shader, "paint_input"));
-        GPU_storagebuf_bind(node_data.gpu_buffers.pixels,
-                            GPU_shader_get_ssbo(shader, "pixel_row_buf"));
-        GPU_shader_uniform_1i(shader, "pixel_row_offset", tile_pixels.gpu_buffer_offset);
-
-        GPU_compute_dispatch(shader, tile_pixels.pixel_rows.size(), 1, 1);
-      }
-      node_data.ensure_gpu_buffers();
-    }
-
-#if 0
-    GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
-    float *tex_data = static_cast<float *>(GPU_texture_read(tex, GPU_DATA_FLOAT, 0));
-    for (int i = 0; i < 10; i++) {
-      printf("%f,", tex_data[i]);
-    }
-    printf("\n");
-    MEM_freeN(tex_data);
-#endif
-
-    /* Integrate active tile to draw engine texture. */
+    gpu_painting_paint_step(data, image_tile, image_buffer, &tex);
+    gpu_painting_image_merge(data, *data.image_data.image, local_image_user, *image_buffer, tex);
 
     BKE_image_release_ibuf(data.image_data.image, image_buffer, nullptr);
   }
diff --git a/source/blender/editors/sculpt_paint/sculpt_shaders.cc b/source/blender/editors/sculpt_paint/sculpt_shaders.cc
index 35efc1a3151..f998fab30c3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_shaders.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_shaders.cc
@@ -11,6 +11,7 @@
 
 static struct SCULPT_Shaders {
   GPUShader *paint_image_comp_sh;
+  GPUShader *paint_image_merge_comp_sh;
 } sh_data;
 
 extern "C" {
@@ -22,6 +23,15 @@ GPUShader *SCULPT_shader_paint_image_get(void)
   return sh_data.paint_image_comp_sh;
 }
 
+GPUShader *SCULPT_shader_paint_image_merge_get(void)
+{
+  if (sh_data.paint_image_merge_comp_sh == nullptr) {
+    sh_data.paint_image_merge_comp_sh = GPU_shader_create_from_info_name(
+        "sculpt_paint_image_merge_compute");
+  }
+  return sh_data.paint_image_merge_comp_sh;
+}
+
 void SCULPT_shader_free(void)
 {
   GPUShader **sh_data_as_array = (GPUShader **)&sh_data;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index a65fee13ca4..15e10c6bcf0 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -481,6 +481,7 @@ set(GLSL_SRC
 
   GPU_sculpt_shader_shared.h
   shaders/sculpt_paint/sculpt_paint_image_comp.glsl
+  shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl
 
   GPU_shader_shared_utils.h
 )
diff --git a/source/blender/gpu/GPU_sculpt_shader_shared.h b/source/blender/gpu/GPU_sculpt_shader_shared.h
index ac767b69826..648cb140188 100644
--- a/source/blender/gpu/GPU_sculpt_shader_shared.h
+++ b/source/blender/gpu/GPU_sculpt_shader_shared.h
@@ -35,8 +35,8 @@ struct PackedPixelRow {
 };
 
 #define PIXEL_ROW_START_IMAGE_COORD(row) \
-  ivec2((row.start_image_coordinate & 0xffff0000) >> 16, row.start_image_coordinate & 0xffff)
-#define PIXEL_ROW_LEN(row) uint((row.encoded & 0xffff0000) >> 16)
-#define PIXEL_ROW_PRIM_INDEX(row) uint(row.encoded & 0xffff);
+  ivec2(row.start_image_coordinate & 0xffff, (row.start_image_coordinate & 0xffff0000) >> 16)
+#define PIXEL_ROW_LEN(row) uint(row.encoded & 0xffff);
+#define PIXEL_ROW_PRIM_INDEX(row) uint((row.encoded & 0xffff0000) >> 16)
 
 BLI_STATIC_ASSERT_ALIGN(TrianglePaintInput, 16)
diff --git a/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh b/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
index 344533d7e8e..3309c8cc739 100644
--- a/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
+++ b/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
@@ -9,10 +9,18 @@
 
 GPU_SHADER_CREATE_INFO(sculpt_paint_image_compute)
     .local_group_size(1, 1, 1)
-    .image(0, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "out_img")
+    .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_img")
     .storage_buf(0, Qualifier::READ, "PackedPixelRow", "pixel_row_buf[]")
     .storage_buf(1, Qualifier::READ, "TrianglePaintInput", "paint_input[]")
     .push_constant(Type::INT, "pixel_row_offset")
     .compute_source("sculpt_paint_image_comp.glsl")
     .typedef_source("GPU_sculpt_shader_shared.h")
     .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(sculpt_paint_image_merge_compute)
+    .local_group_size(1, 1, 1)
+    .image(0, GPU_RGBA32F, Qualifier::READ, ImageType::FLOAT_2D, "in_paint_img")
+    .image(1, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "out_img")
+    .compute_source("sculpt_paint_image_merge_comp.glsl")
+    .typedef_source("GPU_sculpt_shader_shared.h")
+    .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl b/source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl
new file mode 100644
index 00000000000..a9b76ef78d6
--- /dev/null
+++ b/source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl
@@ -0,0 +1,9 @@
+void main()
+{
+  ivec2 coord_in = ivec2(gl_GlobalInvocationID.xy);
+  ivec2 coord_out

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list