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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to