[Bf-blender-cvs] [5da71dd4377] temp-texture-painting-gpu: Use batches drawing.
Jeroen Bakker
noreply at git.blender.org
Fri Sep 30 15:50:30 CEST 2022
Commit: 5da71dd437773b79256a226d58775d3dd293bc22
Author: Jeroen Bakker
Date: Fri Sep 30 15:42:44 2022 +0200
Branches: temp-texture-painting-gpu
https://developer.blender.org/rB5da71dd437773b79256a226d58775d3dd293bc22
Use batches drawing.
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_paint_color.c
M source/blender/editors/sculpt_paint/sculpt_paint_image.cc
M source/blender/gpu/GPU_sculpt_shader_shared.h
M source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
M source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_comp.glsl
M source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_lib.glsl
M source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index ed0969a6306..fb726aab467 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -708,6 +708,10 @@ typedef struct SculptSession {
struct MDeformVert *dvert_prev;
} wpaint;
+ struct {
+ void *gpu_data;
+ } texture_paint;
+
/* TODO: identify sculpt-only fields */
// struct { ... } sculpt;
} mode;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index eb4cc9fd866..23fa2f6b537 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5492,6 +5492,44 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
}
}
+static void sculpt_flush_batches(Sculpt *sd,
+ Object *ob,
+ Brush *brush,
+ PaintModeSettings *paint_mode_settings)
+{
+ if (!sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) {
+ return;
+ }
+ if (brush->sculpt_tool == SCULPT_TOOL_PAINT) {
+ SCULPT_paint_batches_flush(paint_mode_settings, sd, ob);
+ }
+}
+
+static void sculpt_stroke_redraw(const bContext *C,
+ struct PaintStroke *UNUSED(stroke),
+ bool is_final)
+{
+ /* TODO(jbakker): this function should not be called redraw as it doesn't do redrawing, but
+ * triggers batched step drawing and downloading of results and update undo steps for the paint
+ * brush with a canvas target.*/
+ printf("%s %d\n", __func__, is_final);
+
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ ToolSettings *tool_settings = CTX_data_tool_settings(C);
+ sculpt_flush_batches(
+ sd, ob, brush, &tool_settings->paint_mode);
+
+ if (!ss->cache) {
+ return;
+ }
+
+ if (is_final) {
+ }
+}
+
static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))
{
Object *ob = CTX_data_active_object(C);
@@ -5594,9 +5632,10 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_stroke_get_location,
sculpt_stroke_test_start,
sculpt_stroke_update_step,
- NULL,
+ sculpt_stroke_redraw,
sculpt_stroke_done,
event->type);
+ printf("%s\n", __func__);
op->customdata = stroke;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 1dee48d9330..327701de4de 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1697,13 +1697,16 @@ void SCULPT_do_paint_brush(struct PaintModeSettings *paint_mode_settings,
Object *ob,
PBVHNode **nodes,
int totnode) ATTR_NONNULL();
+void SCULPT_paint_batches_flush(struct PaintModeSettings *paint_mode_settings,
+ struct Sculpt *sd,
+ struct Object *ob);
/**
* \brief Get the image canvas for painting on the given object.
*
- * \return #true if an image is found. The #r_image and #r_image_user fields are filled with the
- * image and image user. Returns false when the image isn't found. In the later case the r_image
- * and r_image_user are set to NULL.
+ * \return #true if an image is found. The #r_image and #r_image_user fields are filled with
+ * the image and image user. Returns false when the image isn't found. In the later case the
+ * r_image and r_image_user are set to NULL.
*/
bool SCULPT_paint_image_canvas_get(struct PaintModeSettings *paint_mode_settings,
struct Object *ob,
@@ -1715,6 +1718,9 @@ void SCULPT_do_paint_brush_image(struct PaintModeSettings *paint_mode_settings,
PBVHNode **nodes,
int totnode) ATTR_NONNULL();
bool SCULPT_use_image_paint_brush(struct PaintModeSettings *settings, Object *ob) ATTR_NONNULL();
+void SCULPT_paint_image_batches_flush(struct PaintModeSettings *paint_mode_settings,
+ struct Sculpt *sd,
+ struct Object *ob);
/* Smear Brush. */
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index c494c71f1eb..bd5986c3205 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -377,6 +377,15 @@ void SCULPT_do_paint_brush(
BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
}
+void SCULPT_paint_batches_flush(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob)
+{
+ if (!SCULPT_use_image_paint_brush(paint_mode_settings, ob)) {
+ return;
+ }
+
+ SCULPT_paint_image_batches_flush(paint_mode_settings, sd, ob);
+}
+
static void do_smear_brush_task_cb_exec(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 9ad15fe4863..428ed672f78 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -480,8 +480,17 @@ static void do_mark_dirty_regions(void *__restrict userdata,
/** \name GPU
* \{ */
+struct GPUSculptPaintData {
+ Vector<PaintStepData> steps;
+};
+
static void ensure_gpu_buffers(TexturePaintingUserData &data)
{
+ SculptSession &ss = *data.ob->sculpt;
+ if (!ss.mode.texture_paint.gpu_data) {
+ ss.mode.texture_paint.gpu_data = MEM_new<GPUSculptPaintData>(__func__);
+ }
+
for (PBVHNode *node : MutableSpan<PBVHNode *>(data.nodes, data.nodes_len)) {
NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
node_data.ensure_gpu_buffers();
@@ -493,6 +502,8 @@ static void gpu_painting_paint_step(TexturePaintingUserData &data,
ImBuf *image_buffer,
GPUTexture **tex_ptr,
GPUUniformBuf *paint_brush_buf,
+ GPUStorageBuf *paint_step_buf,
+ int2 paint_step_range,
GPUStorageBuf *vert_coord_buf)
{
GPUShader *shader = SCULPT_shader_paint_image_get();
@@ -513,6 +524,7 @@ static void gpu_painting_paint_step(TexturePaintingUserData &data,
}
/* 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);
@@ -523,14 +535,16 @@ static void gpu_painting_paint_step(TexturePaintingUserData &data,
/* Only clear the texture when it is used for the first time. */
if (texture_needs_clearing) {
+ // Copy from image buffer?
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_uniformbuf_bind(paint_brush_buf,
- GPU_shader_get_uniform_block(shader, "paint_brush_buf"));
+ GPU_storagebuf_bind(paint_step_buf, GPU_shader_get_ssbo(shader, "paint_step_buf"));
+ GPU_shader_uniform_2iv(shader, "paint_step_range", paint_step_range);
+ GPU_uniformbuf_bind(paint_brush_buf, GPU_shader_get_uniform_block(shader, "ren"));
GPU_storagebuf_bind(vert_coord_buf, GPU_shader_get_ssbo(shader, "vert_coord_buf"));
GPU_storagebuf_bind(node_data.triangles.gpu_buffer,
GPU_shader_get_ssbo(shader, "paint_input"));
@@ -582,9 +596,6 @@ static void init_paint_brush_strength(const SculptSession &ss, PaintBrushData &r
/* TODO: Currently only spherical is supported. */
static void init_paint_brush_test(const SculptSession &ss, PaintBrushData &r_paint_brush)
{
- r_paint_brush.test.radius = ss.cache->radius;
- r_paint_brush.test.location = ss.cache->location;
- r_paint_brush.test.mirror_symmetry_pass = ss.cache->mirror_symmetry_pass;
r_paint_brush.test.symm_rot_mat_inv = ss.cache->symm_rot_mat_inv;
}
@@ -597,6 +608,13 @@ static void init_paint_brush(const SculptSession &ss,
init_paint_brush_test(ss, r_paint_brush);
}
+static void init_paint_step(const SculptSession &ss, PaintStepData &r_paint_step)
+{
+ r_paint_step.location = ss.cache->location;
+ r_paint_step.radius = ss.cache->radius;
+ r_paint_step.mirror_symmetry_pass = ss.cache->mirror_symmetry_pass;
+}
+
static GPUStorageBuf *gpu_painting_vert_coord_create(SculptSession &ss)
{
Vector<float4> vert_coords;
@@ -614,28 +632,57 @@ static GPUStorageBuf *gpu_painting_vert_coord_create(SculptSession &ss)
static void dispatch_gpu_painting(TexturePaintingUserData &data)
{
SculptSession &ss = *data.ob->sculpt;
- ImageUser local_image_user = *data.image_data.image_user;
- GPUTexture *tex = nullptr;
- PaintBrushData paint_brush;
- init_paint_brush(ss, *data.brush, paint_brush);
+ GPUSculptPaintData &batches = *static_cast<GPUSculptPaintData *>(ss.mode.texture_paint.gpu_data);
+
+ PaintStepData paint_step;
+ init_paint_step(ss, paint_step);
+ batches.steps.append(paint_step);
+}
+
+static void dispatch_gpu_batches(TexturePaintingUserData &data)
+{
+ SculptSession &ss = *data.ob->sculpt;
+ if (!ss.mode.texture_paint.gpu_data) {
+ /* Currently expected for final redraw. */
+ printf("%s: No batches found to draw\n", __func
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list