| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-01-23 11:29:18 +11:00
										 |  |  |  * Copyright 2016, Blender Foundation. | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup draw | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "DNA_material_types.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-24 17:12:06 +11:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | #include "DNA_world_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | #include "BLI_dynstr.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | #include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | #include "BLI_string_utils.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | #include "BLI_threads.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-17 15:36:47 +02:00
										 |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 19:35:56 +02:00
										 |  |  | #include "GPU_capabilities.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | #include "GPU_material.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "GPU_shader.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | #include "WM_types.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  | #include "wm_window.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-24 17:12:06 +11:00
										 |  |  | #include "draw_manager.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | extern char datatoc_gpu_shader_2D_vert_glsl[]; | 
					
						
							|  |  |  | extern char datatoc_gpu_shader_3D_vert_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-12-07 21:19:02 +01:00
										 |  |  | extern char datatoc_gpu_shader_depth_only_frag_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-03-22 16:10:54 +01:00
										 |  |  | extern char datatoc_common_fullscreen_vert_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 15:58:46 +02:00
										 |  |  | #define USE_DEFERRED_COMPILATION 1
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Deferred Compilation (DRW_deferred)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since compiling shader can take a long time, we do it in a non blocking | 
					
						
							|  |  |  |  * manner in another thread. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct DRWDeferredShader { | 
					
						
							|  |  |  |   struct DRWDeferredShader *prev, *next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GPUMaterial *mat; | 
					
						
							|  |  |  | } DRWDeferredShader; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct DRWShaderCompiler { | 
					
						
							| 
									
										
										
										
											2019-06-05 13:06:11 -03:00
										 |  |  |   ListBase queue;          /* DRWDeferredShader */ | 
					
						
							|  |  |  |   ListBase queue_conclude; /* DRWDeferredShader */ | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   SpinLock list_lock; | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   DRWDeferredShader *mat_compiling; | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   ThreadMutex compilation_lock; | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |   void *gl_context; | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |   GPUContext *gpu_context; | 
					
						
							| 
									
										
										
										
											2018-07-27 13:57:46 +02:00
										 |  |  |   bool own_context; | 
					
						
							| 
									
										
										
										
											2018-03-07 19:40:08 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   int shaders_done; /* To compute progress. */ | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | } DRWShaderCompiler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void drw_deferred_shader_free(DRWDeferredShader *dsh) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* Make sure it is not queued before freeing. */ | 
					
						
							|  |  |  |   MEM_freeN(dsh); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | static void drw_deferred_shader_queue_free(ListBase *queue) | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   DRWDeferredShader *dsh; | 
					
						
							| 
									
										
										
										
											2018-04-19 07:47:03 +02:00
										 |  |  |   while ((dsh = BLI_pophead(queue))) { | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |     drw_deferred_shader_free(dsh); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  | static void drw_deferred_shader_compilation_exec( | 
					
						
							|  |  |  |     void *custom_data, | 
					
						
							|  |  |  |     /* Cannot be const, this function implements wm_jobs_start_callback.
 | 
					
						
							|  |  |  |      * NOLINTNEXTLINE: readability-non-const-parameter. */ | 
					
						
							|  |  |  |     short *stop, | 
					
						
							|  |  |  |     short *do_update, | 
					
						
							|  |  |  |     float *progress) | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data; | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |   void *gl_context = comp->gl_context; | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |   GPUContext *gpu_context = comp->gpu_context; | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-27 15:27:53 +10:00
										 |  |  |   BLI_assert(gl_context != NULL); | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |   BLI_assert(gpu_context != NULL); | 
					
						
							| 
									
										
										
										
											2020-04-27 15:27:53 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |   const bool use_main_context_workaround = GPU_use_main_context_workaround(); | 
					
						
							|  |  |  |   if (use_main_context_workaround) { | 
					
						
							|  |  |  |     BLI_assert(gl_context == DST.gl_context); | 
					
						
							|  |  |  |     GPU_context_main_lock(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |   WM_opengl_context_activate(gl_context); | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |   GPU_context_active_set(gpu_context); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   while (true) { | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |     BLI_spin_lock(&comp->list_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (*stop != 0) { | 
					
						
							|  |  |  |       /* We don't want user to be able to cancel the compilation
 | 
					
						
							|  |  |  |        * but wm can kill the task if we are closing blender. */ | 
					
						
							|  |  |  |       BLI_spin_unlock(&comp->list_lock); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Pop tail because it will be less likely to lock the main thread
 | 
					
						
							|  |  |  |      * if all GPUMaterials are to be freed (see DRW_deferred_shader_remove()). */ | 
					
						
							|  |  |  |     comp->mat_compiling = BLI_poptail(&comp->queue); | 
					
						
							|  |  |  |     if (comp->mat_compiling == NULL) { | 
					
						
							|  |  |  |       /* No more Shader to compile. */ | 
					
						
							|  |  |  |       BLI_spin_unlock(&comp->list_lock); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     comp->shaders_done++; | 
					
						
							|  |  |  |     int total = BLI_listbase_count(&comp->queue) + comp->shaders_done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BLI_mutex_lock(&comp->compilation_lock); | 
					
						
							|  |  |  |     BLI_spin_unlock(&comp->list_lock); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Do the compilation. */ | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |     GPU_material_compile(comp->mat_compiling->mat); | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *progress = (float)comp->shaders_done / (float)total; | 
					
						
							|  |  |  |     *do_update = true; | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 04:23:45 +01:00
										 |  |  |     GPU_flush(); | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |     BLI_mutex_unlock(&comp->compilation_lock); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-04 20:01:58 +01:00
										 |  |  |     BLI_spin_lock(&comp->list_lock); | 
					
						
							| 
									
										
										
										
											2019-06-05 13:06:11 -03:00
										 |  |  |     if (GPU_material_status(comp->mat_compiling->mat) == GPU_MAT_QUEUED) { | 
					
						
							|  |  |  |       BLI_addtail(&comp->queue_conclude, comp->mat_compiling); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       drw_deferred_shader_free(comp->mat_compiling); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-11-04 20:01:58 +01:00
										 |  |  |     comp->mat_compiling = NULL; | 
					
						
							|  |  |  |     BLI_spin_unlock(&comp->list_lock); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |   GPU_context_active_set(NULL); | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |   WM_opengl_context_release(gl_context); | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |   if (use_main_context_workaround) { | 
					
						
							|  |  |  |     GPU_context_main_unlock(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void drw_deferred_shader_compilation_free(void *custom_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   drw_deferred_shader_queue_free(&comp->queue); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-05 13:06:11 -03:00
										 |  |  |   if (!BLI_listbase_is_empty(&comp->queue_conclude)) { | 
					
						
							|  |  |  |     /* Compile the shaders in the context they will be deleted. */ | 
					
						
							|  |  |  |     DRW_opengl_context_enable_ex(false); | 
					
						
							|  |  |  |     DRWDeferredShader *mat_conclude; | 
					
						
							| 
									
										
										
										
											2019-06-06 10:16:18 +10:00
										 |  |  |     while ((mat_conclude = BLI_poptail(&comp->queue_conclude))) { | 
					
						
							| 
									
										
										
										
											2019-06-05 13:06:11 -03:00
										 |  |  |       GPU_material_compile(mat_conclude->mat); | 
					
						
							|  |  |  |       drw_deferred_shader_free(mat_conclude); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     DRW_opengl_context_disable_ex(true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   BLI_spin_end(&comp->list_lock); | 
					
						
							|  |  |  |   BLI_mutex_end(&comp->compilation_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-27 13:57:46 +02:00
										 |  |  |   if (comp->own_context) { | 
					
						
							| 
									
										
										
										
											2018-04-10 19:30:13 +02:00
										 |  |  |     /* Only destroy if the job owns the context. */ | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |     WM_opengl_context_activate(comp->gl_context); | 
					
						
							|  |  |  |     GPU_context_active_set(comp->gpu_context); | 
					
						
							|  |  |  |     GPU_context_discard(comp->gpu_context); | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |     WM_opengl_context_dispose(comp->gl_context); | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     wm_window_reset_drawable(); | 
					
						
							| 
									
										
										
										
											2018-04-10 19:30:13 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-07 19:40:08 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   MEM_freeN(comp); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  | static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-18 04:11:50 +10:00
										 |  |  |   /* Do not defer the compilation if we are rendering for image.
 | 
					
						
							| 
									
										
										
										
											2019-04-25 16:24:06 +02:00
										 |  |  |    * deferred rendering is only possible when `evil_C` is available */ | 
					
						
							|  |  |  |   if (DST.draw_ctx.evil_C == NULL || DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION || | 
					
						
							|  |  |  |       !deferred) { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     /* Double checking that this GPUMaterial is not going to be
 | 
					
						
							|  |  |  |      * compiled by another thread. */ | 
					
						
							|  |  |  |     DRW_deferred_shader_remove(mat); | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |     GPU_material_compile(mat); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |   const bool use_main_context = GPU_use_main_context_workaround(); | 
					
						
							|  |  |  |   const bool job_own_context = !use_main_context; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |   DRWDeferredShader *dsh = MEM_callocN(sizeof(DRWDeferredShader), "Deferred Shader"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |   dsh->mat = mat; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   BLI_assert(DST.draw_ctx.evil_C); | 
					
						
							|  |  |  |   wmWindowManager *wm = CTX_wm_manager(DST.draw_ctx.evil_C); | 
					
						
							|  |  |  |   wmWindow *win = CTX_wm_window(DST.draw_ctx.evil_C); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-17 15:36:47 +02:00
										 |  |  |   /* Use original scene ID since this is what the jobs template tests for. */ | 
					
						
							|  |  |  |   Scene *scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-01 10:35:46 +10:00
										 |  |  |   /* Get the running job or a new one if none is running. Can only have one job per type & owner.
 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-07-01 15:23:42 +02:00
										 |  |  |   wmJob *wm_job = WM_jobs_get( | 
					
						
							|  |  |  |       wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   DRWShaderCompiler *old_comp = (DRWShaderCompiler *)WM_jobs_customdata_get(wm_job); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   DRWShaderCompiler *comp = MEM_callocN(sizeof(DRWShaderCompiler), "DRWShaderCompiler"); | 
					
						
							|  |  |  |   BLI_spin_init(&comp->list_lock); | 
					
						
							|  |  |  |   BLI_mutex_init(&comp->compilation_lock); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   if (old_comp) { | 
					
						
							|  |  |  |     BLI_spin_lock(&old_comp->list_lock); | 
					
						
							|  |  |  |     BLI_movelisttolist(&comp->queue, &old_comp->queue); | 
					
						
							|  |  |  |     BLI_spin_unlock(&old_comp->list_lock); | 
					
						
							| 
									
										
										
										
											2018-04-10 19:30:13 +02:00
										 |  |  |     /* Do not recreate context, just pass ownership. */ | 
					
						
							| 
									
										
										
										
											2018-07-27 13:57:46 +02:00
										 |  |  |     if (old_comp->gl_context) { | 
					
						
							|  |  |  |       comp->gl_context = old_comp->gl_context; | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |       comp->gpu_context = old_comp->gpu_context; | 
					
						
							| 
									
										
										
										
											2018-07-27 13:57:46 +02:00
										 |  |  |       old_comp->own_context = false; | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |       comp->own_context = job_own_context; | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   BLI_addtail(&comp->queue, dsh); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 19:30:13 +02:00
										 |  |  |   /* Create only one context. */ | 
					
						
							| 
									
										
										
										
											2018-06-11 11:38:26 +02:00
										 |  |  |   if (comp->gl_context == NULL) { | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |     if (use_main_context) { | 
					
						
							|  |  |  |       comp->gl_context = DST.gl_context; | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |       comp->gpu_context = DST.gpu_context; | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       comp->gl_context = WM_opengl_context_create(); | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |       comp->gpu_context = GPU_context_create(NULL); | 
					
						
							|  |  |  |       GPU_context_active_set(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |       WM_opengl_context_activate(DST.gl_context); | 
					
						
							| 
									
										
										
										
											2020-09-08 03:15:06 +02:00
										 |  |  |       GPU_context_active_set(DST.gpu_context); | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     comp->own_context = job_own_context; | 
					
						
							| 
									
										
										
										
											2018-04-10 19:30:13 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free); | 
					
						
							|  |  |  |   WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0); | 
					
						
							| 
									
										
										
										
											2019-07-01 15:23:42 +02:00
										 |  |  |   WM_jobs_delay_start(wm_job, 0.1); | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   WM_jobs_callbacks(wm_job, drw_deferred_shader_compilation_exec, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2020-05-19 21:15:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   G.is_break = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   WM_jobs_start(wm, wm_job); | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  | void DRW_deferred_shader_remove(GPUMaterial *mat) | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |   Scene *scene = GPU_material_scene(mat); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 19:30:47 +02:00
										 |  |  |   for (wmWindowManager *wm = G_MAIN->wm.first; wm; wm = wm->id.next) { | 
					
						
							| 
									
										
										
										
											2018-03-07 01:39:09 +01:00
										 |  |  |     if (WM_jobs_test(wm, scene, WM_JOB_TYPE_SHADER_COMPILATION) == false) { | 
					
						
							|  |  |  |       /* No job running, do not create a new one by calling WM_jobs_get. */ | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-03 19:15:01 +02:00
										 |  |  |     LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { | 
					
						
							| 
									
										
										
										
											2019-07-01 15:23:42 +02:00
										 |  |  |       wmJob *wm_job = WM_jobs_get( | 
					
						
							|  |  |  |           wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |       DRWShaderCompiler *comp = (DRWShaderCompiler *)WM_jobs_customdata_get(wm_job); | 
					
						
							|  |  |  |       if (comp != NULL) { | 
					
						
							|  |  |  |         BLI_spin_lock(&comp->list_lock); | 
					
						
							|  |  |  |         DRWDeferredShader *dsh; | 
					
						
							|  |  |  |         dsh = (DRWDeferredShader *)BLI_findptr( | 
					
						
							|  |  |  |             &comp->queue, mat, offsetof(DRWDeferredShader, mat)); | 
					
						
							|  |  |  |         if (dsh) { | 
					
						
							|  |  |  |           BLI_remlink(&comp->queue, dsh); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |         /* Wait for compilation to finish */ | 
					
						
							| 
									
										
										
										
											2018-11-04 20:01:58 +01:00
										 |  |  |         if ((comp->mat_compiling != NULL) && (comp->mat_compiling->mat == mat)) { | 
					
						
							|  |  |  |           BLI_mutex_lock(&comp->compilation_lock); | 
					
						
							|  |  |  |           BLI_mutex_unlock(&comp->compilation_lock); | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |         BLI_spin_unlock(&comp->list_lock); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 21:50:56 +01:00
										 |  |  |         if (dsh) { | 
					
						
							|  |  |  |           drw_deferred_shader_free(dsh); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | /** \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  | GPUShader *DRW_shader_create_ex( | 
					
						
							|  |  |  |     const char *vert, const char *geom, const char *frag, const char *defines, const char *name) | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  |   return GPU_shader_create(vert, frag, geom, NULL, defines, name); | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  | 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) | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   GPUShader *sh; | 
					
						
							|  |  |  |   char *vert_with_lib = NULL; | 
					
						
							|  |  |  |   char *frag_with_lib = NULL; | 
					
						
							|  |  |  |   char *geom_with_lib = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  |   vert_with_lib = BLI_string_joinN(lib, vert); | 
					
						
							|  |  |  |   frag_with_lib = BLI_string_joinN(lib, frag); | 
					
						
							|  |  |  |   if (geom) { | 
					
						
							|  |  |  |     geom_with_lib = BLI_string_joinN(lib, geom); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  |   sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  |   MEM_freeN(vert_with_lib); | 
					
						
							|  |  |  |   MEM_freeN(frag_with_lib); | 
					
						
							|  |  |  |   if (geom) { | 
					
						
							|  |  |  |     MEM_freeN(geom_with_lib); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  |   return sh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  | 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) | 
					
						
							| 
									
										
										
										
											2020-07-15 14:39:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GPUShader *sh; | 
					
						
							|  |  |  |   char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert); | 
					
						
							|  |  |  |   char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag); | 
					
						
							|  |  |  |   char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  |   sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name); | 
					
						
							| 
									
										
										
										
											2020-07-15 14:39:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   MEM_SAFE_FREE(vert_with_lib); | 
					
						
							|  |  |  |   MEM_SAFE_FREE(frag_with_lib); | 
					
						
							|  |  |  |   MEM_SAFE_FREE(geom_with_lib); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return sh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 12:47:15 +02:00
										 |  |  | GPUShader *DRW_shader_create_with_transform_feedback(const char *vert, | 
					
						
							|  |  |  |                                                      const char *geom, | 
					
						
							|  |  |  |                                                      const char *defines, | 
					
						
							| 
									
										
										
										
											2019-01-23 14:15:43 +11:00
										 |  |  |                                                      const eGPUShaderTFBType prim_type, | 
					
						
							|  |  |  |                                                      const char **varying_names, | 
					
						
							|  |  |  |                                                      const int varying_count) | 
					
						
							| 
									
										
										
										
											2018-05-16 12:47:15 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-07 21:19:02 +01:00
										 |  |  |   return GPU_shader_create_ex(vert, | 
					
						
							|  |  |  |                               datatoc_gpu_shader_depth_only_frag_glsl, | 
					
						
							|  |  |  |                               geom, | 
					
						
							|  |  |  |                               NULL, | 
					
						
							| 
									
										
										
										
											2021-05-26 16:49:17 +02:00
										 |  |  |                               NULL, | 
					
						
							| 
									
										
										
										
											2018-12-07 21:19:02 +01:00
										 |  |  |                               defines, | 
					
						
							| 
									
										
										
										
											2018-08-02 18:31:38 +02:00
										 |  |  |                               prim_type, | 
					
						
							|  |  |  |                               varying_names, | 
					
						
							|  |  |  |                               varying_count, | 
					
						
							|  |  |  |                               __func__); | 
					
						
							| 
									
										
										
										
											2018-05-16 12:47:15 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  | GPUShader *DRW_shader_create_fullscreen_ex(const char *frag, const char *defines, const char *name) | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  |   return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, name); | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  | GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag, | 
					
						
							|  |  |  |                                                           const DRWShaderLibrary *lib, | 
					
						
							|  |  |  |                                                           const char *defines, | 
					
						
							|  |  |  |                                                           const char *name) | 
					
						
							| 
									
										
										
										
											2020-07-15 14:39:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GPUShader *sh; | 
					
						
							|  |  |  |   char *vert = datatoc_common_fullscreen_vert_glsl; | 
					
						
							|  |  |  |   char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 19:11:30 +02:00
										 |  |  |   sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, name); | 
					
						
							| 
									
										
										
										
											2020-07-15 14:39:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   MEM_SAFE_FREE(frag_with_lib); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return sh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  | GPUMaterial *DRW_shader_find_from_world(World *wo, | 
					
						
							|  |  |  |                                         const void *engine_type, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                         const int options, | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |                                         bool deferred) | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options); | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |   if (DRW_state_is_image_render() || !deferred) { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { | 
					
						
							|  |  |  |       /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
 | 
					
						
							|  |  |  |        * with the shader code and we will resume the compilation from there. */ | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return mat; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  | GPUMaterial *DRW_shader_find_from_material(Material *ma, | 
					
						
							|  |  |  |                                            const void *engine_type, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                            const int options, | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |                                            bool deferred) | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options); | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |   if (DRW_state_is_image_render() || !deferred) { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { | 
					
						
							|  |  |  |       /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
 | 
					
						
							|  |  |  |        * with the shader code and we will resume the compilation from there. */ | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return mat; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, | 
					
						
							|  |  |  |                                           World *wo, | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |                                           struct bNodeTree *ntree, | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |                                           const void *engine_type, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                           const int options, | 
					
						
							|  |  |  |                                           const bool is_volume_shader, | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |                                           const char *vert, | 
					
						
							|  |  |  |                                           const char *geom, | 
					
						
							|  |  |  |                                           const char *frag_lib, | 
					
						
							|  |  |  |                                           const char *defines, | 
					
						
							| 
									
										
										
										
											2020-07-30 13:55:13 +02:00
										 |  |  |                                           bool deferred, | 
					
						
							| 
									
										
										
										
											2020-07-30 17:01:13 +02:00
										 |  |  |                                           GPUMaterialEvalCallbackFn callback) | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   GPUMaterial *mat = NULL; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |   if (DRW_state_is_image_render() || !deferred) { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   if (mat == NULL) { | 
					
						
							| 
									
										
										
										
											2018-08-18 12:57:42 +02:00
										 |  |  |     scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id); | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     mat = GPU_material_from_nodetree(scene, | 
					
						
							| 
									
										
										
										
											2019-05-11 14:37:27 +02:00
										 |  |  |                                      NULL, | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |                                      ntree, | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |                                      &wo->gpumaterial, | 
					
						
							|  |  |  |                                      engine_type, | 
					
						
							|  |  |  |                                      options, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                      is_volume_shader, | 
					
						
							| 
									
										
										
										
											2018-08-02 18:31:38 +02:00
										 |  |  |                                      vert, | 
					
						
							|  |  |  |                                      geom, | 
					
						
							|  |  |  |                                      frag_lib, | 
					
						
							|  |  |  |                                      defines, | 
					
						
							| 
									
										
										
										
											2020-07-30 13:55:13 +02:00
										 |  |  |                                      wo->id.name, | 
					
						
							|  |  |  |                                      callback); | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |   if (GPU_material_status(mat) == GPU_MAT_QUEUED) { | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |     drw_deferred_shader_add(mat, deferred); | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |   return mat; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, | 
					
						
							|  |  |  |                                              Material *ma, | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |                                              struct bNodeTree *ntree, | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |                                              const void *engine_type, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                              const int options, | 
					
						
							|  |  |  |                                              const bool is_volume_shader, | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |                                              const char *vert, | 
					
						
							|  |  |  |                                              const char *geom, | 
					
						
							|  |  |  |                                              const char *frag_lib, | 
					
						
							|  |  |  |                                              const char *defines, | 
					
						
							| 
									
										
										
										
											2020-07-30 13:55:13 +02:00
										 |  |  |                                              bool deferred, | 
					
						
							| 
									
										
										
										
											2020-07-30 17:01:13 +02:00
										 |  |  |                                              GPUMaterialEvalCallbackFn callback) | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   GPUMaterial *mat = NULL; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |   if (DRW_state_is_image_render() || !deferred) { | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   if (mat == NULL) { | 
					
						
							| 
									
										
										
										
											2018-08-18 12:57:42 +02:00
										 |  |  |     scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id); | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |     mat = GPU_material_from_nodetree(scene, | 
					
						
							| 
									
										
										
										
											2019-05-11 14:37:27 +02:00
										 |  |  |                                      ma, | 
					
						
							| 
									
										
										
										
											2020-06-02 16:58:07 +02:00
										 |  |  |                                      ntree, | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |                                      &ma->gpumaterial, | 
					
						
							|  |  |  |                                      engine_type, | 
					
						
							|  |  |  |                                      options, | 
					
						
							| 
									
										
										
										
											2020-03-11 14:58:19 +01:00
										 |  |  |                                      is_volume_shader, | 
					
						
							| 
									
										
										
										
											2018-08-02 18:31:38 +02:00
										 |  |  |                                      vert, | 
					
						
							|  |  |  |                                      geom, | 
					
						
							|  |  |  |                                      frag_lib, | 
					
						
							|  |  |  |                                      defines, | 
					
						
							| 
									
										
										
										
											2020-07-30 13:55:13 +02:00
										 |  |  |                                      ma->id.name, | 
					
						
							|  |  |  |                                      callback); | 
					
						
							| 
									
										
										
										
											2018-03-13 03:58:00 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |   if (GPU_material_status(mat) == GPU_MAT_QUEUED) { | 
					
						
							| 
									
										
										
										
											2018-07-10 14:40:28 +02:00
										 |  |  |     drw_deferred_shader_add(mat, deferred); | 
					
						
							| 
									
										
										
										
											2018-06-07 11:58:15 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:54:31 +01:00
										 |  |  |   return mat; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:16:23 +01:00
										 |  |  | void DRW_shader_free(GPUShader *shader) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GPU_shader_free(shader); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Shader Library
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Simple include system for glsl files. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Usage: Create a DRWShaderLibrary and add the library in the right order. | 
					
						
							|  |  |  |  * You can have nested dependencies but each new library needs to have all its dependencies already | 
					
						
							|  |  |  |  * added to the DRWShaderLibrary. | 
					
						
							|  |  |  |  * Finally you can use DRW_shader_library_create_shader_string to get a shader string that also | 
					
						
							|  |  |  |  * contains the needed libraries for this shader. | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 32 because we use a 32bit bitmap. */ | 
					
						
							|  |  |  | #define MAX_LIB 32
 | 
					
						
							|  |  |  | #define MAX_LIB_NAME 64
 | 
					
						
							|  |  |  | #define MAX_LIB_DEPS 8
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct DRWShaderLibrary { | 
					
						
							|  |  |  |   char *libs[MAX_LIB]; | 
					
						
							|  |  |  |   char libs_name[MAX_LIB][MAX_LIB_NAME]; | 
					
						
							|  |  |  |   uint32_t libs_deps[MAX_LIB]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DRWShaderLibrary *DRW_shader_library_create(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return MEM_callocN(sizeof(DRWShaderLibrary), "DRWShaderLibrary"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DRW_shader_library_free(DRWShaderLibrary *lib) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   MEM_SAFE_FREE(lib); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  | static int drw_shader_library_search(const DRWShaderLibrary *lib, const char *name) | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   for (int i = 0; i < MAX_LIB; i++) { | 
					
						
							|  |  |  |     if (lib->libs[i]) { | 
					
						
							|  |  |  |       if (!strncmp(lib->libs_name[i], name, strlen(lib->libs_name[i]))) { | 
					
						
							|  |  |  |         return i; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return bitmap of dependencies. */ | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  | static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const char *lib_code) | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   /* Search dependencies. */ | 
					
						
							|  |  |  |   uint32_t deps = 0; | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  |   const char *haystack = lib_code; | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  |   while ((haystack = strstr(haystack, "BLENDER_REQUIRE("))) { | 
					
						
							|  |  |  |     haystack += 16; | 
					
						
							|  |  |  |     int dep = drw_shader_library_search(lib, haystack); | 
					
						
							|  |  |  |     if (dep == -1) { | 
					
						
							| 
									
										
										
										
											2021-04-30 14:27:44 +10:00
										 |  |  |       char dbg_name[33]; | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  |       int i = 0; | 
					
						
							| 
									
										
										
										
											2021-04-30 14:27:44 +10:00
										 |  |  |       while ((*haystack != ')') && (i < (sizeof(dbg_name) - 2))) { | 
					
						
							|  |  |  |         dbg_name[i] = *haystack; | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  |         haystack++; | 
					
						
							|  |  |  |         i++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       dbg_name[i + 1] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  |       printf( | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  |           "Error: Dependency not found: %s\n" | 
					
						
							|  |  |  |           "This might be due to bad lib ordering.\n", | 
					
						
							|  |  |  |           dbg_name); | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  |       BLI_assert(0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       deps |= 1u << (uint32_t)dep; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return deps; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const char *lib_name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int index = -1; | 
					
						
							|  |  |  |   for (int i = 0; i < MAX_LIB; i++) { | 
					
						
							|  |  |  |     if (lib->libs[i] == NULL) { | 
					
						
							|  |  |  |       index = i; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (index > -1) { | 
					
						
							|  |  |  |     lib->libs[index] = lib_code; | 
					
						
							|  |  |  |     BLI_strncpy(lib->libs_name[index], lib_name, MAX_LIB_NAME); | 
					
						
							| 
									
										
										
										
											2020-03-15 21:55:42 +11:00
										 |  |  |     lib->libs_deps[index] = drw_shader_dependencies_get(lib, lib_code); | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     printf("Error: Too many libraries. Cannot add %s.\n", lib_name); | 
					
						
							|  |  |  |     BLI_assert(0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return an allocN'ed string containing the shader code with its dependencies prepended.
 | 
					
						
							|  |  |  |  * Caller must free the string with MEM_freeN after use. */ | 
					
						
							| 
									
										
										
										
											2020-07-15 14:40:28 +02:00
										 |  |  | char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib, const char *shader_code) | 
					
						
							| 
									
										
										
										
											2020-03-11 17:07:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   uint32_t deps = drw_shader_dependencies_get(lib, shader_code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DynStr *ds = BLI_dynstr_new(); | 
					
						
							|  |  |  |   /* Add all dependencies recursively. */ | 
					
						
							|  |  |  |   for (int i = MAX_LIB - 1; i > -1; i--) { | 
					
						
							|  |  |  |     if (lib->libs[i] && (deps & (1u << (uint32_t)i))) { | 
					
						
							|  |  |  |       deps |= lib->libs_deps[i]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Concatenate all needed libs into one string. */ | 
					
						
							|  |  |  |   for (int i = 0; i < MAX_LIB; i++) { | 
					
						
							|  |  |  |     if (deps & 1u) { | 
					
						
							|  |  |  |       BLI_dynstr_append(ds, lib->libs[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     deps = deps >> 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_dynstr_append(ds, shader_code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   char *str = BLI_dynstr_get_cstring(ds); | 
					
						
							|  |  |  |   BLI_dynstr_free(ds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return str; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |