[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