[Bf-blender-cvs] [4a061a87e66] blender2.8: DwM: mesh data now only creates data thats used

Campbell Barton noreply at git.blender.org
Wed Jun 28 05:38:17 CEST 2017


Commit: 4a061a87e6625c396ccbc20c4636f447c453323c
Author: Campbell Barton
Date:   Wed Jun 28 13:38:24 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB4a061a87e6625c396ccbc20c4636f447c453323c

DwM: mesh data now only creates data thats used

Read from the GPUMaterial to find custom-data layers used for drawing.

This resolves problem where having UV's would always calculate tangents
causing noticeable slow down compared to 2.7x.

===================================================================

M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c

===================================================================

diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index c23918d5c2d..5393c8d305e 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -576,6 +576,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 	if (ELEM(ob->type, OB_MESH)) {
 		const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
 		struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
+		struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
 
 		bool use_flat_nor = false;
 
@@ -602,9 +603,15 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 			shgrp = BLI_ghash_lookup(material_hash, (const void *)ma);
 			if (shgrp) {
 				shgrp_array[i] = shgrp;  /* ADD_SHGROUP_CALL below */
+				/* This will have been created already, just perform a lookup. */
+				gpumat_array[i] = (use_gpumat) ? EEVEE_material_mesh_get(
+				        draw_ctx->scene, ma,stl->effects->use_ao, stl->effects->use_bent_normals) : NULL;
 				continue;
 			}
 
+			/* May not be set below. */
+			gpumat_array[i] = NULL;
+
 			if (use_gpumat) {
 				Scene *scene = draw_ctx->scene;
 				struct GPUMaterial *gpumat = EEVEE_material_mesh_get(scene, ma,
@@ -616,6 +623,8 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 
 					BLI_ghash_insert(material_hash, ma, shgrp);
 					shgrp_array[i] = shgrp;  /* ADD_SHGROUP_CALL below */
+
+					gpumat_array[i] = gpumat;
 				}
 				else {
 					/* Shader failed : pink color */
@@ -643,7 +652,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 		}
 
 		/* Get per-material split surface */
-		struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob);
+		struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
 		if (mat_geom) {
 			for (int i = 0; i < materials_len; ++i) {
 				ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]);
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 7636bce9aca..b62559fdb0e 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -522,11 +522,12 @@ Gwn_Batch *DRW_cache_object_surface_get(Object *ob)
 	}
 }
 
-Gwn_Batch **DRW_cache_object_surface_material_get(struct Object *ob)
+Gwn_Batch **DRW_cache_object_surface_material_get(
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
 {
 	switch (ob->type) {
 		case OB_MESH:
-			return DRW_cache_mesh_surface_shaded_get(ob);
+			return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
 		default:
 			return NULL;
 	}
@@ -2212,12 +2213,13 @@ Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(Object *ob)
 }
 
 /* Return list of batches */
-Gwn_Batch **DRW_cache_mesh_surface_shaded_get(Object *ob)
+Gwn_Batch **DRW_cache_mesh_surface_shaded_get(
+        Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
 {
 	BLI_assert(ob->type == OB_MESH);
 
 	Mesh *me = ob->data;
-	return DRW_mesh_batch_cache_get_surface_shaded(me);
+	return DRW_mesh_batch_cache_get_surface_shaded(me, gpumat_array, gpumat_array_len);
 }
 
 /* Return list of batches */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 0bb291caa9c..21fa652778b 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -27,6 +27,7 @@
 #define __DRAW_CACHE_H__
 
 struct Gwn_Batch;
+struct GPUMaterial;
 struct Object;
 struct ModifierData;
 
@@ -43,7 +44,8 @@ struct Gwn_Batch *DRW_cache_screenspace_circle_get(void);
 /* Common Object */
 struct Gwn_Batch *DRW_cache_object_wire_outline_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_object_surface_get(struct Object *ob);
-struct Gwn_Batch **DRW_cache_object_surface_material_get(struct Object *ob);
+struct Gwn_Batch **DRW_cache_object_surface_material_get(
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
 
 /* Empties */
 struct Gwn_Batch *DRW_cache_plain_axes_get(void);
@@ -118,7 +120,8 @@ struct Gwn_Batch *DRW_cache_mesh_verts_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel);
 struct Gwn_Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob);
-struct Gwn_Batch **DRW_cache_mesh_surface_shaded_get(struct Object *ob);
+struct Gwn_Batch **DRW_cache_mesh_surface_shaded_get(
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
 struct Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
 
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index f02f73d1f9d..9328f6f6314 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -27,6 +27,7 @@
 #define __DRAW_CACHE_IMPL_H__
 
 struct Gwn_Batch;
+struct GPUMaterial;
 struct ListBase;
 struct CurveCache;
 struct ParticleSystem;
@@ -72,7 +73,8 @@ struct Gwn_Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
 
 /* Mesh */
 
-struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me);
+struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded(
+        struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
 struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
 struct Gwn_Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
 struct Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index a008af73549..c65799521b2 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -33,6 +33,7 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_math_vector.h"
+#include "BLI_math_bits.h"
 #include "BLI_string.h"
 
 #include "DNA_mesh_types.h"
@@ -52,6 +53,7 @@
 
 #include "GPU_batch.h"
 #include "GPU_draw.h"
+#include "GPU_material.h"
 
 #include "draw_cache_impl.h"  /* own include */
 
@@ -236,7 +238,72 @@ static bool bm_edge_has_visible_face(const BMEdge *e)
 }
 
 
-static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
+static void mesh_cd_calc_used_gpu_layers(
+        CustomData *UNUSED(cd_vdata), uchar cd_vused[CD_NUMTYPES],
+        CustomData *cd_ldata, uchar cd_lused[CD_NUMTYPES],
+        struct GPUMaterial **gpumat_array, int gpumat_array_len)
+{
+	GPUVertexAttribs gattribs = {0};
+
+	for (int i = 0; i < gpumat_array_len; i++) {
+		GPUMaterial *gpumat = gpumat_array[i];
+		if (gpumat) {
+			GPU_material_vertex_attributes(gpumat, &gattribs);
+			for (int j = 0; j < gattribs.totlayer; j++) {
+				const char *name = gattribs.layer[j].name;
+				switch (gattribs.layer[j].type) {
+					case CD_MTFACE:
+					{
+						int index = (name[0] != '\0') ?
+						        CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
+						        CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+						if (index != -1) {
+							cd_lused[CD_MLOOPUV] |= (1 << index);
+						}
+						break;
+					}
+					case CD_TANGENT:
+					{
+						int index = (name[0] != '\0') ?
+						        CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
+						        CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+						if (index != -1) {
+							cd_lused[CD_TANGENT] |= (1 << index);
+
+							/* TODO(campbell): investigate why this is needed T51919. */
+							cd_lused[CD_MLOOPUV] |= (1 << index);
+						}
+						break;
+					}
+					case CD_MCOL:
+					{
+						int index = (name[0] != '\0') ?
+						        CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) :
+						        CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
+						if (index != -1) {
+							cd_lused[CD_MLOOPCOL] |= (1 << index);
+						}
+						break;
+					}
+					case CD_ORCO:
+					{
+						cd_vused[CD_ORCO] |= 1;
+						break;
+					}
+				}
+			}
+		}
+	}
+}
+
+/**
+ * TODO(campbell): 'gpumat_array' may include materials linked to the object.
+ * While not default, object materials should be supported.
+ * Although this only impacts the data thats generated, not the materials that display.
+ */
+static MeshRenderData *mesh_render_data_create_ex(
+        Mesh *me, const int types,
+        struct GPUMaterial **gpumat_array, uint gpumat_array_len)
 {
 	MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
 	rdata->types = types;
@@ -371,33 +438,57 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
 			cd_ldata = &me->ldata;
 		}
 
+		/* Add edge/poly if we need them */
+		uchar cd_vused[CD_NUMTYPES] = {0};
+		uchar cd_lused[CD_NUMTYPES] = {0};
+
+		mesh_cd_calc_used_gpu_layers(
+		        cd_vdata, cd_vused,
+		        cd_ldata, cd_lused,
+		        gpumat_array, gpumat_array_len);
+
 
 		rdata->cd.layers.uv_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
 		rdata->cd.layers.vcol_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
 		rdata->cd.layers.tangent_active = rdata->cd.layers.uv_active;
 
-		rdata->orco = CustomData_get_layer(cd_vdata, CD_ORCO);
-		/* If orco is not available compute it ourselves */
-		if (!rdata->orco) {
-			if (me->edit_btmesh) {
-				BMesh *bm = me->edit_btmesh->bm;
-				rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
-				BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
-				BMVert **vtable = bm->vtable;
-				for (int i = 0; i < bm->totvert; i++) {
-					copy_v3_v3(rdata->orco[i], vtable[i]->co);
+		if ((cd_lused[CD_MLOOPUV] & (1 << rdata->cd.layers.uv_active)) == 0) {
+			rdata->cd.layers.uv_active = -1;
+		}
+		if ((cd_lused[CD_TANGENT] & (1 << rdata->cd.layers.tangent_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list