[Bf-blender-cvs] [e6bf29e] opensubdiv-modifier: OpenSubdiv: Initial glue to the GPU_material routines

Sergey Sharybin noreply at git.blender.org
Thu Jul 17 20:11:39 CEST 2014


Commit: e6bf29e699fff6de5dbbc1f48b681f9d37deb4f3
Author: Sergey Sharybin
Date:   Thu Jul 17 20:34:20 2014 +0600
https://developer.blender.org/rBe6bf29e699fff6de5dbbc1f48b681f9d37deb4f3

OpenSubdiv: Initial glue to the GPU_material routines

For now this only tested on matcaps, the rest of GLSL display is
considered unworkable.

This implements ability to define geometry shader for the GPU
material which later is to be used for texture coordinates generation.

For now GOU materials are split depending on thether they're used
for OpenSubdiv mesh display or for "regular" mesh display. In the
future it'll be possible to get rid of such a split, but that'd
require a bit of changes in how this stuff is used all over the
place. better to do it after the viewport refactor project.

And we're now officially only supporting GPU-side tessellation
only for rather modern GPU, supporting older ones becomeng more
and more difficult. If GPU does not support recent GLSL shading
then Blender will fallback to CPU-side grids evaluation, but it
will still happen using OpenSubdiv. So in the future (once we'll
support uniform subdivisions in evlauator API) there'll be no
differences between old and new GPU visualization.

For those who're using older GPU added new compute type in user
preferences which is called NONE. This means CPU-side tessellation
will be used.

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

M	intern/opensubdiv/gpu_shader_opensubd_display.glsl
M	intern/opensubdiv/opensubdiv_capi.cc
M	intern/opensubdiv/opensubdiv_capi.h
M	intern/opensubdiv/opensubdiv_gpu_capi.cc
M	source/blender/blenkernel/intern/CCGSubSurf.c
M	source/blender/blenkernel/intern/CCGSubSurf.h
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_extensions.h
M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/SConscript
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_codegen.h
M	source/blender/gpu/intern/gpu_draw.c
M	source/blender/gpu/intern/gpu_extensions.c
M	source/blender/gpu/intern/gpu_material.c
M	source/blender/gpu/intern/gpu_simple_shader.c
A	source/blender/gpu/shaders/gpu_shader_geometry.glsl
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/gpu/shaders/gpu_shader_vertex.glsl
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_userdef.c

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

diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index 631857e..8b191b7 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -39,7 +39,7 @@ struct VertexData {
 #ifdef VERTEX_SHADER
 
 in vec3 normal;
-in vec3 position;
+in vec4 position;
 
 uniform mat4 modelViewMatrix;
 uniform mat3 normalMatrix;
@@ -50,7 +50,7 @@ out block {
 
 void main()
 {
-	outpt.v.position = modelViewMatrix * vec4(position, 1.0);
+	outpt.v.position = modelViewMatrix * position;
 	outpt.v.normal = normalize(normalMatrix * normal);
 }
 
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index eb0e07f..d47661c 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -520,8 +520,19 @@ void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
 	((OsdGLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer();
 }
 
+int openSubdiv_supportGPUDisplay(void)
+{
+	return GL_EXT_geometry_shader4 &&
+	       GL_ARB_gpu_shader5 &&
+	       glProgramParameteriEXT;
+}
+
 int openSubdiv_getAvailableControllers(void)
 {
+	if (!openSubdiv_supportGPUDisplay()) {
+		return 0;
+	}
+
 	int flags = OPENSUBDIV_CONTROLLER_CPU;
 
 #ifdef OPENSUBDIV_HAS_OPENMP
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index bee636f..cb66c77 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -26,7 +26,7 @@
 #ifndef __OPENSUBDIV_CAPI_H__
 #define __OPENSUBDIV_CAPI_H__
 
-#define OPENSUBDIV_LEGACY_DRAW
+#undef OPENSUBDIV_LEGACY_DRAW
 
 #ifdef __cplusplus
 extern "C" {
@@ -94,7 +94,7 @@ void openSubdiv_osdGLDisplayDeinit(void);
  *
  * TODO(sergey): Some of the stuff could be initialized once for all meshes.
  */
-void openSubdiv_osdGLMeshDisplayPrepare(void);
+void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl);
 
 /* Draw patches which corresponds to a given partition. */
 void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
@@ -103,6 +103,7 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
                                  int num_partitions);
 
 /* ** Utility functions ** */
+int openSubdiv_supportGPUDisplay(void);
 int openSubdiv_getAvailableControllers(void);
 void openSubdiv_cleanup(void);
 
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index fe812e6..c5b5d22 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -81,6 +81,8 @@ typedef struct Transform {
 	float normal_matrix[9];
 } Transform;
 
+static bool g_use_osd_glsl = false;
+
 static GLuint g_flat_fill_program = 0;
 static GLuint g_smooth_fill_program = 0;
 static GLuint g_wireframe_program = 0;
@@ -238,11 +240,11 @@ GLuint linkProgram(const char *define)
 	glBindAttribLocation(program, 0, "position");
 	glBindAttribLocation(program, 1, "normal");
 
+#ifdef GLSL_COMPAT_WORKAROUND
 	glProgramParameteriEXT(program,
 	                       GL_GEOMETRY_INPUT_TYPE_EXT,
 	                       GL_LINES_ADJACENCY_EXT);
 
-#ifdef GLSL_COMPAT_WORKAROUND
 	if (strstr(define, "WIREFRAME") == NULL) {
 		glProgramParameteriEXT(program,
 		                       GL_GEOMETRY_OUTPUT_TYPE_EXT,
@@ -392,8 +394,10 @@ void openSubdiv_osdGLDisplayDeinit(void)
 #endif
 }
 
-void openSubdiv_osdGLMeshDisplayPrepare(void)
+void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl)
 {
+	g_use_osd_glsl = use_osd_glsl != 0;
+
 #ifndef OPENSUBDIV_LEGACY_DRAW
 	/* Update transformation matricies. */
 	glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix);
@@ -425,6 +429,21 @@ void openSubdiv_osdGLMeshDisplayPrepare(void)
 static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh,
                                 bool fill_quads)
 {
+	if (!g_use_osd_glsl) {
+		GLint program;
+		glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+		if (program) {
+			GLint model;
+			glGetIntegerv(GL_SHADE_MODEL, &model);
+
+			GLint location = glGetUniformLocation(program, "osd_flat_shading");
+			if (location != -1) {
+				glUniform1i(location, model == GL_FLAT);
+			}
+		}
+		return 0;
+	}
+
 	GLuint program = 0;
 
 #ifndef OPENSUBDIV_LEGACY_DRAW
@@ -459,8 +478,10 @@ static void perform_drawElements(GLuint program,
 {
 	int mode = GL_QUADS;
 #ifndef OPENSUBDIV_LEGACY_DRAW
-	glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"),
-	            patch_index);
+	if (program) {
+		glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"),
+		            patch_index);
+	}
 	mode = GL_LINES_ADJACENCY;
 #else
 	(void) patch_index;
@@ -484,9 +505,11 @@ static void finish_patchDraw(bool fill_quads)
 	glBindVertexArray(0);
 
 #ifndef OPENSUBDIV_LEGACY_DRAW
-	glActiveTexture(GL_TEXTURE0);
-	/* TODO(sergey): Store previously used program and roll back to it? */
-	glUseProgram(0);
+	if (g_use_osd_glsl) {
+		glActiveTexture(GL_TEXTURE0);
+		/* TODO(sergey): Store previously used program and roll back to it? */
+		glUseProgram(0);
+	}
 #endif
 }
 
@@ -547,7 +570,6 @@ static void draw_all_patches(PartitionedGLMeshInterface *mesh,
 			                     patch.GetVertIndex());
 		}
 	}
-
 }
 
 void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index e277a60..577ffe7 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -2314,7 +2314,7 @@ static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
 	MEM_freeN(positions);
 }
 
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss)
+bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl)
 {
 	int compute_type;
 
@@ -2399,7 +2399,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss)
 		openSubdiv_osdGLMeshSynchronize(ss->osd_mesh);
 	}
 
-	openSubdiv_osdGLMeshDisplayPrepare();
+	openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl);
 
 	return true;
 }
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index e962b4d..970da85 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -187,7 +187,10 @@ void				ccgFaceIterator_next		(CCGFaceIterator *fi);
 void				ccgFaceIterator_free		(CCGFaceIterator *fi);
 
 #ifdef WITH_OPENSUBDIV
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss);
+/* TODO(sergey): fill_quads is actually an invariant and should be part
+ * of the prepare routine.
+ */
+bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl);
 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
                            int start_partition, int num_partitions);
 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 375af90..4453b47 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -81,6 +81,10 @@
 
 #include "CCGSubSurf.h"
 
+#ifdef WITH_OPENSUBDIV
+#  include "opensubdiv_capi.h"
+#endif
+
 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
 
 static ThreadRWMutex loops_cache_rwlock = BLI_RWLOCK_INITIALIZER;
@@ -1665,7 +1669,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEd
 #ifdef WITH_OPENSUBDIV
 	if (ccgdm->useGpuBackend) {
 		/* TODO(sergey): We currently only support all edges drawing. */
-		if (ccgSubSurf_prepareGLMesh(ss)) {
+		if (ccgSubSurf_prepareGLMesh(ss, true)) {
 			ccgSubSurf_drawGLMesh(ss, false, -1, -1);
 		}
 		return;
@@ -1793,7 +1797,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 		int i, matnr = -1, shademodel = -1;
 		CCGFaceIterator *fi;
 		int start_partition = 0, num_partitions = 0;
-		if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss) == false)) {
+		if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true) == false)) {
 			return;
 		}
 
@@ -2044,7 +2048,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
 	if (ccgdm->useGpuBackend) {
 		int i, matnr = -1, shademodel = -1;
 		CCGFaceIterator *fi;
-		if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss) == false)) {
+		if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false) == false)) {
 			return;
 		}
 		do_draw = 0;
@@ -2453,7 +2457,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 		if (drawParams != NULL)
 			drawParams(&tmp_tf, (mcol != NULL), mat_nr);
 
-		if (ccgSubSurf_prepareGLMesh(ss)) {
+		if (ccgSubSurf_prepareGLMesh(ss, true)) {
 			ccgSubSurf_drawGLMesh(ss, true, -1, -1);
 		}
 		return;
@@ -4166,7 +4170,9 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
 			bool use_gpu_backend = false;
 
 #ifdef WITH_OPENSUBDIV
-			use_gpu_backend = (flags & SUBSURF_USE_GPU_BACKEND) != 0;
+			use_gpu_backend = (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
+				openSubdiv_supportGPUDisplay() &&
+				U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE;
 #endif
 
 			if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 739deff..075d057 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -60,6 +60,7 @@ set(SRC
 	intern/gpu_codegen.h
 )
 
+data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
@@ -83,6 +84,9 @@ if(WITH_IMAGE_DDS)
 	add_definitions(-DWITH_DDS)
 endif()
 
+if(WITH_OPENSUBDIV)
+	add_definitions(-DWITH_OPENSUBDIV)
+endif()
 
 blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}")
 
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 04c4119..c86ed17 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -168,7 +168,7 @@ int GPU_offscreen_height(GPUOffScreen *ofs);
  * - only for fragment shaders now
  * - must call texture bind before setting a texture as uniform! */
 
-GPU

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list