[Bf-blender-cvs] [85f96255b25] temp-texture-painting-gpu: Improve performance by making buffers persistent.
Jeroen Bakker
noreply at git.blender.org
Tue Oct 4 11:17:33 CEST 2022
Commit: 85f96255b25bbabb8e53d4183adea66a312a4742
Author: Jeroen Bakker
Date: Tue Oct 4 10:02:59 2022 +0200
Branches: temp-texture-painting-gpu
https://developer.blender.org/rB85f96255b25bbabb8e53d4183adea66a312a4742
Improve performance by making buffers persistent.
===================================================================
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/shaders/sculpt_paint/sculpt_paint_image_comp.glsl
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index f19f8e91738..aa3893cf466 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5511,13 +5511,13 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
static void sculpt_flush_batches(Sculpt *sd,
Object *ob,
Brush *brush,
- PaintModeSettings *paint_mode_settings)
+ PaintModeSettings *paint_mode_settings, const bool is_final)
{
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);
+ SCULPT_paint_batches_flush(paint_mode_settings, sd, ob, is_final);
}
}
@@ -5534,14 +5534,11 @@ static void sculpt_stroke_redraw(const bContext *C,
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);
+ sculpt_flush_batches(sd, ob, brush, &tool_settings->paint_mode, is_final);
if (!ss->cache) {
return;
}
-
- if (is_final) {
- }
}
static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index d639ff82545..bc22e496013 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1744,7 +1744,8 @@ void SCULPT_do_paint_brush(struct PaintModeSettings *paint_mode_settings,
int totnode) ATTR_NONNULL();
void SCULPT_paint_batches_flush(struct PaintModeSettings *paint_mode_settings,
struct Sculpt *sd,
- struct Object *ob);
+ struct Object *ob,
+ const bool is_final);
/**
* \brief Get the image canvas for painting on the given object.
@@ -1766,6 +1767,9 @@ bool SCULPT_use_image_paint_brush(struct PaintModeSettings *settings, Object *ob
void SCULPT_paint_image_batches_flush(struct PaintModeSettings *paint_mode_settings,
struct Sculpt *sd,
struct Object *ob);
+void SCULPT_paint_image_batches_finalize(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 bc4861f84f3..ccf94aa842e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -395,13 +395,18 @@ 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)
+void SCULPT_paint_batches_flush(PaintModeSettings *paint_mode_settings,
+ Sculpt *sd,
+ Object *ob,
+ const bool is_final)
{
if (!SCULPT_use_image_paint_brush(paint_mode_settings, ob)) {
return;
}
-
SCULPT_paint_image_batches_flush(paint_mode_settings, sd, ob);
+ if (is_final) {
+ SCULPT_paint_image_batches_finalize(paint_mode_settings, sd, ob);
+ }
}
static void do_smear_brush_task_cb_exec(void *__restrict userdata,
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 14ea5bad8b3..3bb2db62932 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -14,6 +14,8 @@
#include "BLI_math_color_blend.h"
#include "BLI_task.h"
+#include "PIL_time_utildefines.h"
+
#include "GPU_capabilities.h"
#include "GPU_compute.h"
#include "GPU_debug.h"
@@ -489,9 +491,140 @@ static void do_mark_dirty_regions(void *__restrict userdata,
/* -------------------------------------------------------------------- */
/** \name GPU
* \{ */
+static GPUStorageBuf *gpu_painting_vert_coord_create(SculptSession &ss)
+{
+ Vector<float4> vert_coords;
+
+ vert_coords.reserve(ss.totvert);
+ for (const MVert &mvert : Span<MVert>(ss.mvert, ss.totvert)) {
+ float3 co(mvert.co);
+ vert_coords.append(float4(co.x, co.y, co.z, 0.0f));
+ }
+ GPUStorageBuf *result = GPU_storagebuf_create_ex(
+ sizeof(float4) * ss.totvert, vert_coords.data(), GPU_USAGE_STATIC, __func__);
+ return result;
+}
+
+static void init_paint_brush_color(const SculptSession &ss,
+ const Brush &brush,
+ PaintBrushData &r_paint_brush)
+{
+ if (ss.cache->invert) {
+ copy_v3_v3(r_paint_brush.color, BKE_brush_secondary_color_get(ss.scene, &brush));
+ }
+ else {
+ copy_v3_v3(r_paint_brush.color, BKE_brush_color_get(ss.scene, &brush));
+ }
+ /* NOTE: Brush colors are stored in sRGB. We use math color to follow other areas that use
+ brush colors. */
+ srgb_to_linearrgb_v3_v3(r_paint_brush.color, r_paint_brush.color);
+ r_paint_brush.color[3] = 1.0f;
+}
+
+static void init_paint_brush_strength(const SculptSession &ss, PaintBrushData &r_paint_brush)
+{
+ r_paint_brush.strength = ss.cache->bstrength;
+}
+
+/* TODO: Currently only spherical is supported. */
+static void init_paint_brush_test(const SculptSession &ss, PaintBrushData &r_paint_brush)
+{
+ r_paint_brush.test.symm_rot_mat_inv = ss.cache->symm_rot_mat_inv;
+}
+
+static void init_paint_brush(const SculptSession &ss,
+ const Brush &brush,
+ PaintBrushData &r_paint_brush)
+{
+ init_paint_brush_color(ss, brush, r_paint_brush);
+ init_paint_brush_strength(ss, r_paint_brush);
+ init_paint_brush_test(ss, r_paint_brush);
+}
struct GPUSculptPaintData {
Vector<PaintStepData> steps;
+ GPUStorageBuf *step_buf = nullptr;
+ size_t step_buf_alloc_size = 0;
+ GPUStorageBuf *vert_coord_buf = nullptr;
+ GPUUniformBuf *paint_brush_buf = nullptr;
+
+ GPUTexture *tile_texture = nullptr;
+
+ ~GPUSculptPaintData()
+ {
+ if (vert_coord_buf) {
+ GPU_storagebuf_free(vert_coord_buf);
+ vert_coord_buf = nullptr;
+ }
+
+ if (paint_brush_buf) {
+ GPU_uniformbuf_free(paint_brush_buf);
+ paint_brush_buf = nullptr;
+ }
+
+ if (step_buf) {
+ GPU_storagebuf_free(step_buf);
+ step_buf = nullptr;
+ }
+
+ if (tile_texture) {
+ GPU_texture_free(tile_texture);
+ tile_texture = nullptr;
+ }
+ }
+
+ void update_step_buf()
+ {
+ int requested_size = sizeof(PaintStepData) * steps.size();
+
+ if (step_buf && requested_size > step_buf_alloc_size) {
+ GPU_storagebuf_free(step_buf);
+ step_buf = nullptr;
+ }
+
+ if (step_buf == nullptr) {
+ step_buf = GPU_storagebuf_create_ex(
+ requested_size, nullptr, GPU_USAGE_STATIC, "PaintStepData");
+ step_buf_alloc_size = requested_size;
+ }
+
+ BLI_assert_msg(sizeof(PaintStepData) * steps.capacity() > step_buf_alloc_size,
+ "Possible read from unallocated memory as storage buffer is larger than the "
+ "step capacity.");
+ GPU_storagebuf_update(step_buf, steps.data());
+ }
+
+ void ensure_vert_coord_buf(SculptSession &ss)
+ {
+ if (!vert_coord_buf) {
+ vert_coord_buf = gpu_painting_vert_coord_create(ss);
+ }
+ }
+
+ void ensure_paint_brush_buf(SculptSession &ss, Brush &brush)
+ {
+ PaintBrushData paint_brush;
+ init_paint_brush(ss, brush, paint_brush);
+
+ if (!paint_brush_buf) {
+ paint_brush_buf = GPU_uniformbuf_create_ex(
+ sizeof(PaintBrushData), nullptr, "PaintBrushData");
+ }
+
+ GPU_uniformbuf_update(paint_brush_buf, &paint_brush);
+ }
+
+ void ensure_tile_texture(const int2 resolution)
+ {
+ if (tile_texture == nullptr || GPU_texture_width(tile_texture) != resolution.x ||
+ GPU_texture_height(tile_texture) != resolution.y) {
+ if (tile_texture) {
+ GPU_texture_free(tile_texture);
+ tile_texture = nullptr;
+ }
+ tile_texture = GPU_texture_create_2d(__func__, UNPACK2(resolution), 1, GPU_RGBA32F, nullptr);
+ }
+ }
};
static void ensure_gpu_buffers(TexturePaintingUserData &data)
@@ -499,6 +632,11 @@ 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__);
+ }
+
+ GPUSculptPaintData &paint_data = *static_cast<GPUSculptPaintData *>(
+ ss.mode.texture_paint.gpu_data);
+ if (paint_data.steps.is_empty()) {
PBVH *pbvh = ss.pbvh;
BKE_pbvh_frame_selection_clear(pbvh);
}
@@ -510,40 +648,19 @@ static void ensure_gpu_buffers(TexturePaintingUserData &data)
}
static void gpu_painting_paint_step(TexturePaintingUserData &data,
+ GPUSculptPaintData &batches,
TileNumber tile_number,
ImBuf *image_buffer,
- GPUTexture **tex_ptr,
- GPUUniformBuf *paint_brush_buf,
- GPUStorageBuf *paint_step_buf,
- int2 paint_step_range,
- GPUStorageBuf *vert_coord_buf)
+ int2 paint_step_range)
{
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. */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list