Mesh Batch Cache: Optimization & Refactor shaded surface support
This now only upload data per loops to the GPU, making use of index buffer to draw polygon. This make use of the vertex cache, speed up renders and saves a lot of vram. Update performance is also slightly faster and can even be improved further by updating only uvs or vcol independently. This commits breaks texture paint batches. It will be added back in another commit.
This commit is contained in:
parent
bc74e48680
commit
36cc42e796
Notes:
blender-bot
2023-02-14 08:47:25 +01:00
Referenced by issue #59554, Crash drawing armature with custom bone shapes
|
@ -157,10 +157,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
}
|
||||
|
||||
const bool is_active = (ob == draw_ctx->obact);
|
||||
const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get_ex(ob, use_hide);
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING));
|
||||
/* Depth Prepass */
|
||||
|
|
|
@ -1523,7 +1523,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
|
|||
int *auto_layer_is_srgb;
|
||||
int auto_layer_count;
|
||||
struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
|
||||
ob, gpumat_array, materials_len, use_hide,
|
||||
ob, gpumat_array, materials_len,
|
||||
&auto_layer_names,
|
||||
&auto_layer_is_srgb,
|
||||
&auto_layer_count);
|
||||
|
|
|
@ -823,7 +823,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
if (me->mloopuv) {
|
||||
const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
|
||||
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob, use_hide) : NULL;
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
|
||||
if (materials_len > 0 && geom_array) {
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if (geom_array[i] == NULL) {
|
||||
|
@ -846,7 +846,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
if (!is_drawn) {
|
||||
if (ELEM(wpd->shading.color_type, V3D_SHADING_SINGLE_COLOR, V3D_SHADING_RANDOM_COLOR)) {
|
||||
/* No material split needed */
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get_ex(ob, use_hide);
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type);
|
||||
if (is_sculpt_mode) {
|
||||
|
@ -865,7 +865,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
}
|
||||
|
||||
struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
|
||||
ob, gpumat_array, materials_len, use_hide, NULL, NULL, NULL);
|
||||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
if (mat_geom[i] == NULL) {
|
||||
|
|
|
@ -497,7 +497,6 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
const bool is_active = (ob == draw_ctx->obact);
|
||||
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
|
||||
const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
|
||||
bool is_drawn = false;
|
||||
|
||||
if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && ELEM(ob->type, OB_MESH)) {
|
||||
|
@ -505,7 +504,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
if (me->mloopuv) {
|
||||
const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
|
||||
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob, use_hide) : NULL;
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
|
||||
if (materials_len > 0 && geom_array) {
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if (geom_array[i] == NULL) {
|
||||
|
@ -538,7 +537,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
if (!is_drawn) {
|
||||
if (ELEM(wpd->shading.color_type, V3D_SHADING_SINGLE_COLOR, V3D_SHADING_RANDOM_COLOR)) {
|
||||
/* No material split needed */
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get_ex(ob, use_hide);
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type);
|
||||
if (is_sculpt_mode) {
|
||||
|
@ -563,7 +562,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
}
|
||||
|
||||
struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
|
||||
ob, gpumat_array, materials_len, use_hide, NULL, NULL, NULL);
|
||||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
if (mat_geom[i] == NULL) {
|
||||
|
|
|
@ -732,15 +732,10 @@ GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob)
|
|||
}
|
||||
|
||||
GPUBatch *DRW_cache_object_surface_get(Object *ob)
|
||||
{
|
||||
return DRW_cache_object_surface_get_ex(ob, false);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_object_surface_get_ex(Object *ob, bool use_hide)
|
||||
{
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
return DRW_cache_mesh_surface_get(ob, use_hide);
|
||||
return DRW_cache_mesh_surface_get(ob);
|
||||
case OB_CURVE:
|
||||
return DRW_cache_curve_surface_get(ob);
|
||||
case OB_SURF:
|
||||
|
@ -755,7 +750,7 @@ GPUBatch *DRW_cache_object_surface_get_ex(Object *ob, bool use_hide)
|
|||
}
|
||||
|
||||
GPUBatch **DRW_cache_object_surface_material_get(
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
|
||||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count)
|
||||
{
|
||||
if (auto_layer_names != NULL) {
|
||||
|
@ -766,7 +761,7 @@ GPUBatch **DRW_cache_object_surface_material_get(
|
|||
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len, use_hide,
|
||||
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len,
|
||||
auto_layer_names, auto_layer_is_srgb, auto_layer_count);
|
||||
case OB_CURVE:
|
||||
return DRW_cache_curve_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
|
@ -3029,12 +3024,12 @@ GPUBatch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
|
|||
return DRW_mesh_batch_cache_get_edge_detection(me, r_is_manifold);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_mesh_surface_get(Object *ob, bool use_hide)
|
||||
GPUBatch *DRW_cache_mesh_surface_get(Object *ob)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
|
||||
Mesh *me = ob->data;
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(me, use_hide);
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(me);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
|
||||
|
@ -3106,23 +3101,23 @@ GPUBatch *DRW_cache_mesh_surface_vert_colors_get(Object *ob)
|
|||
|
||||
/* Return list of batches */
|
||||
GPUBatch **DRW_cache_mesh_surface_shaded_get(
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
|
||||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
|
||||
Mesh *me = ob->data;
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(me, gpumat_array, gpumat_array_len, use_hide,
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(me, gpumat_array, gpumat_array_len,
|
||||
auto_layer_names, auto_layer_is_srgb, auto_layer_count);
|
||||
}
|
||||
|
||||
/* Return list of batches */
|
||||
GPUBatch **DRW_cache_mesh_surface_texpaint_get(Object *ob, bool use_hide)
|
||||
GPUBatch **DRW_cache_mesh_surface_texpaint_get(Object *ob)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
|
||||
Mesh *me = ob->data;
|
||||
return DRW_mesh_batch_cache_get_surface_texpaint(me, use_hide);
|
||||
return DRW_mesh_batch_cache_get_surface_texpaint(me);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
|
||||
|
@ -3235,7 +3230,7 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true);
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_triangles_with_normals(cu);
|
||||
|
@ -3281,7 +3276,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
@ -3339,7 +3334,7 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
|
|||
return NULL;
|
||||
}
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true);
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_triangles_with_normals(cu);
|
||||
|
@ -3389,7 +3384,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get(
|
|||
return NULL;
|
||||
}
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
@ -3410,7 +3405,7 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true);
|
||||
return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_triangles_with_normals(cu);
|
||||
|
@ -3464,7 +3459,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
@ -3788,6 +3783,7 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
|
|||
|
||||
GPUBatch *DRW_batch_request(GPUBatch **batch)
|
||||
{
|
||||
/* XXX TODO(fclem): We are writting to batch cache here. Need to make this thread safe. */
|
||||
if (*batch == NULL) {
|
||||
*batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
|
||||
}
|
||||
|
|
|
@ -53,10 +53,9 @@ struct GPUBatch *DRW_cache_screenspace_circle_get(void);
|
|||
struct GPUBatch *DRW_cache_object_wire_outline_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_object_edge_detection_get(struct Object *ob, bool *r_is_manifold);
|
||||
struct GPUBatch *DRW_cache_object_surface_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_object_surface_get_ex(struct Object *ob, bool use_hide);
|
||||
struct GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_object_surface_material_get(
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
|
||||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
|
||||
struct GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob);
|
||||
|
||||
|
@ -129,7 +128,7 @@ struct GPUBatch *DRW_cache_mesh_surface_overlay_get(struct Object *ob);
|
|||
struct GPUBatch *DRW_cache_face_centers_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob, bool use_hide);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_loose_edges_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob, struct ToolSettings *ts, bool paint_mode);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
|
||||
|
@ -140,9 +139,9 @@ struct GPUBatch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool
|
|||
struct GPUBatch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_shaded_get(
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
|
||||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob, bool use_hide);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
|
||||
|
||||
|
|
|
@ -122,16 +122,16 @@ bool DRW_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const st
|
|||
void DRW_mesh_batch_cache_create_requested(struct Object *ob, struct Mesh *me);
|
||||
|
||||
struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
|
||||
struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
|
||||
struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
|
||||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
|
||||
struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me, bool use_hide);
|
||||
struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel, bool use_hide);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me, bool use_hide);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, const struct DRW_MeshWeightState *wstate);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1917,6 +1917,8 @@ void DRW_render_object_iter(
|
|||
DST.dupli_source = data_.dupli_object_current;
|
||||
DST.ob_state = NULL;
|
||||
callback(vedata, ob, engine, depsgraph);
|
||||
|
||||
drw_batch_cache_generate_requested(ob);
|
||||
}
|
||||
}
|
||||
DEG_OBJECT_ITER_END
|
||||
|
|
|
@ -662,7 +662,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
|
||||
if (do_occlude_wire) {
|
||||
geom = DRW_cache_mesh_surface_get(ob, false);
|
||||
geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
|
||||
}
|
||||
|
||||
|
|
|
@ -300,9 +300,9 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
|
|||
if (use_surface) {
|
||||
if (me->mloopuv != NULL) {
|
||||
if (use_material_slots || use_face_sel) {
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob, use_face_sel) : NULL;
|
||||
struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
|
||||
if ((me->totcol == 0) || (geom_array == NULL)) {
|
||||
struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob, use_face_sel);
|
||||
struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat);
|
||||
ok = true;
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
|
||||
if (!ok) {
|
||||
struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob, use_face_sel);
|
||||
struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue