Blender  V2.93
draw_manager_shader.c
Go to the documentation of this file.
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 
23 #include "DNA_material_types.h"
24 #include "DNA_object_types.h"
25 #include "DNA_world_types.h"
26 
27 #include "BLI_dynstr.h"
28 #include "BLI_listbase.h"
29 #include "BLI_string_utils.h"
30 #include "BLI_threads.h"
31 
32 #include "BKE_context.h"
33 #include "BKE_global.h"
34 #include "BKE_main.h"
35 
36 #include "DEG_depsgraph_query.h"
37 
38 #include "GPU_capabilities.h"
39 #include "GPU_material.h"
40 #include "GPU_shader.h"
41 
42 #include "WM_api.h"
43 #include "WM_types.h"
44 
45 #include "wm_window.h"
46 
47 #include "draw_manager.h"
48 
53 
54 #define USE_DEFERRED_COMPILATION 1
55 
56 /* -------------------------------------------------------------------- */
64 typedef struct DRWDeferredShader {
66 
69 
70 typedef struct DRWShaderCompiler {
71  ListBase queue; /* DRWDeferredShader */
72  ListBase queue_conclude; /* DRWDeferredShader */
74 
77 
78  void *gl_context;
81 
82  int shaders_done; /* To compute progress. */
84 
86 {
87  /* Make sure it is not queued before freeing. */
88  MEM_freeN(dsh);
89 }
90 
92 {
93  DRWDeferredShader *dsh;
94  while ((dsh = BLI_pophead(queue))) {
96  }
97 }
98 
100  void *custom_data,
101  /* Cannot be const, this function implements wm_jobs_start_callback.
102  * NOLINTNEXTLINE: readability-non-const-parameter. */
103  short *stop,
104  short *do_update,
105  float *progress)
106 {
107  DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
108  void *gl_context = comp->gl_context;
109  GPUContext *gpu_context = comp->gpu_context;
110 
111  BLI_assert(gl_context != NULL);
112  BLI_assert(gpu_context != NULL);
113 
114  const bool use_main_context_workaround = GPU_use_main_context_workaround();
115  if (use_main_context_workaround) {
116  BLI_assert(gl_context == DST.gl_context);
118  }
119 
120  WM_opengl_context_activate(gl_context);
121  GPU_context_active_set(gpu_context);
122 
123  while (true) {
124  BLI_spin_lock(&comp->list_lock);
125 
126  if (*stop != 0) {
127  /* We don't want user to be able to cancel the compilation
128  * but wm can kill the task if we are closing blender. */
129  BLI_spin_unlock(&comp->list_lock);
130  break;
131  }
132 
133  /* Pop tail because it will be less likely to lock the main thread
134  * if all GPUMaterials are to be freed (see DRW_deferred_shader_remove()). */
135  comp->mat_compiling = BLI_poptail(&comp->queue);
136  if (comp->mat_compiling == NULL) {
137  /* No more Shader to compile. */
138  BLI_spin_unlock(&comp->list_lock);
139  break;
140  }
141 
142  comp->shaders_done++;
143  int total = BLI_listbase_count(&comp->queue) + comp->shaders_done;
144 
146  BLI_spin_unlock(&comp->list_lock);
147 
148  /* Do the compilation. */
150 
151  *progress = (float)comp->shaders_done / (float)total;
152  *do_update = true;
153 
154  GPU_flush();
156 
157  BLI_spin_lock(&comp->list_lock);
160  }
161  else {
163  }
164  comp->mat_compiling = NULL;
165  BLI_spin_unlock(&comp->list_lock);
166  }
167 
169  WM_opengl_context_release(gl_context);
170  if (use_main_context_workaround) {
172  }
173 }
174 
175 static void drw_deferred_shader_compilation_free(void *custom_data)
176 {
177  DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
178 
180 
181  if (!BLI_listbase_is_empty(&comp->queue_conclude)) {
182  /* Compile the shaders in the context they will be deleted. */
184  DRWDeferredShader *mat_conclude;
185  while ((mat_conclude = BLI_poptail(&comp->queue_conclude))) {
186  GPU_material_compile(mat_conclude->mat);
187  drw_deferred_shader_free(mat_conclude);
188  }
190  }
191 
192  BLI_spin_end(&comp->list_lock);
194 
195  if (comp->own_context) {
196  /* Only destroy if the job owns the context. */
201 
203  }
204 
205  MEM_freeN(comp);
206 }
207 
208 static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
209 {
210  /* Do not defer the compilation if we are rendering for image.
211  * deferred rendering is only possible when `evil_C` is available */
213  !deferred) {
214  /* Double checking that this GPUMaterial is not going to be
215  * compiled by another thread. */
218  return;
219  }
220  const bool use_main_context = GPU_use_main_context_workaround();
221  const bool job_own_context = !use_main_context;
222 
223  DRWDeferredShader *dsh = MEM_callocN(sizeof(DRWDeferredShader), "Deferred Shader");
224 
225  dsh->mat = mat;
226 
230 
231  /* Use original scene ID since this is what the jobs template tests for. */
233 
234  /* Get the running job or a new one if none is running. Can only have one job per type & owner.
235  */
236  wmJob *wm_job = WM_jobs_get(
237  wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION);
238 
240 
241  DRWShaderCompiler *comp = MEM_callocN(sizeof(DRWShaderCompiler), "DRWShaderCompiler");
242  BLI_spin_init(&comp->list_lock);
244 
245  if (old_comp) {
246  BLI_spin_lock(&old_comp->list_lock);
247  BLI_movelisttolist(&comp->queue, &old_comp->queue);
248  BLI_spin_unlock(&old_comp->list_lock);
249  /* Do not recreate context, just pass ownership. */
250  if (old_comp->gl_context) {
251  comp->gl_context = old_comp->gl_context;
252  comp->gpu_context = old_comp->gpu_context;
253  old_comp->own_context = false;
254  comp->own_context = job_own_context;
255  }
256  }
257 
258  BLI_addtail(&comp->queue, dsh);
259 
260  /* Create only one context. */
261  if (comp->gl_context == NULL) {
262  if (use_main_context) {
263  comp->gl_context = DST.gl_context;
264  comp->gpu_context = DST.gpu_context;
265  }
266  else {
270 
273  }
274  comp->own_context = job_own_context;
275  }
276 
278  WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0);
279  WM_jobs_delay_start(wm_job, 0.1);
281 
282  G.is_break = false;
283 
284  WM_jobs_start(wm, wm_job);
285 }
286 
288 {
290 
291  for (wmWindowManager *wm = G_MAIN->wm.first; wm; wm = wm->id.next) {
293  /* No job running, do not create a new one by calling WM_jobs_get. */
294  continue;
295  }
296  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
297  wmJob *wm_job = WM_jobs_get(
298  wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION);
299 
301  if (comp != NULL) {
302  BLI_spin_lock(&comp->list_lock);
303  DRWDeferredShader *dsh;
305  &comp->queue, mat, offsetof(DRWDeferredShader, mat));
306  if (dsh) {
307  BLI_remlink(&comp->queue, dsh);
308  }
309 
310  /* Wait for compilation to finish */
311  if ((comp->mat_compiling != NULL) && (comp->mat_compiling->mat == mat)) {
314  }
315 
316  BLI_spin_unlock(&comp->list_lock);
317 
318  if (dsh) {
320  }
321  }
322  }
323  }
324 }
325 
328 /* -------------------------------------------------------------------- */
329 
333  const char *vert, const char *geom, const char *frag, const char *defines, const char *name)
334 {
335  return GPU_shader_create(vert, frag, geom, NULL, defines, name);
336 }
337 
339  const char *geom,
340  const char *frag,
341  const char *lib,
342  const char *defines,
343  const char *name)
344 {
345  GPUShader *sh;
346  char *vert_with_lib = NULL;
347  char *frag_with_lib = NULL;
348  char *geom_with_lib = NULL;
349 
350  vert_with_lib = BLI_string_joinN(lib, vert);
351  frag_with_lib = BLI_string_joinN(lib, frag);
352  if (geom) {
353  geom_with_lib = BLI_string_joinN(lib, geom);
354  }
355 
356  sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name);
357 
358  MEM_freeN(vert_with_lib);
359  MEM_freeN(frag_with_lib);
360  if (geom) {
361  MEM_freeN(geom_with_lib);
362  }
363 
364  return sh;
365 }
366 
368  const char *geom,
369  const char *frag,
370  const DRWShaderLibrary *lib,
371  const char *defines,
372  const char *name)
373 {
374  GPUShader *sh;
375  char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert);
376  char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
377  char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL;
378 
379  sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name);
380 
381  MEM_SAFE_FREE(vert_with_lib);
382  MEM_SAFE_FREE(frag_with_lib);
383  MEM_SAFE_FREE(geom_with_lib);
384 
385  return sh;
386 }
387 
389  const char *geom,
390  const char *defines,
391  const eGPUShaderTFBType prim_type,
392  const char **varying_names,
393  const int varying_count)
394 {
395  return GPU_shader_create_ex(vert,
397  geom,
398  NULL,
399  defines,
400  prim_type,
401  varying_names,
402  varying_count,
403  __func__);
404 }
405 
406 GPUShader *DRW_shader_create_fullscreen_ex(const char *frag, const char *defines, const char *name)
407 {
408  return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, name);
409 }
410 
412  const DRWShaderLibrary *lib,
413  const char *defines,
414  const char *name)
415 {
416 
417  GPUShader *sh;
419  char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
420 
421  sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, name);
422 
423  MEM_SAFE_FREE(frag_with_lib);
424 
425  return sh;
426 }
427 
429  const void *engine_type,
430  const int options,
431  bool deferred)
432 {
434  if (DRW_state_is_image_render() || !deferred) {
435  if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
436  /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
437  * with the shader code and we will resume the compilation from there. */
438  return NULL;
439  }
440  }
441  return mat;
442 }
443 
445  const void *engine_type,
446  const int options,
447  bool deferred)
448 {
450  if (DRW_state_is_image_render() || !deferred) {
451  if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
452  /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
453  * with the shader code and we will resume the compilation from there. */
454  return NULL;
455  }
456  }
457  return mat;
458 }
459 
461  World *wo,
462  struct bNodeTree *ntree,
463  const void *engine_type,
464  const int options,
465  const bool is_volume_shader,
466  const char *vert,
467  const char *geom,
468  const char *frag_lib,
469  const char *defines,
470  bool deferred,
472 {
473  GPUMaterial *mat = NULL;
474  if (DRW_state_is_image_render() || !deferred) {
475  mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
476  }
477 
478  if (mat == NULL) {
481  NULL,
482  ntree,
483  &wo->gpumaterial,
484  engine_type,
485  options,
486  is_volume_shader,
487  vert,
488  geom,
489  frag_lib,
490  defines,
491  wo->id.name,
492  callback);
493  }
494 
495  if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
496  drw_deferred_shader_add(mat, deferred);
497  }
498 
499  return mat;
500 }
501 
503  Material *ma,
504  struct bNodeTree *ntree,
505  const void *engine_type,
506  const int options,
507  const bool is_volume_shader,
508  const char *vert,
509  const char *geom,
510  const char *frag_lib,
511  const char *defines,
512  bool deferred,
514 {
515  GPUMaterial *mat = NULL;
516  if (DRW_state_is_image_render() || !deferred) {
517  mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
518  }
519 
520  if (mat == NULL) {
523  ma,
524  ntree,
525  &ma->gpumaterial,
526  engine_type,
527  options,
528  is_volume_shader,
529  vert,
530  geom,
531  frag_lib,
532  defines,
533  ma->id.name,
534  callback);
535  }
536 
537  if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
538  drw_deferred_shader_add(mat, deferred);
539  }
540 
541  return mat;
542 }
543 
545 {
547 }
548 
551 /* -------------------------------------------------------------------- */
563 /* 32 because we use a 32bit bitmap. */
564 #define MAX_LIB 32
565 #define MAX_LIB_NAME 64
566 #define MAX_LIB_DEPS 8
567 
569  char *libs[MAX_LIB];
572 };
573 
575 {
576  return MEM_callocN(sizeof(DRWShaderLibrary), "DRWShaderLibrary");
577 }
578 
580 {
582 }
583 
584 static int drw_shader_library_search(const DRWShaderLibrary *lib, const char *name)
585 {
586  for (int i = 0; i < MAX_LIB; i++) {
587  if (lib->libs[i]) {
588  if (!strncmp(lib->libs_name[i], name, strlen(lib->libs_name[i]))) {
589  return i;
590  }
591  }
592  else {
593  break;
594  }
595  }
596  return -1;
597 }
598 
599 /* Return bitmap of dependencies. */
600 static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const char *lib_code)
601 {
602  /* Search dependencies. */
603  uint32_t deps = 0;
604  const char *haystack = lib_code;
605  while ((haystack = strstr(haystack, "BLENDER_REQUIRE("))) {
606  haystack += 16;
607  int dep = drw_shader_library_search(lib, haystack);
608  if (dep == -1) {
609  char dbg_name[33];
610  int i = 0;
611  while ((*haystack != ')') && (i < (sizeof(dbg_name) - 2))) {
612  dbg_name[i] = *haystack;
613  haystack++;
614  i++;
615  }
616  dbg_name[i + 1] = '\0';
617 
618  printf(
619  "Error: Dependency not found: %s\n"
620  "This might be due to bad lib ordering.\n",
621  dbg_name);
622  BLI_assert(0);
623  }
624  else {
625  deps |= 1u << (uint32_t)dep;
626  }
627  }
628  return deps;
629 }
630 
631 void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const char *lib_name)
632 {
633  int index = -1;
634  for (int i = 0; i < MAX_LIB; i++) {
635  if (lib->libs[i] == NULL) {
636  index = i;
637  break;
638  }
639  }
640 
641  if (index > -1) {
642  lib->libs[index] = lib_code;
643  BLI_strncpy(lib->libs_name[index], lib_name, MAX_LIB_NAME);
644  lib->libs_deps[index] = drw_shader_dependencies_get(lib, lib_code);
645  }
646  else {
647  printf("Error: Too many libraries. Cannot add %s.\n", lib_name);
648  BLI_assert(0);
649  }
650 }
651 
652 /* Return an allocN'ed string containing the shader code with its dependencies prepended.
653  * Caller must free the string with MEM_freeN after use. */
654 char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib, const char *shader_code)
655 {
656  uint32_t deps = drw_shader_dependencies_get(lib, shader_code);
657 
658  DynStr *ds = BLI_dynstr_new();
659  /* Add all dependencies recursively. */
660  for (int i = MAX_LIB - 1; i > -1; i--) {
661  if (lib->libs[i] && (deps & (1u << (uint32_t)i))) {
662  deps |= lib->libs_deps[i];
663  }
664  }
665  /* Concatenate all needed libs into one string. */
666  for (int i = 0; i < MAX_LIB; i++) {
667  if (deps & 1u) {
668  BLI_dynstr_append(ds, lib->libs[i]);
669  }
670  deps = deps >> 1;
671  }
672 
673  BLI_dynstr_append(ds, shader_code);
674 
675  char *str = BLI_dynstr_get_cstring(ds);
676  BLI_dynstr_free(ds);
677 
678  return str;
679 }
680 
typedef float(TangentPoint)[2]
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
#define G_MAIN
Definition: BKE_global.h:232
#define BLI_assert(a)
Definition: BLI_assert.h:58
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:71
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition: BLI_dynstr.c:358
char * BLI_dynstr_get_cstring(DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:323
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition: BLI_dynstr.c:107
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:257
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
void * BLI_poptail(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:269
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define BLI_string_joinN(...)
pthread_spinlock_t SpinLock
Definition: BLI_threads.h:111
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:416
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:396
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:401
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:406
void BLI_spin_init(SpinLock *spin)
Definition: threads.cc:447
void BLI_spin_unlock(SpinLock *spin)
Definition: threads.cc:480
void BLI_spin_lock(SpinLock *spin)
Definition: threads.cc:461
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:83
void BLI_spin_end(SpinLock *spin)
Definition: threads.cc:495
struct ID * DEG_get_original_id(struct ID *id)
Object is a sort of wrapper for general info.
void DRW_opengl_context_disable_ex(bool restore)
void DRW_opengl_context_enable_ex(bool restore)
void(* GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat, int options, const char **vert_code, const char **geom_code, const char **frag_lib, const char **defines)
Definition: DRW_render.h:200
bool GPU_use_main_context_workaround(void)
struct GPUContext GPUContext
Definition: GPU_context.h:44
void GPU_context_main_lock(void)
Definition: gpu_context.cc:149
void GPU_context_discard(GPUContext *)
Definition: gpu_context.cc:113
GPUContext * GPU_context_create(void *ghost_window)
Definition: gpu_context.cc:99
void GPU_context_active_set(GPUContext *)
Definition: gpu_context.cc:121
void GPU_context_main_unlock(void)
Definition: gpu_context.cc:154
void GPU_material_compile(GPUMaterial *mat)
Definition: gpu_material.c:775
GPUMaterial * GPU_material_from_nodetree(struct Scene *scene, struct Material *ma, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, const int options, const bool is_volume_shader, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, const char *name, GPUMaterialEvalCallbackFn callback)
Definition: gpu_material.c:670
struct Scene * GPU_material_scene(GPUMaterial *material)
Definition: gpu_material.c:202
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
Definition: gpu_material.c:619
@ GPU_MAT_QUEUED
Definition: GPU_material.h:128
GPUMaterial * GPU_material_from_nodetree_find(struct ListBase *gpumaterials, const void *engine_type, int options)
Definition: gpu_material.c:651
GPUShader * GPU_shader_create(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *shname)
Definition: gpu_shader.cc:376
struct GPUShader GPUShader
Definition: GPU_shader.h:33
GPUShader * GPU_shader_create_ex(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const eGPUShaderTFBType tf_type, const char **tf_names, const int tf_count, const char *shname)
Definition: gpu_shader.cc:290
eGPUShaderTFBType
Definition: GPU_shader.h:35
void GPU_shader_free(GPUShader *shader)
Definition: gpu_shader.cc:365
void GPU_flush(void)
Definition: gpu_state.cc:311
#define MEM_SAFE_FREE(v)
@ WM_JOB_TYPE_SHADER_COMPILATION
Definition: WM_api.h:752
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
#define NC_MATERIAL
Definition: WM_types.h:281
#define ND_SHADING_DRAW
Definition: WM_types.h:378
CCL_NAMESPACE_BEGIN struct Options options
Scene scene
DEGForeachIDComponentCallback callback
DRWManager DST
Definition: draw_manager.c:111
bool DRW_state_is_image_render(void)
GPUShader * DRW_shader_create_with_lib_ex(const char *vert, const char *geom, const char *frag, const char *lib, const char *defines, const char *name)
GPUShader * DRW_shader_create_with_transform_feedback(const char *vert, const char *geom, const char *defines, const eGPUShaderTFBType prim_type, const char **varying_names, const int varying_count)
char datatoc_gpu_shader_depth_only_frag_glsl[]
GPUShader * DRW_shader_create_ex(const char *vert, const char *geom, const char *frag, const char *defines, const char *name)
GPUMaterial * DRW_shader_find_from_material(Material *ma, const void *engine_type, const int options, bool deferred)
static void drw_deferred_shader_compilation_exec(void *custom_data, short *stop, short *do_update, float *progress)
void DRW_shader_free(GPUShader *shader)
struct DRWShaderCompiler DRWShaderCompiler
struct DRWDeferredShader DRWDeferredShader
GPUMaterial * DRW_shader_create_from_world(struct Scene *scene, World *wo, struct bNodeTree *ntree, const void *engine_type, const int options, const bool is_volume_shader, const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred, GPUMaterialEvalCallbackFn callback)
void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const char *lib_name)
char datatoc_common_fullscreen_vert_glsl[]
static int drw_shader_library_search(const DRWShaderLibrary *lib, const char *name)
void DRW_shader_library_free(DRWShaderLibrary *lib)
static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const char *lib_code)
static void drw_deferred_shader_queue_free(ListBase *queue)
GPUShader * DRW_shader_create_fullscreen_ex(const char *frag, const char *defines, const char *name)
GPUShader * DRW_shader_create_with_shaderlib_ex(const char *vert, const char *geom, const char *frag, const DRWShaderLibrary *lib, const char *defines, const char *name)
DRWShaderLibrary * DRW_shader_library_create(void)
GPUShader * DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag, const DRWShaderLibrary *lib, const char *defines, const char *name)
GPUMaterial * DRW_shader_create_from_material(struct Scene *scene, Material *ma, struct bNodeTree *ntree, const void *engine_type, const int options, const bool is_volume_shader, const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred, GPUMaterialEvalCallbackFn callback)
#define USE_DEFERRED_COMPILATION
char * DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib, const char *shader_code)
char datatoc_gpu_shader_3D_vert_glsl[]
#define MAX_LIB
static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
void DRW_deferred_shader_remove(GPUMaterial *mat)
static void drw_deferred_shader_free(DRWDeferredShader *dsh)
static void drw_deferred_shader_compilation_free(void *custom_data)
#define MAX_LIB_NAME
char datatoc_gpu_shader_2D_vert_glsl[]
GPUMaterial * DRW_shader_find_from_world(World *wo, const void *engine_type, const int options, bool deferred)
bNodeTree * ntree
DRWShaderLibrary * lib
#define str(s)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
ThreadQueue * queue
all scheduled work for the cpu
unsigned int uint32_t
Definition: stdint.h:83
struct Scene * scene
Definition: DRW_render.h:745
const struct bContext * evil_C
Definition: DRW_render.h:763
struct DRWDeferredShader * prev
struct DRWDeferredShader * next
DRWContextState draw_ctx
Definition: draw_manager.h:539
GPUContext * gpu_context
Definition: draw_manager.h:572
void * gl_context
Definition: draw_manager.h:571
DRWDeferredShader * mat_compiling
ThreadMutex compilation_lock
GPUContext * gpu_context
uint32_t libs_deps[MAX_LIB]
char * libs[MAX_LIB]
char libs_name[MAX_LIB][MAX_LIB_NAME]
char name[66]
Definition: DNA_ID.h:283
ListBase gpumaterial
ListBase gpumaterial
Definition: wm_jobs.c:73
#define G(x, y, z)
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:450
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:223
void WM_jobs_delay_start(wmJob *wm_job, double delay_time)
Definition: wm_jobs.c:367
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:372
void * WM_jobs_customdata_get(wmJob *wm_job)
Definition: wm_jobs.c:336
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360
void * WM_opengl_context_create(void)
Definition: wm_window.c:2421
void wm_window_reset_drawable(void)
Definition: wm_window.c:1074
void WM_opengl_context_activate(void *context)
Definition: wm_window.c:2443
void WM_opengl_context_release(void *context)
Definition: wm_window.c:2449
void WM_opengl_context_dispose(void *context)
Definition: wm_window.c:2437