[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