[Bf-blender-cvs] [52d8778a60] temp-select-pick: Split select code

Campbell Barton noreply at git.blender.org
Tue Mar 7 16:20:26 CET 2017


Commit: 52d8778a60db6d3ad011577a66210f45033188c8
Author: Campbell Barton
Date:   Tue Mar 7 12:36:14 2017 +1100
Branches: temp-select-pick
https://developer.blender.org/rB52d8778a60db6d3ad011577a66210f45033188c8

Split select code

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

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_select.h
M	source/blender/gpu/intern/gpu_select.c
A	source/blender/gpu/intern/gpu_select_pick.c
A	source/blender/gpu/intern/gpu_select_private.h
A	source/blender/gpu/intern/gpu_select_sample_query.c

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 8885209ce0..885ff2ff15 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -57,6 +57,8 @@ set(SRC
 	intern/gpu_init_exit.c
 	intern/gpu_material.c
 	intern/gpu_select.c
+	intern/gpu_select_pick.c
+	intern/gpu_select_sample_query.c
 	intern/gpu_shader.c
 	intern/gpu_texture.c
 
@@ -97,6 +99,7 @@ set(SRC
 	GPU_texture.h
 	intern/gpu_codegen.h
 	intern/gpu_private.h
+	intern/gpu_select_private.h
 )
 
 data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h
index 92e870d406..bdddcec38e 100644
--- a/source/blender/gpu/GPU_select.h
+++ b/source/blender/gpu/GPU_select.h
@@ -37,8 +37,10 @@ struct rctf;
 /* flags for mode of operation */
 enum {
 	GPU_SELECT_ALL                      = 1,
+	/* gpu_select_query */
 	GPU_SELECT_NEAREST_FIRST_PASS       = 2,
 	GPU_SELECT_NEAREST_SECOND_PASS      = 3,
+	/* gpu_select_pick */
 	GPU_SELECT_DEPTH_SORT_ALL           = 4,
 	GPU_SELECT_DEPTH_SORT_NEAREST       = 5,
 };
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index d0ec97c6cb..e610486dee 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -46,215 +46,39 @@
 
 #include "BLI_utildefines.h"
 
-/* Ad hoc number of queries to allocate to skip doing many glGenQueries */
-#define ALLOC_QUERIES 200
+#include "gpu_select_private.h"
 
-/* Alloc number for depths */
-#define ALLOC_DEPTHS 200
-
-#define SELECT_ID_NONE ((unsigned int)0xffffffff)
-
-typedef struct DepthID {
-	unsigned int id;
-	float depth;
-} DepthID;
-
-static int depth_id_cmp(const void *v1, const void *v2)
-{
-	const DepthID *d1 = v1, *d2 = v2;
-	if (d1->id < d2->id) {
-		return -1;
-	}
-	else if (d1->id > d2->id) {
-		return 1;
-	}
-	else {
-		return 0;
-	}
-}
-
-static int depth_cmp(const void *v1, const void *v2)
-{
-	const DepthID *d1 = v1, *d2 = v2;
-	if (d1->depth < d2->depth) {
-		return -1;
-	}
-	else if (d1->depth > d2->depth) {
-		return 1;
-	}
-	else {
-		return 0;
-	}
-}
-
-/* depth sorting */
-typedef struct GPUQueryStateDepth {
-	unsigned int rect_len;
-	float *rect_depth;
-	/* scratch buffer, avoid allocs every time */
-	float *rect_depth_test;
-	rcti clip_rect;
-	/* Pass to glReadPixels (x,y,w,h */
-	int clip_readpixels[4];
-
-	unsigned int prev_id;
-	bool is_init;
-
-	union {
-		struct {
-			unsigned int *rect_id;
-		} nearest;
-		struct {
-			DepthID *hits;
-			unsigned int hits_len;
-			unsigned int hits_len_alloc;
-		} all;
-	};
-} GPUQueryStateDepth;
-
-typedef struct GPUQueryState {
+typedef struct GPUSelectState {
 	/* To ignore selection id calls when not initialized */
 	bool select_is_active;
-	/* Tracks whether a query has been issued so that gpu_load_id can end the previous one */
-	bool query_issued;
-	/* array holding the OpenGL query identifiers */
-	unsigned int *queries;
-	/* array holding the id corresponding to each query */
-	unsigned int *id;
-	/* number of queries in *queries and *id */
-	unsigned int num_of_queries;
-	/* index to the next query to start */
-	unsigned int active_query;
 	/* flag to cache user preference for occlusion based selection */
 	bool use_gpu_select;
-	/* cache on initialization */
-	unsigned int *buffer;
-	/* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
-	unsigned int bufsize;
 	/* mode of operation */
 	char mode;
-	unsigned int index;
-	int oldhits;
+} GPUSelectState;
 
-	GPUQueryStateDepth depth;
-} GPUQueryState;
-
-static GPUQueryState g_query_state = {0};
+static GPUSelectState g_select_state = {0};
 
 /**
  * initialize and provide buffer for results
  */
 void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rctf *input, char mode, int oldhits)
 {
-	printf("gl select\n");
-	g_query_state.select_is_active = true;
-	g_query_state.query_issued = false;
-	g_query_state.active_query = 0;
-	g_query_state.use_gpu_select = GPU_select_query_check_active();
-	g_query_state.num_of_queries = 0;
-	g_query_state.bufsize = bufsize;
-	g_query_state.buffer = buffer;
-	g_query_state.mode = mode;
-	g_query_state.index = 0;
-	g_query_state.oldhits = oldhits;
+	g_select_state.select_is_active = true;
+	g_select_state.use_gpu_select = GPU_select_query_check_active();
+	g_select_state.mode = mode;
 
-	if (!g_query_state.use_gpu_select) {
+	if (!g_select_state.use_gpu_select) {
 		glSelectBuffer(bufsize, (GLuint *)buffer);
 		glRenderMode(GL_SELECT);
 		glInitNames();
 		glPushName(-1);
 	}
-	else if (ELEM(g_query_state.mode, GPU_SELECT_DEPTH_SORT_ALL, GPU_SELECT_DEPTH_SORT_NEAREST)) {
-		float viewport[4];
-
-		glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
-		/* disable writing to the framebuffer */
-		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-		glClear(GL_DEPTH_BUFFER_BIT);
-
-		GPUQueryStateDepth *qsd = &g_query_state.depth;
-
-		BLI_rcti_rctf_copy(&qsd->clip_rect, input);
-
-		glGetFloatv(GL_SCISSOR_BOX, viewport);
-
-		qsd->clip_readpixels[0] = viewport[0];
-		qsd->clip_readpixels[1] = viewport[1];
-		qsd->clip_readpixels[2] = BLI_rcti_size_x(&qsd->clip_rect);
-		qsd->clip_readpixels[3] = BLI_rcti_size_y(&qsd->clip_rect);
-
-
-		glViewport(viewport[0], viewport[1], qsd->clip_readpixels[2], qsd->clip_readpixels[3]);
-
-		const unsigned int rect_len = BLI_rcti_size_x(&qsd->clip_rect) * BLI_rcti_size_y(&qsd->clip_rect);
-		qsd->rect_len = rect_len;
-
-		qsd->rect_depth = MEM_mallocN(sizeof(float) * rect_len, __func__);
-
-		glReadPixels(UNPACK4(qsd->clip_readpixels), GL_DEPTH_COMPONENT, GL_FLOAT, qsd->rect_depth);
-
-		/* scratch buffer (read new values here) */
-		qsd->rect_depth_test = MEM_mallocN(sizeof(float) * rect_len, __func__);
-
-		qsd->prev_id = 0;
-		qsd->is_init = false;
-
-		if (g_query_state.mode == GPU_SELECT_DEPTH_SORT_ALL) {
-			glEnable(GL_DEPTH_TEST);
-			glDepthMask(GL_TRUE);
-			glDepthFunc(GL_ALWAYS);
-
-			qsd->all.hits = MEM_mallocN(sizeof(*qsd->all.hits) * ALLOC_DEPTHS, __func__);
-			qsd->all.hits_len = 0;
-			qsd->all.hits_len_alloc = ALLOC_DEPTHS;
-		}
-		else {
-			glEnable(GL_DEPTH_TEST);
-			glDepthMask(GL_TRUE);
-			glDepthFunc(GL_LEQUAL);
-
-			qsd->nearest.rect_id = MEM_mallocN(sizeof(unsigned int) * rect_len, __func__);
-			memset(qsd->nearest.rect_id, 0xff, sizeof(unsigned int) * rect_len);
-		}
+	else if (ELEM(g_select_state.mode, GPU_SELECT_DEPTH_SORT_ALL, GPU_SELECT_DEPTH_SORT_NEAREST)) {
+		gpu_select_pick_begin(buffer, bufsize, input, mode);
 	}
 	else {
-		float viewport[4];
-
-		g_query_state.num_of_queries = ALLOC_QUERIES;
-
-		g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries), "gpu selection queries");
-		g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
-		glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
-
-		glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
-		/* disable writing to the framebuffer */
-		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-		/* In order to save some fill rate we minimize the viewport using rect.
-		 * We need to get the region of the scissor so that our geometry doesn't
-		 * get rejected before the depth test. Should probably cull rect against
-		 * scissor for viewport but this is a rare case I think */
-		glGetFloatv(GL_SCISSOR_BOX, viewport);
-		glViewport(viewport[0], viewport[1], (int)(input->xmax - input->xmin), (int)(input->ymax - input->ymin));
-
-		/* occlusion queries operates on fragments that pass tests and since we are interested on all
-		 * objects in the view frustum independently of their order, we need to disable the depth test */
-		if (mode == GPU_SELECT_ALL) {
-			glDisable(GL_DEPTH_TEST);
-			glDepthMask(GL_FALSE);
-		}
-		else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
-			glClear(GL_DEPTH_BUFFER_BIT);
-			glEnable(GL_DEPTH_TEST);
-			glDepthMask(GL_TRUE);
-			glDepthFunc(GL_LEQUAL);
-		}
-		else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
-			glEnable(GL_DEPTH_TEST);
-			glDepthMask(GL_FALSE);
-			glDepthFunc(GL_EQUAL);
-		}
+		gpu_select_query_begin(buffer, bufsize, input, mode, oldhits);
 	}
 }
 
