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.
This commit is contained in:
parent
e108318af8
commit
47a14ef4ad
|
@ -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. */
|
||||
|
|
|
@ -36,6 +36,7 @@ struct ImBuf;
|
|||
struct ImageFormatData;
|
||||
struct Main;
|
||||
struct MenuType;
|
||||
struct PBVH;
|
||||
struct PointerRNA;
|
||||
struct PropertyRNA;
|
||||
struct ScrArea;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue