Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / draw / intern / draw_manager_exec.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file \ingroup draw
20  */
21
22 #include "draw_manager.h"
23
24 #include "BLI_mempool.h"
25
26
27 #include "BKE_global.h"
28
29 #include "GPU_draw.h"
30 #include "GPU_extensions.h"
31 #include "intern/gpu_shader_private.h"
32
33 #ifdef USE_GPU_SELECT
34 #  include "GPU_select.h"
35 #endif
36
37 #ifdef USE_GPU_SELECT
38 void DRW_select_load_id(uint id)
39 {
40         BLI_assert(G.f & G_FLAG_PICKSEL);
41         DST.select_id = id;
42 }
43 #endif
44
45 #define DEBUG_UBO_BINDING
46
47 struct GPUUniformBuffer *view_ubo;
48
49 /* -------------------------------------------------------------------- */
50 /** \name Draw State (DRW_state)
51  * \{ */
52
53 void drw_state_set(DRWState state)
54 {
55         if (DST.state == state) {
56                 return;
57         }
58
59 #define CHANGED_TO(f) \
60         ((DST.state_lock & (f)) ? 0 : \
61          (((DST.state & (f)) ? \
62            ((state & (f)) ?  0 : -1) : \
63            ((state & (f)) ?  1 :  0))))
64
65 #define CHANGED_ANY(f) \
66         (((DST.state & (f)) != (state & (f))) && \
67          ((DST.state_lock & (f)) == 0))
68
69 #define CHANGED_ANY_STORE_VAR(f, enabled) \
70         (((DST.state & (f)) != (enabled = (state & (f)))) && \
71          (((DST.state_lock & (f)) == 0)))
72
73         /* Depth Write */
74         {
75                 int test;
76                 if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
77                         if (test == 1) {
78                                 glDepthMask(GL_TRUE);
79                         }
80                         else {
81                                 glDepthMask(GL_FALSE);
82                         }
83                 }
84         }
85
86         /* Color Write */
87         {
88                 int test;
89                 if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
90                         if (test == 1) {
91                                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
92                         }
93                         else {
94                                 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
95                         }
96                 }
97         }
98
99         /* Raster Discard */
100         {
101                 if (CHANGED_ANY(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR |
102                                 DRW_STATE_WRITE_STENCIL |
103                                 DRW_STATE_WRITE_STENCIL_SHADOW_PASS |
104                                 DRW_STATE_WRITE_STENCIL_SHADOW_FAIL))
105                 {
106                         if ((state & (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR |
107                                       DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW_PASS |
108                                       DRW_STATE_WRITE_STENCIL_SHADOW_FAIL)) != 0)
109                         {
110                                 glDisable(GL_RASTERIZER_DISCARD);
111                         }
112                         else {
113                                 glEnable(GL_RASTERIZER_DISCARD);
114                         }
115                 }
116         }
117
118         /* Cull */
119         {
120                 DRWState test;
121                 if (CHANGED_ANY_STORE_VAR(
122                         DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT,
123                         test))
124                 {
125                         if (test) {
126                                 glEnable(GL_CULL_FACE);
127
128                                 if ((state & DRW_STATE_CULL_BACK) != 0) {
129                                         glCullFace(GL_BACK);
130                                 }
131                                 else if ((state & DRW_STATE_CULL_FRONT) != 0) {
132                                         glCullFace(GL_FRONT);
133                                 }
134                                 else {
135                                         BLI_assert(0);
136                                 }
137                         }
138                         else {
139                                 glDisable(GL_CULL_FACE);
140                         }
141                 }
142         }
143
144         /* Depth Test */
145         {
146                 DRWState test;
147                 if (CHANGED_ANY_STORE_VAR(
148                         DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
149                         DRW_STATE_DEPTH_GREATER | DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_DEPTH_ALWAYS,
150                         test))
151                 {
152                         if (test) {
153                                 glEnable(GL_DEPTH_TEST);
154
155                                 if (state & DRW_STATE_DEPTH_LESS) {
156                                         glDepthFunc(GL_LESS);
157                                 }
158                                 else if (state & DRW_STATE_DEPTH_LESS_EQUAL) {
159                                         glDepthFunc(GL_LEQUAL);
160                                 }
161                                 else if (state & DRW_STATE_DEPTH_EQUAL) {
162                                         glDepthFunc(GL_EQUAL);
163                                 }
164                                 else if (state & DRW_STATE_DEPTH_GREATER) {
165                                         glDepthFunc(GL_GREATER);
166                                 }
167                                 else if (state & DRW_STATE_DEPTH_GREATER_EQUAL) {
168                                         glDepthFunc(GL_GEQUAL);
169                                 }
170                                 else if (state & DRW_STATE_DEPTH_ALWAYS) {
171                                         glDepthFunc(GL_ALWAYS);
172                                 }
173                                 else {
174                                         BLI_assert(0);
175                                 }
176                         }
177                         else {
178                                 glDisable(GL_DEPTH_TEST);
179                         }
180                 }
181         }
182
183         /* Wire Width */
184         {
185                 int test;
186                 if (CHANGED_ANY_STORE_VAR(
187                         DRW_STATE_WIRE | DRW_STATE_WIRE_WIDE | DRW_STATE_WIRE_SMOOTH,
188                         test))
189                 {
190                         if (test & DRW_STATE_WIRE_WIDE) {
191                                 GPU_line_width(3.0f);
192                         }
193                         else if (test & DRW_STATE_WIRE_SMOOTH) {
194                                 GPU_line_width(2.0f);
195                                 GPU_line_smooth(true);
196                         }
197                         else if (test & DRW_STATE_WIRE) {
198                                 GPU_line_width(1.0f);
199                         }
200                         else {
201                                 GPU_line_width(1.0f);
202                                 GPU_line_smooth(false);
203                         }
204                 }
205         }
206
207         /* Points Size */
208         {
209                 int test;
210                 if ((test = CHANGED_TO(DRW_STATE_POINT))) {
211                         if (test == 1) {
212                                 GPU_enable_program_point_size();
213                                 glPointSize(5.0f);
214                         }
215                         else {
216                                 GPU_disable_program_point_size();
217                         }
218                 }
219         }
220
221         /* Blending (all buffer) */
222         {
223                 int test;
224                 if (CHANGED_ANY_STORE_VAR(
225                         DRW_STATE_BLEND | DRW_STATE_BLEND_PREMUL | DRW_STATE_ADDITIVE |
226                         DRW_STATE_MULTIPLY | DRW_STATE_ADDITIVE_FULL |
227                         DRW_STATE_BLEND_OIT,
228                         test))
229                 {
230                         if (test) {
231                                 glEnable(GL_BLEND);
232
233                                 if ((state & DRW_STATE_BLEND) != 0) {
234                                         glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, /* RGB */
235                                                             GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
236                                 }
237                                 else if ((state & DRW_STATE_BLEND_PREMUL) != 0) {
238                                         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
239                                 }
240                                 else if ((state & DRW_STATE_MULTIPLY) != 0) {
241                                         glBlendFunc(GL_DST_COLOR, GL_ZERO);
242                                 }
243                                 else if ((state & DRW_STATE_BLEND_OIT) != 0) {
244                                         glBlendFuncSeparate(GL_ONE, GL_ONE, /* RGB */
245                                                             GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
246                                 }
247                                 else if ((state & DRW_STATE_ADDITIVE) != 0) {
248                                         /* Do not let alpha accumulate but premult the source RGB by it. */
249                                         glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, /* RGB */
250                                                             GL_ZERO, GL_ONE); /* Alpha */
251                                 }
252                                 else if ((state & DRW_STATE_ADDITIVE_FULL) != 0) {
253                                         /* Let alpha accumulate. */
254                                         glBlendFunc(GL_ONE, GL_ONE);
255                                 }
256                                 else {
257                                         BLI_assert(0);
258                                 }
259                         }
260                         else {
261                                 glDisable(GL_BLEND);
262                                 glBlendFunc(GL_ONE, GL_ONE); /* Don't multiply incoming color by alpha. */
263                         }
264                 }
265         }
266
267         /* Clip Planes */
268         {
269                 int test;
270                 if ((test = CHANGED_TO(DRW_STATE_CLIP_PLANES))) {
271                         if (test == 1) {
272                                 for (int i = 0; i < DST.clip_planes_len; ++i) {
273                                         glEnable(GL_CLIP_DISTANCE0 + i);
274                                 }
275                         }
276                         else {
277                                 for (int i = 0; i < MAX_CLIP_PLANES; ++i) {
278                                         glDisable(GL_CLIP_DISTANCE0 + i);
279                                 }
280                         }
281                 }
282         }
283
284         /* Stencil */
285         {
286                 DRWState test;
287                 if (CHANGED_ANY_STORE_VAR(
288                         DRW_STATE_WRITE_STENCIL |
289                         DRW_STATE_WRITE_STENCIL_SHADOW_PASS |
290                         DRW_STATE_WRITE_STENCIL_SHADOW_FAIL |
291                         DRW_STATE_STENCIL_EQUAL |
292                         DRW_STATE_STENCIL_NEQUAL,
293                         test))
294                 {
295                         if (test) {
296                                 glEnable(GL_STENCIL_TEST);
297                                 /* Stencil Write */
298                                 if ((state & DRW_STATE_WRITE_STENCIL) != 0) {
299                                         glStencilMask(0xFF);
300                                         glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
301                                 }
302                                 else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW_PASS) != 0) {
303                                         glStencilMask(0xFF);
304                                         glStencilOpSeparate(GL_BACK,  GL_KEEP, GL_KEEP, GL_INCR_WRAP);
305                                         glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
306                                 }
307                                 else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) != 0) {
308                                         glStencilMask(0xFF);
309                                         glStencilOpSeparate(GL_BACK,  GL_KEEP, GL_DECR_WRAP, GL_KEEP);
310                                         glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
311                                 }
312                                 /* Stencil Test */
313                                 else if ((state & (DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)) != 0) {
314                                         glStencilMask(0x00); /* disable write */
315                                         DST.stencil_mask = STENCIL_UNDEFINED;
316                                 }
317                                 else {
318                                         BLI_assert(0);
319                                 }
320                         }
321                         else {
322                                 /* disable write & test */
323                                 DST.stencil_mask = 0;
324                                 glStencilMask(0x00);
325                                 glStencilFunc(GL_ALWAYS, 0, 0xFF);
326                                 glDisable(GL_STENCIL_TEST);
327                         }
328                 }
329         }
330
331         /* Provoking Vertex */
332         {
333                 int test;
334                 if ((test = CHANGED_TO(DRW_STATE_FIRST_VERTEX_CONVENTION))) {
335                         if (test == 1) {
336                                 glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
337                         }
338                         else {
339                                 glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
340                         }
341                 }
342         }
343
344         /* Polygon Offset */
345         {
346                 int test;
347                 if (CHANGED_ANY_STORE_VAR(
348                         DRW_STATE_OFFSET_POSITIVE |
349                         DRW_STATE_OFFSET_NEGATIVE,
350                         test))
351                 {
352                         if (test) {
353                                 glEnable(GL_POLYGON_OFFSET_FILL);
354                                 glEnable(GL_POLYGON_OFFSET_LINE);
355                                 glEnable(GL_POLYGON_OFFSET_POINT);
356                                 /* Stencil Write */
357                                 if ((state & DRW_STATE_OFFSET_POSITIVE) != 0) {
358                                         glPolygonOffset(1.0f, 1.0f);
359                                 }
360                                 else if ((state & DRW_STATE_OFFSET_NEGATIVE) != 0) {
361                                         glPolygonOffset(-1.0f, -1.0f);
362                                 }
363                                 else {
364                                         BLI_assert(0);
365                                 }
366                         }
367                         else {
368                                 glDisable(GL_POLYGON_OFFSET_FILL);
369                                 glDisable(GL_POLYGON_OFFSET_LINE);
370                                 glDisable(GL_POLYGON_OFFSET_POINT);
371                         }
372                 }
373         }
374
375 #undef CHANGED_TO
376 #undef CHANGED_ANY
377 #undef CHANGED_ANY_STORE_VAR
378
379         DST.state = state;
380 }
381
382 static void drw_stencil_set(uint mask)
383 {
384         if (DST.stencil_mask != mask) {
385                 DST.stencil_mask = mask;
386                 /* Stencil Write */
387                 if ((DST.state & DRW_STATE_WRITE_STENCIL) != 0) {
388                         glStencilFunc(GL_ALWAYS, mask, 0xFF);
389                 }
390                 /* Stencil Test */
391                 else if ((DST.state & DRW_STATE_STENCIL_EQUAL) != 0) {
392                         glStencilFunc(GL_EQUAL, mask, 0xFF);
393                 }
394                 else if ((DST.state & DRW_STATE_STENCIL_NEQUAL) != 0) {
395                         glStencilFunc(GL_NOTEQUAL, mask, 0xFF);
396                 }
397         }
398 }
399
400 /* Reset state to not interfer with other UI drawcall */
401 void DRW_state_reset_ex(DRWState state)
402 {
403         DST.state = ~state;
404         drw_state_set(state);
405 }
406
407 /**
408  * Use with care, intended so selection code can override passes depth settings,
409  * which is important for selection to work properly.
410  *
411  * Should be set in main draw loop, cleared afterwards
412  */
413 void DRW_state_lock(DRWState state)
414 {
415         DST.state_lock = state;
416 }
417
418 void DRW_state_reset(void)
419 {
420         DRW_state_reset_ex(DRW_STATE_DEFAULT);
421
422         /* Reset blending function */
423         glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
424 }
425
426 /* NOTE : Make sure to reset after use! */
427 void DRW_state_invert_facing(void)
428 {
429         SWAP(GLenum, DST.backface, DST.frontface);
430         glFrontFace(DST.frontface);
431 }
432
433 /**
434  * This only works if DRWPasses have been tagged with DRW_STATE_CLIP_PLANES,
435  * and if the shaders have support for it (see usage of gl_ClipDistance).
436  * Be sure to call DRW_state_clip_planes_reset() after you finish drawing.
437  **/
438 void DRW_state_clip_planes_len_set(uint plane_len)
439 {
440         BLI_assert(plane_len <= MAX_CLIP_PLANES);
441         DST.clip_planes_len = plane_len;
442 }
443
444 void DRW_state_clip_planes_reset(void)
445 {
446         DST.clip_planes_len = 0;
447 }
448
449 void DRW_state_clip_planes_set_from_rv3d(RegionView3D *rv3d)
450 {
451         int max_len = 6;
452         int real_len = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : max_len;
453         while (real_len < max_len) {
454                 /* Fill in dummy values that wont change results (6 is hard coded in shaders). */
455                 copy_v4_v4(rv3d->clip[real_len], rv3d->clip[3]);
456                 real_len++;
457         }
458
459         DRW_state_clip_planes_len_set(max_len);
460 }
461
462 /** \} */
463
464 /* -------------------------------------------------------------------- */
465 /** \name Clipping (DRW_clipping)
466  * \{ */
467
468 /* Extract the 8 corners from a Projection Matrix.
469  * Although less accurate, this solution can be simplified as follows:
470  * BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const float[3]){1.0f, 1.0f, 1.0f});
471  * for (int i = 0; i < 8; i++) {mul_project_m4_v3(projinv, bbox.vec[i]);}
472  */
473 static void draw_frustum_boundbox_calc(const float(*projmat)[4], BoundBox *r_bbox)
474 {
475         float near, far, left, right, bottom, top;
476         bool is_persp = projmat[3][3] == 0.0f;
477
478         if (is_persp) {
479                 near   = projmat[3][2] / (projmat[2][2] - 1.0f);
480                 far    = projmat[3][2] / (projmat[2][2] + 1.0f);
481                 left   = near * (projmat[2][0] - 1.0f) / projmat[0][0];
482                 right  = near * (projmat[2][0] + 1.0f) / projmat[0][0];
483                 bottom = near * (projmat[2][1] - 1.0f) / projmat[1][1];
484                 top    = near * (projmat[2][1] + 1.0f) / projmat[1][1];
485         }
486         else {
487                 near   = ( projmat[3][2] + 1.0f) / projmat[2][2];
488                 far    = ( projmat[3][2] - 1.0f) / projmat[2][2];
489                 left   = (-projmat[3][0] - 1.0f) / projmat[0][0];
490                 right  = (-projmat[3][0] + 1.0f) / projmat[0][0];
491                 bottom = (-projmat[3][1] - 1.0f) / projmat[1][1];
492                 top    = (-projmat[3][1] + 1.0f) / projmat[1][1];
493         }
494
495         r_bbox->vec[0][2] = r_bbox->vec[3][2] = r_bbox->vec[7][2] = r_bbox->vec[4][2] = -near;
496         r_bbox->vec[0][0] = r_bbox->vec[3][0] = left;
497         r_bbox->vec[4][0] = r_bbox->vec[7][0] = right;
498         r_bbox->vec[0][1] = r_bbox->vec[4][1] = bottom;
499         r_bbox->vec[7][1] = r_bbox->vec[3][1] = top;
500
501         /* Get the coordinates of the far plane. */
502         if (is_persp) {
503                 float sca_far = far / near;
504                 left   *= sca_far;
505                 bottom *= sca_far;
506                 right  *= sca_far;
507                 top    *= sca_far;
508         }
509
510         r_bbox->vec[1][2] = r_bbox->vec[2][2] = r_bbox->vec[6][2] = r_bbox->vec[5][2] = -far;
511         r_bbox->vec[1][0] = r_bbox->vec[2][0] = left;
512         r_bbox->vec[6][0] = r_bbox->vec[5][0] = right;
513         r_bbox->vec[1][1] = r_bbox->vec[5][1] = bottom;
514         r_bbox->vec[2][1] = r_bbox->vec[6][1] = top;
515 }
516
517 static void draw_clipping_setup_from_view(void)
518 {
519         if (DST.clipping.updated) {
520                 return;
521         }
522
523         float (*viewinv)[4] = DST.view_data.matstate.mat[DRW_MAT_VIEWINV];
524         float (*projmat)[4] = DST.view_data.matstate.mat[DRW_MAT_WIN];
525         float (*projinv)[4] = DST.view_data.matstate.mat[DRW_MAT_WININV];
526         BoundSphere *bsphere = &DST.clipping.frustum_bsphere;
527
528         /* Extract Clipping Planes */
529         BoundBox bbox;
530 #if 0 /* It has accuracy problems. */
531         BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const float[3]){1.0f, 1.0f, 1.0f});
532         for (int i = 0; i < 8; i++) {
533                 mul_project_m4_v3(projinv, bbox.vec[i]);
534         }
535 #else
536         draw_frustum_boundbox_calc(projmat, &bbox);
537 #endif
538         /* Transform into world space. */
539         for (int i = 0; i < 8; i++) {
540                 mul_m4_v3(viewinv, bbox.vec[i]);
541         }
542
543         memcpy(&DST.clipping.frustum_corners, &bbox, sizeof(BoundBox));
544
545         /* Compute clip planes using the world space frustum corners. */
546         for (int p = 0; p < 6; p++) {
547                 int q, r, s;
548                 switch (p) {
549                         case 0:  q = 1; r = 2; s = 3; break; /* -X */
550                         case 1:  q = 0; r = 4; s = 5; break; /* -Y */
551                         case 2:  q = 1; r = 5; s = 6; break; /* +Z (far) */
552                         case 3:  q = 2; r = 6; s = 7; break; /* +Y */
553                         case 4:  q = 0; r = 3; s = 7; break; /* -Z (near) */
554                         default: q = 4; r = 7; s = 6; break; /* +X */
555                 }
556                 if (DST.frontface == GL_CW) {
557                         SWAP(int, q, s);
558                 }
559
560                 normal_quad_v3(DST.clipping.frustum_planes[p], bbox.vec[p], bbox.vec[q], bbox.vec[r], bbox.vec[s]);
561                 /* Increase precision and use the mean of all 4 corners. */
562                 DST.clipping.frustum_planes[p][3]  = -dot_v3v3(DST.clipping.frustum_planes[p], bbox.vec[p]);
563                 DST.clipping.frustum_planes[p][3] += -dot_v3v3(DST.clipping.frustum_planes[p], bbox.vec[q]);
564                 DST.clipping.frustum_planes[p][3] += -dot_v3v3(DST.clipping.frustum_planes[p], bbox.vec[r]);
565                 DST.clipping.frustum_planes[p][3] += -dot_v3v3(DST.clipping.frustum_planes[p], bbox.vec[s]);
566                 DST.clipping.frustum_planes[p][3] *= 0.25f;
567         }
568
569         /* Extract Bounding Sphere */
570         if (projmat[3][3] != 0.0f) {
571                 /* Orthographic */
572                 /* The most extreme points on the near and far plane. (normalized device coords). */
573                 float *nearpoint = bbox.vec[0];
574                 float *farpoint = bbox.vec[6];
575
576                 /* just use median point */
577                 mid_v3_v3v3(bsphere->center, farpoint, nearpoint);
578                 bsphere->radius = len_v3v3(bsphere->center, farpoint);
579         }
580         else if (projmat[2][0] == 0.0f && projmat[2][1] == 0.0f) {
581                 /* Perspective with symmetrical frustum. */
582
583                 /* We obtain the center and radius of the circumscribed circle of the
584                  * isosceles trapezoid composed by the diagonals of the near and far clipping plane */
585
586                 /* center of each clipping plane */
587                 float mid_min[3], mid_max[3];
588                 mid_v3_v3v3(mid_min, bbox.vec[3], bbox.vec[4]);
589                 mid_v3_v3v3(mid_max, bbox.vec[2], bbox.vec[5]);
590
591                 /* square length of the diagonals of each clipping plane */
592                 float a_sq = len_squared_v3v3(bbox.vec[3], bbox.vec[4]);
593                 float b_sq = len_squared_v3v3(bbox.vec[2], bbox.vec[5]);
594
595                 /* distance squared between clipping planes */
596                 float h_sq = len_squared_v3v3(mid_min, mid_max);
597
598                 float fac = (4 * h_sq + b_sq - a_sq) / (8 * h_sq);
599
600                 /* The goal is to get the smallest sphere,
601                  * not the sphere that passes through each corner */
602                 CLAMP(fac, 0.0f, 1.0f);
603
604                 interp_v3_v3v3(bsphere->center, mid_min, mid_max, fac);
605
606                 /* distance from the center to one of the points of the far plane (1, 2, 5, 6) */
607                 bsphere->radius = len_v3v3(bsphere->center, bbox.vec[1]);
608         }
609         else {
610                 /* Perspective with asymmetrical frustum. */
611
612                 /* We put the sphere center on the line that goes from origin
613                  * to the center of the far clipping plane. */
614
615                 /* Detect which of the corner of the far clipping plane is the farthest to the origin */
616                 float nfar[4];       /* most extreme far point in NDC space */
617                 float farxy[2];      /* farpoint projection onto the near plane */
618                 float farpoint[3] = {0.0f}; /* most extreme far point in camera coordinate */
619                 float nearpoint[3];  /* most extreme near point in camera coordinate */
620                 float farcenter[3] = {0.0f}; /* center of far cliping plane in camera coordinate */
621                 float F = -1.0f, N;  /* square distance of far and near point to origin */
622                 float f, n;          /* distance of far and near point to z axis. f is always > 0 but n can be < 0 */
623                 float e, s;          /* far and near clipping distance (<0) */
624                 float c;             /* slope of center line = distance of far clipping center to z axis / far clipping distance */
625                 float z;             /* projection of sphere center on z axis (<0) */
626
627                 /* Find farthest corner and center of far clip plane. */
628                 float corner[3] = {1.0f, 1.0f, 1.0f}; /* in clip space */
629                 for (int i = 0; i < 4; i++) {
630                         float point[3];
631                         mul_v3_project_m4_v3(point, projinv, corner);
632                         float len = len_squared_v3(point);
633                         if (len > F) {
634                                 copy_v3_v3(nfar, corner);
635                                 copy_v3_v3(farpoint, point);
636                                 F = len;
637                         }
638                         add_v3_v3(farcenter, point);
639                         /* rotate by 90 degree to walk through the 4 points of the far clip plane */
640                         float tmp = corner[0];
641                         corner[0] = -corner[1];
642                         corner[1] = tmp;
643                 }
644
645                 /* the far center is the average of the far clipping points */
646                 mul_v3_fl(farcenter, 0.25f);
647                 /* the extreme near point is the opposite point on the near clipping plane */
648                 copy_v3_fl3(nfar, -nfar[0], -nfar[1], -1.0f);
649                 mul_v3_project_m4_v3(nearpoint, projinv, nfar);
650                 /* this is a frustum projection */
651                 N = len_squared_v3(nearpoint);
652                 e = farpoint[2];
653                 s = nearpoint[2];
654                 /* distance to view Z axis */
655                 f = len_v2(farpoint);
656                 /* get corresponding point on the near plane */
657                 mul_v2_v2fl(farxy, farpoint, s / e);
658                 /* this formula preserve the sign of n */
659                 sub_v2_v2(nearpoint, farxy);
660                 n = f * s / e - len_v2(nearpoint);
661                 c = len_v2(farcenter) / e;
662                 /* the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case */
663                 z = (F - N) / (2.0f * (e - s + c * (f - n)));
664
665                 bsphere->center[0] = farcenter[0] * z / e;
666                 bsphere->center[1] = farcenter[1] * z / e;
667                 bsphere->center[2] = z;
668                 bsphere->radius = len_v3v3(bsphere->center, farpoint);
669
670                 /* Transform to world space. */
671                 mul_m4_v3(viewinv, bsphere->center);
672         }
673
674         DST.clipping.updated = true;
675 }
676
677 /* Return True if the given BoundSphere intersect the current view frustum */
678 bool DRW_culling_sphere_test(BoundSphere *bsphere)
679 {
680         draw_clipping_setup_from_view();
681
682         /* Bypass test if radius is negative. */
683         if (bsphere->radius < 0.0f) {
684                 return true;
685         }
686
687         /* Do a rough test first: Sphere VS Sphere intersect. */
688         BoundSphere *frustum_bsphere = &DST.clipping.frustum_bsphere;
689         float center_dist = len_squared_v3v3(bsphere->center, frustum_bsphere->center);
690         if (center_dist > SQUARE(bsphere->radius + frustum_bsphere->radius)) {
691                 return false;
692         }
693
694         /* Test against the 6 frustum planes. */
695         for (int p = 0; p < 6; p++) {
696                 float dist = plane_point_side_v3(DST.clipping.frustum_planes[p], bsphere->center);
697                 if (dist < -bsphere->radius) {
698                         return false;
699                 }
700         }
701
702         return true;
703 }
704
705 /* Return True if the given BoundBox intersect the current view frustum.
706  * bbox must be in world space. */
707 bool DRW_culling_box_test(BoundBox *bbox)
708 {
709         draw_clipping_setup_from_view();
710
711         /* 6 view frustum planes */
712         for (int p = 0; p < 6; p++) {
713                 /* 8 box vertices. */
714                 for (int v = 0; v < 8 ; v++) {
715                         float dist = plane_point_side_v3(DST.clipping.frustum_planes[p], bbox->vec[v]);
716                         if (dist > 0.0f) {
717                                 /* At least one point in front of this plane.
718                                  * Go to next plane. */
719                                 break;
720                         }
721                         else if (v == 7) {
722                                 /* 8 points behind this plane. */
723                                 return false;
724                         }
725                 }
726         }
727
728         return true;
729 }
730
731 /* Return True if the current view frustum is inside or intersect the given plane */
732 bool DRW_culling_plane_test(float plane[4])
733 {
734         draw_clipping_setup_from_view();
735
736         /* Test against the 8 frustum corners. */
737         for (int c = 0; c < 8; c++) {
738                 float dist = plane_point_side_v3(plane, DST.clipping.frustum_corners.vec[c]);
739                 if (dist < 0.0f) {
740                         return true;
741                 }
742         }
743
744         return false;
745 }
746
747 void DRW_culling_frustum_corners_get(BoundBox *corners)
748 {
749         draw_clipping_setup_from_view();
750         memcpy(corners, &DST.clipping.frustum_corners, sizeof(BoundBox));
751 }
752
753 /* See draw_clipping_setup_from_view() for the plane order. */
754 void DRW_culling_frustum_planes_get(float planes[6][4])
755 {
756         draw_clipping_setup_from_view();
757         memcpy(planes, &DST.clipping.frustum_planes, sizeof(DST.clipping.frustum_planes));
758 }
759
760 /** \} */
761
762 /* -------------------------------------------------------------------- */
763 /** \name Draw (DRW_draw)
764  * \{ */
765
766 static void draw_visibility_eval(DRWCallState *st)
767 {
768         bool culled = st->flag & DRW_CALL_CULLED;
769
770         if (st->cache_id != DST.state_cache_id) {
771                 /* Update culling result for this view. */
772                 culled = !DRW_culling_sphere_test(&st->bsphere);
773         }
774
775         if (st->visibility_cb) {
776                 culled = !st->visibility_cb(!culled, st->user_data);
777         }
778
779         SET_FLAG_FROM_TEST(st->flag, culled, DRW_CALL_CULLED);
780 }
781
782 static void draw_matrices_model_prepare(DRWCallState *st)
783 {
784         if (st->cache_id == DST.state_cache_id) {
785                 /* Values are already updated for this view. */
786                 return;
787         }
788         else {
789                 st->cache_id = DST.state_cache_id;
790         }
791
792         /* No need to go further the call will not be used. */
793         if ((st->flag & DRW_CALL_CULLED) != 0 &&
794             (st->flag & DRW_CALL_BYPASS_CULLING) == 0)
795         {
796                 return;
797         }
798         /* Order matters */
799         if (st->matflag & (DRW_CALL_MODELVIEW | DRW_CALL_MODELVIEWINVERSE |
800                            DRW_CALL_NORMALVIEW | DRW_CALL_EYEVEC))
801         {
802                 mul_m4_m4m4(st->modelview, DST.view_data.matstate.mat[DRW_MAT_VIEW], st->model);
803         }
804         if (st->matflag & DRW_CALL_MODELVIEWINVERSE) {
805                 invert_m4_m4(st->modelviewinverse, st->modelview);
806         }
807         if (st->matflag & DRW_CALL_MODELVIEWPROJECTION) {
808                 mul_m4_m4m4(st->modelviewprojection, DST.view_data.matstate.mat[DRW_MAT_PERS], st->model);
809         }
810         if (st->matflag & (DRW_CALL_NORMALVIEW | DRW_CALL_EYEVEC)) {
811                 copy_m3_m4(st->normalview, st->modelview);
812                 invert_m3(st->normalview);
813                 transpose_m3(st->normalview);
814         }
815         if (st->matflag & DRW_CALL_EYEVEC) {
816                 /* Used by orthographic wires */
817                 float tmp[3][3];
818                 copy_v3_fl3(st->eyevec, 0.0f, 0.0f, 1.0f);
819                 invert_m3_m3(tmp, st->normalview);
820                 /* set eye vector, transformed to object coords */
821                 mul_m3_v3(tmp, st->eyevec);
822         }
823         /* Non view dependent */
824         if (st->matflag & DRW_CALL_MODELINVERSE) {
825                 invert_m4_m4(st->modelinverse, st->model);
826                 st->matflag &= ~DRW_CALL_MODELINVERSE;
827         }
828         if (st->matflag & DRW_CALL_NORMALWORLD) {
829                 copy_m3_m4(st->normalworld, st->model);
830                 invert_m3(st->normalworld);
831                 transpose_m3(st->normalworld);
832                 st->matflag &= ~DRW_CALL_NORMALWORLD;
833         }
834 }
835
836 static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
837 {
838         /* step 1 : bind object dependent matrices */
839         if (call != NULL) {
840                 DRWCallState *state = call->state;
841                 float objectinfo[3];
842                 objectinfo[0] = state->objectinfo[0];
843                 objectinfo[1] = call->single.ma_index; /* WATCH this is only valid for single drawcalls. */
844                 objectinfo[2] = state->objectinfo[1];
845
846                 GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model);
847                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse);
848                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelview, 16, 1, (float *)state->modelview);
849                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewinverse, 16, 1, (float *)state->modelviewinverse);
850                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)state->modelviewprojection);
851                 GPU_shader_uniform_vector(shgroup->shader, shgroup->normalview, 9, 1, (float *)state->normalview);
852                 GPU_shader_uniform_vector(shgroup->shader, shgroup->normalworld, 9, 1, (float *)state->normalworld);
853                 GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 3, 1, (float *)objectinfo);
854                 GPU_shader_uniform_vector(shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
855                 GPU_shader_uniform_vector(shgroup->shader, shgroup->eye, 3, 1, (float *)state->eyevec);
856         }
857         else {
858                 BLI_assert((shgroup->normalview == -1) && (shgroup->normalworld == -1) && (shgroup->eye == -1));
859                 /* For instancing and batching. */
860                 float unitmat[4][4];
861                 unit_m4(unitmat);
862                 GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)unitmat);
863                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelinverse, 16, 1, (float *)unitmat);
864                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelview, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_VIEW]);
865                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewinverse, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_VIEWINV]);
866                 GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_PERS]);
867                 GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 3, 1, (float *)unitmat);
868                 GPU_shader_uniform_vector(shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)shgroup->instance_orcofac);
869         }
870 }
871
872 static void draw_geometry_execute_ex(
873         DRWShadingGroup *shgroup, GPUBatch *geom, uint start, uint count, bool draw_instance)
874 {
875         /* Special case: empty drawcall, placement is done via shader, don't bind anything. */
876         /* TODO use DRW_CALL_PROCEDURAL instead */
877         if (geom == NULL) {
878                 BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */
879                 /* Shader is already bound. */
880                 GPU_draw_primitive(GPU_PRIM_TRIS, count);
881                 return;
882         }
883
884         /* step 2 : bind vertex array & draw */
885         GPU_batch_program_set_no_use(
886                 geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
887         /* XXX hacking gawain. we don't want to call glUseProgram! (huge performance loss) */
888         geom->program_in_use = true;
889
890         GPU_batch_draw_range_ex(geom, start, count, draw_instance);
891
892         geom->program_in_use = false; /* XXX hacking gawain */
893 }
894
895 static void draw_geometry_execute(DRWShadingGroup *shgroup, GPUBatch *geom)
896 {
897         draw_geometry_execute_ex(shgroup, geom, 0, 0, false);
898 }
899
900 enum {
901         BIND_NONE = 0,
902         BIND_TEMP = 1,         /* Release slot after this shading group. */
903         BIND_PERSIST = 2,      /* Release slot only after the next shader change. */
904 };
905
906 static void bind_texture(GPUTexture *tex, char bind_type)
907 {
908         int index;
909         char *slot_flags = DST.RST.bound_tex_slots;
910         int bind_num = GPU_texture_bound_number(tex);
911         if (bind_num == -1) {
912                 for (int i = 0; i < GPU_max_textures(); ++i) {
913                         index = DST.RST.bind_tex_inc = (DST.RST.bind_tex_inc + 1) % GPU_max_textures();
914                         if (slot_flags[index] == BIND_NONE) {
915                                 if (DST.RST.bound_texs[index] != NULL) {
916                                         GPU_texture_unbind(DST.RST.bound_texs[index]);
917                                 }
918                                 GPU_texture_bind(tex, index);
919                                 DST.RST.bound_texs[index] = tex;
920                                 slot_flags[index] = bind_type;
921                                 // printf("Binds Texture %d %p\n", DST.RST.bind_tex_inc, tex);
922                                 return;
923                         }
924                 }
925                 printf("Not enough texture slots! Reduce number of textures used by your shader.\n");
926         }
927         slot_flags[bind_num] = bind_type;
928 }
929
930 static void bind_ubo(GPUUniformBuffer *ubo, char bind_type)
931 {
932         int index;
933         char *slot_flags = DST.RST.bound_ubo_slots;
934         int bind_num = GPU_uniformbuffer_bindpoint(ubo);
935         if (bind_num == -1) {
936                 for (int i = 0; i < GPU_max_ubo_binds(); ++i) {
937                         index = DST.RST.bind_ubo_inc = (DST.RST.bind_ubo_inc + 1) % GPU_max_ubo_binds();
938                         if (slot_flags[index] == BIND_NONE) {
939                                 if (DST.RST.bound_ubos[index] != NULL) {
940                                         GPU_uniformbuffer_unbind(DST.RST.bound_ubos[index]);
941                                 }
942                                 GPU_uniformbuffer_bind(ubo, index);
943                                 DST.RST.bound_ubos[index] = ubo;
944                                 slot_flags[index] = bind_type;
945                                 return;
946                         }
947                 }
948                 /* printf so user can report bad behavior */
949                 printf("Not enough ubo slots! This should not happen!\n");
950                 /* This is not depending on user input.
951                  * It is our responsibility to make sure there is enough slots. */
952                 BLI_assert(0);
953         }
954         slot_flags[bind_num] = bind_type;
955 }
956
957 #ifndef NDEBUG
958 /**
959  * Opengl specification is strict on buffer binding.
960  *
961  * " If any active uniform block is not backed by a
962  * sufficiently large buffer object, the results of shader
963  * execution are undefined, and may result in GL interruption or
964  * termination. " - Opengl 3.3 Core Specification
965  *
966  * For now we only check if the binding is correct. Not the size of
967  * the bound ubo.
968  *
969  * See T55475.
970  * */
971 static bool ubo_bindings_validate(DRWShadingGroup *shgroup)
972 {
973         bool valid = true;
974 #  ifdef DEBUG_UBO_BINDING
975         /* Check that all active uniform blocks have a non-zero buffer bound. */
976         GLint program = 0;
977         GLint active_blocks = 0;
978
979         glGetIntegerv(GL_CURRENT_PROGRAM, &program);
980         glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &active_blocks);
981
982         for (uint i = 0; i < active_blocks; ++i) {
983                 int binding = 0;
984                 int buffer = 0;
985
986                 glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_BINDING, &binding);
987                 glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, binding, &buffer);
988
989                 if (buffer == 0) {
990                         char blockname[64];
991                         glGetActiveUniformBlockName(program, i, sizeof(blockname), NULL, blockname);
992
993                         if (valid) {
994                                 printf("Trying to draw with missing UBO binding.\n");
995                                 valid = false;
996                         }
997                         printf("Pass : %s, Shader : %s, Block : %s\n", shgroup->pass_parent->name, shgroup->shader->name, blockname);
998                 }
999         }
1000 #  endif
1001         return valid;
1002 }
1003 #endif
1004
1005 static void release_texture_slots(bool with_persist)
1006 {
1007         if (with_persist) {
1008                 memset(DST.RST.bound_tex_slots, 0x0, sizeof(*DST.RST.bound_tex_slots) * GPU_max_textures());
1009         }
1010         else {
1011                 for (int i = 0; i < GPU_max_textures(); ++i) {
1012                         if (DST.RST.bound_tex_slots[i] != BIND_PERSIST) {
1013                                 DST.RST.bound_tex_slots[i] = BIND_NONE;
1014                         }
1015                 }
1016         }
1017
1018         /* Reset so that slots are consistently assigned for different shader
1019          * draw calls, to avoid shader specialization/patching by the driver. */
1020         DST.RST.bind_tex_inc = 0;
1021 }
1022
1023 static void release_ubo_slots(bool with_persist)
1024 {
1025         if (with_persist) {
1026                 memset(DST.RST.bound_ubo_slots, 0x0, sizeof(*DST.RST.bound_ubo_slots) * GPU_max_ubo_binds());
1027         }
1028         else {
1029                 for (int i = 0; i < GPU_max_ubo_binds(); ++i) {
1030                         if (DST.RST.bound_ubo_slots[i] != BIND_PERSIST) {
1031                                 DST.RST.bound_ubo_slots[i] = BIND_NONE;
1032                         }
1033                 }
1034         }
1035
1036         /* Reset so that slots are consistently assigned for different shader
1037          * draw calls, to avoid shader specialization/patching by the driver. */
1038         DST.RST.bind_ubo_inc = 0;
1039 }
1040
1041 static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
1042 {
1043         BLI_assert(shgroup->shader);
1044
1045         GPUTexture *tex;
1046         GPUUniformBuffer *ubo;
1047         int val;
1048         float fval;
1049         const bool shader_changed = (DST.shader != shgroup->shader);
1050         bool use_tfeedback = false;
1051
1052         if (shader_changed) {
1053                 if (DST.shader) GPU_shader_unbind();
1054                 GPU_shader_bind(shgroup->shader);
1055                 DST.shader = shgroup->shader;
1056         }
1057
1058         if ((pass_state & DRW_STATE_TRANS_FEEDBACK) != 0 &&
1059             (shgroup->type == DRW_SHG_FEEDBACK_TRANSFORM))
1060         {
1061                 use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
1062                                                                      shgroup->tfeedback_target->vbo_id);
1063         }
1064
1065         release_ubo_slots(shader_changed);
1066         release_texture_slots(shader_changed);
1067
1068         drw_state_set((pass_state & shgroup->state_extra_disable) | shgroup->state_extra);
1069         drw_stencil_set(shgroup->stencil_mask);
1070
1071         /* Binding Uniform */
1072         for (DRWUniform *uni = shgroup->uniforms; uni; uni = uni->next) {
1073                 if (uni->location == -2) {
1074                         uni->location = GPU_shader_get_uniform_ensure(shgroup->shader, DST.uniform_names.buffer + uni->name_ofs);
1075                         if (uni->location == -1) {
1076                                 continue;
1077                         }
1078                 }
1079                 switch (uni->type) {
1080                         case DRW_UNIFORM_SHORT_TO_INT:
1081                                 val = (int)*((short *)uni->pvalue);
1082                                 GPU_shader_uniform_vector_int(
1083                                         shgroup->shader, uni->location, uni->length, uni->arraysize, &val);
1084                                 break;
1085                         case DRW_UNIFORM_SHORT_TO_FLOAT:
1086                                 fval = (float)*((short *)uni->pvalue);
1087                                 GPU_shader_uniform_vector(
1088                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)&fval);
1089                                 break;
1090                         case DRW_UNIFORM_BOOL_COPY:
1091                         case DRW_UNIFORM_INT_COPY:
1092                                 GPU_shader_uniform_vector_int(
1093                                         shgroup->shader, uni->location, uni->length, uni->arraysize, &uni->ivalue);
1094                                 break;
1095                         case DRW_UNIFORM_BOOL:
1096                         case DRW_UNIFORM_INT:
1097                                 GPU_shader_uniform_vector_int(
1098                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->pvalue);
1099                                 break;
1100                         case DRW_UNIFORM_FLOAT_COPY:
1101                                 GPU_shader_uniform_vector(
1102                                         shgroup->shader, uni->location, uni->length, uni->arraysize, &uni->fvalue);
1103                                 break;
1104                         case DRW_UNIFORM_FLOAT:
1105                                 GPU_shader_uniform_vector(
1106                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->pvalue);
1107                                 break;
1108                         case DRW_UNIFORM_TEXTURE:
1109                                 tex = (GPUTexture *)uni->pvalue;
1110                                 BLI_assert(tex);
1111                                 bind_texture(tex, BIND_TEMP);
1112                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1113                                 break;
1114                         case DRW_UNIFORM_TEXTURE_PERSIST:
1115                                 tex = (GPUTexture *)uni->pvalue;
1116                                 BLI_assert(tex);
1117                                 bind_texture(tex, BIND_PERSIST);
1118                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1119                                 break;
1120                         case DRW_UNIFORM_TEXTURE_REF:
1121                                 tex = *((GPUTexture **)uni->pvalue);
1122                                 BLI_assert(tex);
1123                                 bind_texture(tex, BIND_TEMP);
1124                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1125                                 break;
1126                         case DRW_UNIFORM_BLOCK:
1127                                 ubo = (GPUUniformBuffer *)uni->pvalue;
1128                                 bind_ubo(ubo, BIND_TEMP);
1129                                 GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
1130                                 break;
1131                         case DRW_UNIFORM_BLOCK_PERSIST:
1132                                 ubo = (GPUUniformBuffer *)uni->pvalue;
1133                                 bind_ubo(ubo, BIND_PERSIST);
1134                                 GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
1135                                 break;
1136                 }
1137         }
1138
1139 #ifdef USE_GPU_SELECT
1140 #  define GPU_SELECT_LOAD_IF_PICKSEL(_select_id) \
1141         if (G.f & G_FLAG_PICKSEL) { \
1142                 GPU_select_load_id(_select_id); \
1143         } ((void)0)
1144
1145 #  define GPU_SELECT_LOAD_IF_PICKSEL_CALL(_call) \
1146         if ((G.f & G_FLAG_PICKSEL) && (_call)) { \
1147                 GPU_select_load_id((_call)->select_id); \
1148         } ((void)0)
1149
1150 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count)  \
1151         _start = 0;                                                      \
1152         _count = _shgroup->instance_count;                     \
1153         int *select_id = NULL;                                           \
1154         if (G.f & G_FLAG_PICKSEL) {                                           \
1155                 if (_shgroup->override_selectid == -1) {                        \
1156                         /* Hack : get vbo data without actually drawing. */     \
1157                         GPUVertBufRaw raw;                   \
1158                         GPU_vertbuf_attr_get_raw_data(_shgroup->inst_selectid, 0, &raw); \
1159                         select_id = GPU_vertbuf_raw_step(&raw);                               \
1160                         switch (_shgroup->type) {                                             \
1161                                 case DRW_SHG_TRIANGLE_BATCH: _count = 3; break;                   \
1162                                 case DRW_SHG_LINE_BATCH: _count = 2; break;                       \
1163                                 default: _count = 1; break;                                       \
1164                         }                                                                     \
1165                 }                                                                         \
1166                 else {                                                                    \
1167                         GPU_select_load_id(_shgroup->override_selectid);            \
1168                 }                                                                         \
1169         }                                                                \
1170         while (_start < _shgroup->instance_count) {            \
1171                 if (select_id) {                                             \
1172                         GPU_select_load_id(select_id[_start]);                   \
1173                 }
1174
1175 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(_start, _count) \
1176                 _start += _count;                                    \
1177         }
1178
1179 #else
1180 #  define GPU_SELECT_LOAD_IF_PICKSEL(select_id)
1181 #  define GPU_SELECT_LOAD_IF_PICKSEL_CALL(call)
1182 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
1183 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count) \
1184         _start = 0;                                                     \
1185         _count = _shgroup->instance_count;
1186
1187 #endif
1188
1189         BLI_assert(ubo_bindings_validate(shgroup));
1190
1191         /* Rendering Calls */
1192         if (!ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)) {
1193                 /* Replacing multiple calls with only one */
1194                 if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
1195                         if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) {
1196                                 if (shgroup->instance_geom != NULL) {
1197                                         GPU_SELECT_LOAD_IF_PICKSEL(shgroup->override_selectid);
1198                                         draw_geometry_prepare(shgroup, NULL);
1199                                         draw_geometry_execute_ex(shgroup, shgroup->instance_geom, 0, 0, true);
1200                                 }
1201                         }
1202                         else {
1203                                 if (shgroup->instance_count > 0) {
1204                                         uint count, start;
1205                                         draw_geometry_prepare(shgroup, NULL);
1206                                         GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
1207                                         {
1208                                                 draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count, true);
1209                                         }
1210                                         GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
1211                                 }
1212                         }
1213                 }
1214                 else { /* DRW_SHG_***_BATCH */
1215                         /* Some dynamic batch can have no geom (no call to aggregate) */
1216                         if (shgroup->instance_count > 0) {
1217                                 uint count, start;
1218                                 draw_geometry_prepare(shgroup, NULL);
1219                                 GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
1220                                 {
1221                                         draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count, false);
1222                                 }
1223                                 GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
1224                         }
1225                 }
1226         }
1227         else {
1228                 bool prev_neg_scale = false;
1229                 int callid = 0;
1230                 for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
1231
1232                         /* OPTI/IDEA(clem): Do this preparation in another thread. */
1233                         draw_visibility_eval(call->state);
1234                         draw_matrices_model_prepare(call->state);
1235
1236                         if ((call->state->flag & DRW_CALL_CULLED) != 0 &&
1237                             (call->state->flag & DRW_CALL_BYPASS_CULLING) == 0)
1238                         {
1239                                 continue;
1240                         }
1241
1242                         /* XXX small exception/optimisation for outline rendering. */
1243                         if (shgroup->callid != -1) {
1244                                 GPU_shader_uniform_vector_int(shgroup->shader, shgroup->callid, 1, 1, &callid);
1245                                 callid += 1;
1246                         }
1247
1248                         /* Negative scale objects */
1249                         bool neg_scale = call->state->flag & DRW_CALL_NEGSCALE;
1250                         if (neg_scale != prev_neg_scale) {
1251                                 glFrontFace((neg_scale) ? DST.backface : DST.frontface);
1252                                 prev_neg_scale = neg_scale;
1253                         }
1254
1255                         GPU_SELECT_LOAD_IF_PICKSEL_CALL(call);
1256                         draw_geometry_prepare(shgroup, call);
1257
1258                         switch (call->type) {
1259                                 case DRW_CALL_SINGLE:
1260                                         draw_geometry_execute(shgroup, call->single.geometry);
1261                                         break;
1262                                 case DRW_CALL_RANGE:
1263                                         draw_geometry_execute_ex(shgroup, call->range.geometry, call->range.start, call->range.count, false);
1264                                         break;
1265                                 case DRW_CALL_INSTANCES:
1266                                         draw_geometry_execute_ex(shgroup, call->instances.geometry, 0, *call->instances.count, true);
1267                                         break;
1268                                 case DRW_CALL_GENERATE:
1269                                         call->generate.geometry_fn(shgroup, draw_geometry_execute, call->generate.user_data);
1270                                         break;
1271                                 case DRW_CALL_PROCEDURAL:
1272                                         GPU_draw_primitive(call->procedural.prim_type, call->procedural.vert_count);
1273                                         break;
1274                                 default:
1275                                         BLI_assert(0);
1276                         }
1277                 }
1278                 /* Reset state */
1279                 glFrontFace(DST.frontface);
1280         }
1281
1282         if (use_tfeedback) {
1283                 GPU_shader_transform_feedback_disable(shgroup->shader);
1284         }
1285
1286         /* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */
1287         DRW_state_reset();
1288 }
1289
1290 static void drw_update_view(void)
1291 {
1292         if (DST.dirty_mat) {
1293                 DST.state_cache_id++;
1294                 DST.dirty_mat = false;
1295
1296                 DRW_uniformbuffer_update(view_ubo, &DST.view_data);
1297
1298                 /* Catch integer wrap around. */
1299                 if (UNLIKELY(DST.state_cache_id == 0)) {
1300                         DST.state_cache_id = 1;
1301                         /* We must reset all CallStates to ensure that not
1302                          * a single one stayed with cache_id equal to 1. */
1303                         BLI_mempool_iter iter;
1304                         DRWCallState *state;
1305                         BLI_mempool_iternew(DST.vmempool->states, &iter);
1306                         while ((state = BLI_mempool_iterstep(&iter))) {
1307                                 state->cache_id = 0;
1308                         }
1309                 }
1310
1311                 /* TODO dispatch threads to compute matrices/culling */
1312         }
1313
1314         draw_clipping_setup_from_view();
1315 }
1316
1317 static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group)
1318 {
1319         if (start_group == NULL) {
1320                 return;
1321         }
1322
1323         DST.shader = NULL;
1324
1325         BLI_assert(DST.buffer_finish_called && "DRW_render_instance_buffer_finish had not been called before drawing");
1326
1327         drw_update_view();
1328
1329         drw_state_set(pass->state);
1330
1331         DRW_stats_query_start(pass->name);
1332
1333         for (DRWShadingGroup *shgroup = start_group; shgroup; shgroup = shgroup->next) {
1334                 draw_shgroup(shgroup, pass->state);
1335                 /* break if upper limit */
1336                 if (shgroup == end_group) {
1337                         break;
1338                 }
1339         }
1340
1341         /* Clear Bound textures */
1342         for (int i = 0; i < GPU_max_textures(); i++) {
1343                 if (DST.RST.bound_texs[i] != NULL) {
1344                         GPU_texture_unbind(DST.RST.bound_texs[i]);
1345                         DST.RST.bound_texs[i] = NULL;
1346                 }
1347         }
1348
1349         /* Clear Bound Ubos */
1350         for (int i = 0; i < GPU_max_ubo_binds(); i++) {
1351                 if (DST.RST.bound_ubos[i] != NULL) {
1352                         GPU_uniformbuffer_unbind(DST.RST.bound_ubos[i]);
1353                         DST.RST.bound_ubos[i] = NULL;
1354                 }
1355         }
1356
1357         if (DST.shader) {
1358                 GPU_shader_unbind();
1359                 DST.shader = NULL;
1360         }
1361
1362         DRW_stats_query_end();
1363 }
1364
1365 void DRW_draw_pass(DRWPass *pass)
1366 {
1367         drw_draw_pass_ex(pass, pass->shgroups.first, pass->shgroups.last);
1368 }
1369
1370 /* Draw only a subset of shgroups. Used in special situations as grease pencil strokes */
1371 void DRW_draw_pass_subset(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group)
1372 {
1373         drw_draw_pass_ex(pass, start_group, end_group);
1374 }
1375
1376 /** \} */