@@ -268,89 +92,19 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rctf *in
 bool GPU_select_load_id(unsigned int id)
 {
 	/* if no selection mode active, ignore */
-	if (!g_query_state.select_is_active)
+	if (!g_select_state.select_is_active)
 		return true;
 
-	if (!g_query_state.use_gpu_select) {
+	if (!g_select_state.use_gpu_select) {
 		glLoadName(id);
+		return true;
 	}
-	else if (ELEM(g_query_state.mode, GPU_SELECT_DEPTH_SORT_ALL, GPU_SELECT_DEPTH_SORT_NEAREST)) {
-		GPUQueryStateDepth *qsd = &g_query_state.depth;
-		if (qsd->is_init) {
-			const unsigned int rect_len = qsd->rect_len;
-			glReadPixels(UNPACK4(qsd->clip_readpixels), GL_DEPTH_COMPONENT, GL_FLOAT, qsd->rect_depth_test);
-			/* perform initial memcmp since most cases the array remains unchanged  */
-			if (memcmp(qsd->rect_depth, qsd->rect_depth_test, rect_len * sizeof(float)) != 0) {
-				const unsigned int prev_id = qsd->prev_id;
-				if (g_query_state.mode == GPU_SELECT_DEPTH_SORT_ALL) {
-					/* find the best depth for this pass and store in 'all.hits' */
-					const float *prev = qsd->rect_depth;
-					const float *curr = qsd->rect_depth_test;
-					float depth_best = FLT_MAX;
-					for (unsigned int i = 0; i < rect_len; i++, curr++, prev++) {
-						if (*curr != *prev) {
-							if (depth_best > *curr) {
-								depth_best = *curr;
-							}
-						}
-					}
-					/* ensure enough space */
-					if (UNLIKELY(qsd->all.hits_len == qsd->all.hits_len_alloc)) {
-						qsd->all.hits_len_alloc += ALLOC_DEPTHS;
-						qsd->all.hits = MEM_reallocN(qsd->all.hits, qsd->all.hits_len_alloc * sizeof(*qsd->all.hits));
-					}
-					DepthID *d = &qsd->all.hits[qsd->all.hits_len++];
-					d->id = prev_id;
-					d->depth = depth_best;
-				}
-				else {
-					/* keep track each pixels ID in 'nearest.rect_id' */
-					if (prev_id != SELECT_ID_NONE) {
-						const float *prev = qsd->rect_depth;
-						const float *curr = qsd->rect_depth_test;
-						unsigned int *id

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list