[Bf-blender-cvs] [47a14ef4adc] sculpt-dev: sculpt-dev: Fix draw cache bug
Joseph Eagar
noreply at git.blender.org
Tue Jun 14 18:55:34 CEST 2022
Commit: 47a14ef4adc53705aee722bb406c3f854791005f
Author: Joseph Eagar
Date: Tue Jun 14 09:52:34 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rB47a14ef4adc53705aee722bb406c3f854791005f
sculpt-dev: Fix draw cache bug
Fix the pbvh draw optimization that only sends
active attributes to the GPU. The solution here
is the original sculpt-dev one (somehow this
ended up being removed but not replaced in the
pbvh-eevee patch).
It works by checking every viewport in every
window and if it finds eevee or workbench
in material mode it sets a flag in the pbvh
to forcibly upload all attributes.
Another approach is to simply rewrite pbvh
draw properly inside the draw manager to
begin with.
===================================================================
M source/blender/blenkernel/intern/pbvh.c
M source/blender/windowmanager/WM_api.h
M source/blender/windowmanager/intern/wm_draw.c
===================================================================
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 632458019fb..3ed45fde5a4 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -870,7 +870,9 @@ void BKE_pbvh_free(PBVH *pbvh)
void BKE_pbvh_need_full_render_set(PBVH *pbvh, bool state)
{
- GPU_pbvh_need_full_render_set(pbvh->vbo_id, state);
+ if (pbvh->vbo_id) {
+ GPU_pbvh_need_full_render_set(pbvh->vbo_id, state);
+ }
}
static void pbvh_iter_begin(PBVHIter *iter,
@@ -1657,7 +1659,7 @@ void pbvh_update_free_all_draw_buffers(PBVH *pbvh, PBVHNode *node)
}
}
-static void pbvh_check_draw_layout(PBVH *pbvh, bool full_render)
+ATTR_NO_OPT static void pbvh_check_draw_layout(PBVH *pbvh, bool full_render)
{
const CustomData *vdata;
const CustomData *ldata;
@@ -1687,6 +1689,8 @@ static void pbvh_check_draw_layout(PBVH *pbvh, bool full_render)
/* rebuild all draw buffers if attribute layout changed */
if (GPU_pbvh_attribute_names_update(pbvh->type, pbvh->vbo_id, vdata, ldata, !full_render)) {
+ printf("%s: draw update\n", __func__);
+
/* attribute layout changed; force rebuild */
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *node = pbvh->nodes + i;
@@ -1701,29 +1705,10 @@ static void pbvh_check_draw_layout(PBVH *pbvh, bool full_render)
static void pbvh_update_draw_buffers(
PBVH *pbvh, Mesh *me, PBVHNode **nodes, int totnode, int update_flag)
{
- const CustomData *vdata;
-
if (!pbvh->vbo_id) {
pbvh->vbo_id = GPU_pbvh_make_format();
}
- switch (pbvh->type) {
- case PBVH_BMESH:
- if (!pbvh->bm) {
- /* BMesh hasn't been created yet */
- return;
- }
-
- vdata = &pbvh->bm->vdata;
- break;
- case PBVH_FACES:
- vdata = pbvh->vdata;
- break;
- case PBVH_GRIDS:
- vdata = NULL;
- break;
- }
-
if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) {
/* Free buffers uses OpenGL, so not in parallel. */
for (int n = 0; n < totnode; n++) {
@@ -3265,6 +3250,10 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
int totnode;
int update_flag = 0;
+ if (pbvh->vbo_id) {
+ full_render |= GPU_pbvh_need_full_render_get(pbvh->vbo_id);
+ }
+
pbvh->draw_cache_invalid = false;
/* Search for nodes that need updates. */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index ac06ababfd4..3ba41a79841 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -36,6 +36,7 @@ struct ImBuf;
struct ImageFormatData;
struct Main;
struct MenuType;
+struct PBVH;
struct PointerRNA;
struct PropertyRNA;
struct ScrArea;
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index e27a6aaefbc..a6e544ebe57 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -27,10 +27,10 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_pbvh.h"
-#include "BKE_paint.h"
#include "GHOST_C-api.h"
@@ -1194,16 +1194,24 @@ void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *UNUSED(region))
}
}
-static void pbvh_full_render_update(PBVH *pbvh, bContext *C, Main *bmain, wmWindowManager *wm)
+static void wm_pbvh_full_render_update(bContext *C)
{
+ Main *bmain = CTX_data_main(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
- /*We can save GPU bandwidth for PBVH drawing if we know for sure that no
- viewport has EEVEE running in it. As in no viewport in any windows.
+ /*
+ * We can save GPU bandwidth for PBVH drawing if we know for sure that no
+ * viewport has EEVEE running in it. As in no viewport in any windows.
+ *
+ * This saves us from having to upload every possible attribute eevee
+ * might need.
+ *
+ * This is because PBVH only supplies one set of drawing buffers
+ * to the draw manager. Creating more buffers for specific drawengines
+ * is simply not feasible for performance reasons.
+ */
- This is because PBVH only supplies one set of drawing buffers
- to the draw manager. Creating more buffers for specific drawengines
- is simply not feasible for performance reasons.
- */
+ bool need_full_render = false;
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
@@ -1214,7 +1222,12 @@ static void pbvh_full_render_update(PBVH *pbvh, bContext *C, Main *bmain, wmWind
CTX_wm_window_set(C, win);
- BKE_pbvh_need_full_render_set(pbvh, false);
+ Object *ob = CTX_data_active_object(C);
+ if (!ob || !(ob->mode & OB_MODE_SCULPT) || !ob->sculpt || !ob->sculpt->pbvh) {
+ continue;
+ }
+
+ BKE_pbvh_need_full_render_set(ob->sculpt->pbvh, false);
if (wm_draw_update_test_window(bmain, C, win)) {
bScreen *screen = WM_window_get_active_screen(win);
@@ -1226,13 +1239,31 @@ static void pbvh_full_render_update(PBVH *pbvh, bContext *C, Main *bmain, wmWind
}
CTX_wm_area_set(C, area);
+
View3D *v3d = CTX_wm_view3d(C);
- if (v3d->shading.type >= OB_MATERIAL) {
- BKE_pbvh_need_full_render_set(pbvh, true);
- }
+
+ need_full_render |= v3d->shading.type >= OB_MATERIAL;
+ need_full_render |= v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR;
}
}
}
+
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
+
+ if (state == GHOST_kWindowStateMinimized) {
+ continue;
+ }
+
+ CTX_wm_window_set(C, win);
+
+ Object *ob = CTX_data_active_object(C);
+ if (!ob || !(ob->mode & OB_MODE_SCULPT) || !ob->sculpt || !ob->sculpt->pbvh) {
+ continue;
+ }
+
+ BKE_pbvh_need_full_render_set(ob->sculpt->pbvh, need_full_render);
+ }
}
void wm_draw_update(bContext *C)
@@ -1247,11 +1278,6 @@ void wm_draw_update(bContext *C)
BKE_image_free_unused_gpu_textures();
- Object *ob = CTX_data_active_object(C);
- if (ob && (ob->mode & OB_MODE_SCULPT) && ob->sculpt && ob->sculpt->pbvh) {
- pbvh_full_render_update(ob->sculpt->pbvh, C, bmain, wm);
- }
-
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
#ifdef WIN32
GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
@@ -1267,6 +1293,8 @@ void wm_draw_update(bContext *C)
CTX_wm_window_set(C, win);
+ wm_pbvh_full_render_update(C);
+
if (wm_draw_update_test_window(bmain, C, win)) {
bScreen *screen = WM_window_get_active_screen(win);
More information about the Bf-blender-cvs
mailing list