[Bf-blender-cvs] [cddae66] opensubdiv-modifier: OpenSubdiv: Wrapping up skipping grid evaluation for GPU pipeline

Sergey Sharybin noreply at git.blender.org
Thu Jul 16 12:56:14 CEST 2015


Commit: cddae66d73bd956f88a18dc45200dfc4e3128e6f
Author: Sergey Sharybin
Date:   Thu Jul 16 12:09:19 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rBcddae66d73bd956f88a18dc45200dfc4e3128e6f

OpenSubdiv: Wrapping up skipping grid evaluation for GPU pipeline

This commit adds some missing topology changes checks and does various smaller
fixes related on both CU and GPU code paths for subsurf modifier.

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

M	intern/opensubdiv/opensubdiv_capi.cc
M	intern/opensubdiv/opensubdiv_capi.h
M	intern/opensubdiv/opensubdiv_converter.cc
M	intern/opensubdiv/opensubdiv_converter_capi.h
M	source/blender/blenkernel/intern/CCGSubSurf.c
M	source/blender/blenkernel/intern/CCGSubSurf.h
M	source/blender/blenkernel/intern/CCGSubSurf_intern.h
M	source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
M	source/blender/blenkernel/intern/subsurf_ccg.c

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

diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index 26247ed..b5e7aa7 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -213,7 +213,7 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
 		(OpenSubdiv_GLMesh *) OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
 	gl_mesh->evaluator_type = evaluator_type;
 	gl_mesh->descriptor = (OpenSubdiv_GLMeshDescr *) mesh;
-	gl_mesh->level = level;
+	gl_mesh->topology_refiner = (OpenSubdiv_TopologyRefinerDescr*)refiner;
 
 	return gl_mesh;
 }
@@ -290,6 +290,12 @@ void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
 	((GLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer();
 }
 
+const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner(
+        OpenSubdiv_GLMesh *gl_mesh)
+{
+	return gl_mesh->topology_refiner;;
+}
+
 int openSubdiv_supportGPUDisplay(void)
 {
 	return GL_EXT_geometry_shader4 &&
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index 184c9d7..b5c3932 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -41,7 +41,7 @@ struct OpenSubdiv_GLMeshDescr;
 typedef struct OpenSubdiv_GLMesh {
 	int evaluator_type;
 	OpenSubdiv_GLMeshDescr *descriptor;
-	int level;
+	OpenSubdiv_TopologyRefinerDescr *topology_refiner;
 } OpenSubdiv_GLMesh;
 #endif
 
@@ -82,6 +82,9 @@ void openSubdiv_osdGLMeshRefine(OpenSubdiv_GLMesh *gl_mesh);
 void openSubdiv_osdGLMeshSynchronize(OpenSubdiv_GLMesh *gl_mesh);
 void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh);
 
+const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner(
+        OpenSubdiv_GLMesh *gl_mesh);
+
 /* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */
 void openSubdiv_osdGLDisplayInit(void);
 void openSubdiv_osdGLDisplayDeinit(void);
diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc
index fec9ed1..a75649d 100644
--- a/intern/opensubdiv/opensubdiv_converter.cc
+++ b/intern/opensubdiv/opensubdiv_converter.cc
@@ -23,7 +23,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#include <stdio.h>
+#include <cstdio>
+#include <vector>
 
 #include <opensubdiv/far/topologyRefinerFactory.h>
 
@@ -219,8 +220,81 @@ struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr(
 #ifdef OPENSUBDIV_VALIDATE_TOPOLOGY
 	topology_options.validateFullTopology = true;
 #endif
+	/* We don't use guarded allocation here so we can re-use the refiner
+	 * for GL mesh creation directly.
+	 */
 	return (struct OpenSubdiv_TopologyRefinerDescr*)
 	        TopologyRefinerFactory<OpenSubdiv_Converter>::Create(
 	                *converter,
 	                topology_options);
 }
+
+void openSubdiv_deleteTopologyRefinerDescr(
+        OpenSubdiv_TopologyRefinerDescr *topology_refiner)
+{
+	delete (OpenSubdiv::Far::TopologyRefiner *)topology_refiner;
+}
+
+int openSubdiv_topologyRefinerGetSubdivLevel(
+        const OpenSubdiv_TopologyRefinerDescr *topology_refiner)
+{
+	using OpenSubdiv::Far::TopologyRefiner;
+	const TopologyRefiner *refiner = (const TopologyRefiner *)topology_refiner;
+	return refiner->GetMaxLevel();
+}
+
+int openSubdiv_topologyRefnerCompareConverter(
+        const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+        OpenSubdiv_Converter *converter)
+{
+	using OpenSubdiv::Far::ConstIndexArray;
+	using OpenSubdiv::Far::TopologyRefiner;
+	using OpenSubdiv::Far::TopologyLevel;
+	const TopologyRefiner *refiner = (const TopologyRefiner *)topology_refiner;
+	const TopologyLevel &base_level = refiner->GetLevel(0);
+	const int num_verts = base_level.GetNumVertices();
+	const int num_edges = base_level.GetNumEdges();
+	const int num_faces = base_level.GetNumFaces();
+	/* Quick preliminary check. */
+	OpenSubdiv::Sdc::SchemeType scheme_type =
+	        get_capi_scheme_type(converter->get_type(converter));
+	if (scheme_type != refiner->GetSchemeType()) {
+		return false;
+	}
+	if (converter->get_num_verts(converter) != num_verts ||
+	    converter->get_num_edges(converter) != num_edges ||
+	    converter->get_num_faces(converter) != num_faces)
+	{
+		return false;
+	}
+	/* Compare all edges. */
+	for (int edge = 0; edge < num_edges; ++edge) {
+		ConstIndexArray edge_verts = base_level.GetEdgeVertices(edge);
+		int conv_edge_verts[2];
+		converter->get_edge_verts(converter, edge, conv_edge_verts);
+		if (conv_edge_verts[0] != edge_verts[0] ||
+		    conv_edge_verts[1] != edge_verts[1])
+		{
+			return false;
+		}
+	}
+	/* Compare all faces. */
+	std::vector<int> conv_face_verts;
+	for (int face = 0; face < num_faces; ++face) {
+		ConstIndexArray face_verts = base_level.GetFaceVertices(face);
+		if (face_verts.size() != converter->get_num_face_verts(converter,
+		                                                       face))
+		{
+			return false;
+		}
+		conv_face_verts.resize(face_verts.size());
+		converter->get_face_verts(converter, face, &conv_face_verts[0]);
+		for (int i = 0; i < face_verts.size(); ++i) {
+			if (conv_face_verts[i] != face_verts[i]) {
+				return false;
+			}
+		}
+	}
+	/* TODO(sergey): Edge crease comparison. */
+	return true;
+}
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h
index d005b2c..f5d8a7e 100644
--- a/intern/opensubdiv/opensubdiv_converter_capi.h
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -87,6 +87,20 @@ typedef struct OpenSubdiv_Converter {
 OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr(
         OpenSubdiv_Converter *converter);
 
+void openSubdiv_deleteTopologyRefinerDescr(
+        OpenSubdiv_TopologyRefinerDescr *topology_refiner);
+
+/* TODO(sergey): Those calls are not strictly related on conversion.
+ * needs some dedicated fiel perhaps.
+ */
+
+int openSubdiv_topologyRefinerGetSubdivLevel(
+        const OpenSubdiv_TopologyRefinerDescr *topology_refiner);
+
+int openSubdiv_topologyRefnerCompareConverter(
+        const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+        OpenSubdiv_Converter *converter);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 1a51ef2..530e9f8 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -39,6 +39,7 @@
 
 #ifdef WITH_OPENSUBDIV
 #  include "opensubdiv_capi.h"
+#  include "opensubdiv_converter_capi.h"
 #endif
 
 #include "GL/glew.h"
@@ -342,8 +343,9 @@ void ccgSubSurf_free(CCGSubSurf *ss)
 	if (ss->osd_coarse_coords != NULL) {
 		MEM_freeN(ss->osd_coarse_coords);
 	}
-	/* TODO(sergey): This is not valid when viewport is not visible. */
-	BLI_assert(ss->osd_topology_refiner == NULL);
+	if (ss->osd_topology_refiner != NULL) {
+		openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner);
+	}
 #endif
 
 	if (ss->syncState) {
@@ -404,9 +406,6 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
 		return eCCGError_InvalidValue;
 	}
 	else if (subdivisionLevels != ss->subdivLevels) {
-#ifdef WITH_OPENSUBDIV
-		ss->osd_mesh_invalid = true;
-#endif
 		ss->numGrids = 0;
 		ss->subdivLevels = subdivisionLevels;
 		ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 59f8a56..6669298 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -80,6 +80,9 @@ void		ccgSubSurf_free	(CCGSubSurf *ss);
 
 CCGError	ccgSubSurf_initFullSync		(CCGSubSurf *ss);
 CCGError	ccgSubSurf_initPartialSync	(CCGSubSurf *ss);
+#ifdef WITH_OPENSUBDIV
+CCGError	ccgSubSurf_initOpenSubdivSync	(CCGSubSurf *ss);
+#endif
 
 CCGError	ccgSubSurf_syncVert		(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r);
 CCGError	ccgSubSurf_syncEdge		(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r);
@@ -191,16 +194,29 @@ int					ccgFaceIterator_isStopped	(CCGFaceIterator *fi);
 void				ccgFaceIterator_next		(CCGFaceIterator *fi);
 
 #ifdef WITH_OPENSUBDIV
-/* TODO(sergey): fill_quads is actually an invariant and should be part
- * of the prepare routine.
- */
 struct DerivedMesh;
-void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss,
-                                       struct DerivedMesh *dm);
+
+/* Check if topology changed and evaluators are to be re-created. */
+void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, struct DerivedMesh *dm);
+
+/* Create topology refiner from give derived mesh which then later will be
+ * used for GL mesh creation.
+ */
+void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, struct DerivedMesh *dm);
+
+/* Make sure GL mesh exists, up to date and ready to draw. */
 bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl);
+
+/* Draw given partitions of the GL mesh.
+ *
+ * TODO(sergey): fill_quads is actually an invariant and should be part
+ * of the prepare routine.
+ */
 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
                            int start_partition, int num_partitions);
+
 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
+
 bool ccgSubSurf_needGrids(CCGSubSurf *ss);
 
 void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index d7a95e4..372cdec 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -160,7 +160,10 @@ typedef enum {
 	eSyncState_Vert,
 	eSyncState_Edge,
 	eSyncState_Face,
-	eSyncState_Partial
+	eSyncState_Partial,
+#ifdef WITH_OPENSUBDIV
+	eSyncState_OpenSubdiv,
+#endif
 } SyncState;
 
 struct CCGSubSurf {
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index e7987c6..d812e0b 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSur

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list