GPU: refactor clipped drawing from DRW into GPU
authorCampbell Barton <ideasman42@gmail.com>
Tue, 5 Feb 2019 22:15:16 +0000 (09:15 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 5 Feb 2019 22:15:16 +0000 (09:15 +1100)
Needed to fix T61196, supporting clipped back-buffer in the 3D view
which is done outside the draw module.

It was also inconvenient having DRW_shader_* versions of GPU_shader_*
API calls.

- Clipping distances are now supported as a shader configuration
  for builtin shaders.
- Add shader config argument when accessing builtin shaders.
- Move GPU_shader_create_from_arrays() from DRW to GPU.

22 files changed:
source/blender/draw/CMakeLists.txt
source/blender/draw/engines/basic/basic_engine.c
source/blender/draw/engines/external/external_engine.c
source/blender/draw/engines/workbench/workbench_deferred.c
source/blender/draw/engines/workbench/workbench_forward.c
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_builtin_shader.c [deleted file]
source/blender/draw/intern/draw_builtin_shader.h [deleted file]
source/blender/draw/intern/draw_common.c
source/blender/draw/intern/draw_common.h
source/blender/draw/intern/draw_manager.c
source/blender/draw/intern/draw_manager_shader.c
source/blender/draw/modes/edit_lattice_mode.c
source/blender/draw/modes/edit_mesh_mode.c
source/blender/draw/modes/object_mode.c
source/blender/draw/modes/overlay_mode.c
source/blender/draw/modes/paint_vertex_mode.c
source/blender/draw/modes/paint_weight_mode.c
source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/shaders/gpu_shader_cfg_world_clip_lib.glsl [moved from source/blender/draw/modes/shaders/common_world_clip_lib.glsl with 100% similarity]

index 1b7c2a1..74a9b3a 100644 (file)
@@ -50,7 +50,6 @@ set(INC_SYS
 set(SRC
        intern/draw_anim_viz.c
        intern/draw_armature.c
-       intern/draw_builtin_shader.c
        intern/draw_cache.c
        intern/draw_cache_impl_curve.c
        intern/draw_cache_impl_displist.c
@@ -130,7 +129,6 @@ set(SRC
 
        DRW_engine.h
        intern/DRW_render.h
-       intern/draw_builtin_shader.h
        intern/draw_cache.h
        intern/draw_cache_impl.h
        intern/draw_common.h
@@ -248,7 +246,6 @@ data_to_c_simple(modes/shaders/common_hair_refine_vert.glsl SRC)
 data_to_c_simple(modes/shaders/common_view_lib.glsl SRC)
 data_to_c_simple(modes/shaders/common_fxaa_lib.glsl SRC)
 data_to_c_simple(modes/shaders/common_fullscreen_vert.glsl SRC)
-data_to_c_simple(modes/shaders/common_world_clip_lib.glsl SRC)
 data_to_c_simple(modes/shaders/animviz_mpath_lines_vert.glsl SRC)
 data_to_c_simple(modes/shaders/animviz_mpath_lines_geom.glsl SRC)
 data_to_c_simple(modes/shaders/animviz_mpath_points_vert.glsl SRC)
index d22f4cc..cdc625f 100644 (file)
@@ -65,7 +65,7 @@ typedef struct BASIC_Shaders {
 /* *********** STATIC *********** */
 
 static struct {
-       BASIC_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       BASIC_Shaders sh_data[GPU_SHADER_CFG_LEN];
 } e_data = {NULL}; /* Engine data */
 
 typedef struct BASIC_PrivateData {
@@ -79,11 +79,11 @@ typedef struct BASIC_PrivateData {
 static void basic_engine_init(void *UNUSED(vedata))
 {
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        /* Depth prepass */
        if (!sh_data->depth) {
-               sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_slot);
+               sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_cfg);
        }
 }
 
@@ -93,7 +93,7 @@ static void basic_cache_init(void *vedata)
        BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const RegionView3D *rv3d = draw_ctx->rv3d;
        const bool is_clip = (rv3d->rflag & RV3D_CLIPPING) != 0;
 
index d7e2909..d493088 100644 (file)
@@ -91,7 +91,7 @@ static void external_engine_init(void *UNUSED(vedata))
 {
        /* Depth prepass */
        if (!e_data.depth_sh) {
-               e_data.depth_sh = DRW_shader_create_3D_depth_only(DRW_SHADER_SLOT_DEFAULT);
+               e_data.depth_sh = DRW_shader_create_3D_depth_only(GPU_SHADER_CFG_DEFAULT);
        }
 }
 
index 18b4712..0991546 100644 (file)
@@ -88,7 +88,7 @@ static struct {
 
 /* Shaders */
 extern char datatoc_common_hair_lib_glsl[];
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 extern char datatoc_workbench_prepass_vert_glsl[];
 extern char datatoc_workbench_prepass_frag_glsl[];
@@ -160,14 +160,14 @@ static char *workbench_build_prepass_vert(bool is_hair)
        char *str = NULL;
        if (!is_hair) {
                return BLI_string_joinN(
-                       datatoc_common_world_clip_lib_glsl,
+                       datatoc_gpu_shader_cfg_world_clip_lib_glsl,
                        datatoc_workbench_prepass_vert_glsl);
        }
 
        DynStr *ds = BLI_dynstr_new();
 
        BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
-       BLI_dynstr_append(ds, datatoc_common_world_clip_lib_glsl);
+       BLI_dynstr_append(ds, datatoc_gpu_shader_cfg_world_clip_lib_glsl);
        BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
 
        str = BLI_dynstr_get_cstring(ds);
index 1f3d141..10dfbb4 100644 (file)
@@ -61,7 +61,7 @@ static struct {
 } e_data = {{NULL}};
 
 /* Shaders */
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 extern char datatoc_common_hair_lib_glsl[];
 
 extern char datatoc_workbench_forward_composite_frag_glsl[];
@@ -82,14 +82,14 @@ static char *workbench_build_forward_vert(bool is_hair)
        char *str = NULL;
        if (!is_hair) {
                return BLI_string_joinN(
-                       datatoc_common_world_clip_lib_glsl,
+                       datatoc_gpu_shader_cfg_world_clip_lib_glsl,
                        datatoc_workbench_prepass_vert_glsl);
        }
 
        DynStr *ds = BLI_dynstr_new();
 
        BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
-       BLI_dynstr_append(ds, datatoc_common_world_clip_lib_glsl);
+       BLI_dynstr_append(ds, datatoc_gpu_shader_cfg_world_clip_lib_glsl);
        BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
 
        str = BLI_dynstr_get_cstring(ds);
index 87a1add..d9b2e89 100644 (file)
@@ -240,11 +240,6 @@ void DRW_multisamples_resolve(
 /* Shaders */
 struct GPUShader *DRW_shader_create(
         const char *vert, const char *geom, const char *frag, const char *defines);
-struct DRW_ShaderCreateFromArray_Params { const char **vert, **geom, **frag, **defs; };
-struct GPUShader *DRW_shader_create_from_arrays_impl(
-        const struct DRW_ShaderCreateFromArray_Params *params);
-#define DRW_shader_create_from_arrays(...) \
-       DRW_shader_create_from_arrays_impl(&(const struct DRW_ShaderCreateFromArray_Params)__VA_ARGS__)
 struct GPUShader *DRW_shader_create_with_lib(
         const char *vert, const char *geom, const char *frag, const char *lib, const char *defines);
 struct GPUShader *DRW_shader_create_with_transform_feedback(
@@ -253,7 +248,7 @@ struct GPUShader *DRW_shader_create_with_transform_feedback(
 struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
 struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
 struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
-struct GPUShader *DRW_shader_create_3D_depth_only(eDRW_ShaderSlot slot);
+struct GPUShader *DRW_shader_create_3D_depth_only(eGPUShaderConfig slot);
 struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool deferred);
 struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool deferred);
 struct GPUMaterial *DRW_shader_create_from_world(
@@ -584,7 +579,7 @@ typedef struct DRWContextState {
 
        eObjectMode object_mode;
 
-       eDRW_ShaderSlot shader_slot;
+       eGPUShaderConfig shader_cfg;
 
        /** Last resort (some functions take this as an arg so we can't easily avoid).
         * May be NULL when used for selection or depth buffer. */
diff --git a/source/blender/draw/intern/draw_builtin_shader.c b/source/blender/draw/intern/draw_builtin_shader.c
deleted file mode 100644 (file)
index 5da2271..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.
- */
-
-/** \file draw_builtin_shader.c
- *  \ingroup draw
- * Draw manager versions of #eGPUBuiltinShader, see #GPU_shader_get_builtin_shader.
- *
- * Allows for modifications to shaders (currently only clipping support).
- * Follow GPU_shader.h conventions to avoid annoyance.
- */
-
-#include "BLI_utildefines.h"
-
-#include "GPU_shader.h"
-
-#include "DRW_render.h"
-
-#include "draw_builtin_shader.h"  /* own include */
-
-
-extern char datatoc_common_world_clip_lib_glsl[];
-
-/* Add shaders to this list when support is added. */
-#define GPU_SHADER_IS_SUPPORTED(shader_id) \
-       ELEM(shader_id, \
-            GPU_SHADER_3D_UNIFORM_COLOR, \
-            GPU_SHADER_3D_SMOOTH_COLOR, \
-            GPU_SHADER_3D_DEPTH_ONLY, \
-            GPU_SHADER_CAMERA, \
-            GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, \
-            GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, \
-            GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, \
-            GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, \
-            GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR, \
-            GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED, \
-            GPU_SHADER_3D_GROUNDLINE, \
-            GPU_SHADER_3D_GROUNDPOINT, \
-            GPU_SHADER_DISTANCE_LINES, \
-            GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR)
-
-/* cache of built-in shaders (each is created on first use) */
-static struct {
-       GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS];
-} g_sh_data[DRW_SHADER_SLOT_LEN - 1] = {{{NULL}}};
-
-static GPUShader *drw_shader_get_builtin_shader_clipped(eGPUBuiltinShader shader_id)
-{
-       const char *world_clip_lib = datatoc_common_world_clip_lib_glsl;
-       const char *world_clip_def = "#define USE_WORLD_CLIP_PLANES\n";
-
-       struct  { const char *vert, *frag, *geom, *defs; } shader_code;
-       GPU_shader_get_builtin_shader_code(
-               shader_id,
-               &shader_code.vert,
-               &shader_code.frag,
-               &shader_code.geom,
-               &shader_code.defs);
-
-       /* In rare cases geometry shaders calculate clipping themselves. */
-       return DRW_shader_create_from_arrays({
-               .vert = (const char *[]){world_clip_lib, shader_code.vert, NULL},
-               .geom = (const char *[]){shader_code.geom ? world_clip_lib : NULL, shader_code.geom, NULL},
-               .frag = (const char *[]){shader_code.frag, NULL},
-               .defs = (const char *[]){world_clip_def, shader_code.defs, NULL},
-       });
-}
-
-GPUShader *DRW_shader_get_builtin_shader(eGPUBuiltinShader shader_id, eDRW_ShaderSlot slot)
-{
-       BLI_assert(GPU_SHADER_IS_SUPPORTED(shader_id));
-
-       if (slot == DRW_SHADER_SLOT_DEFAULT) {
-               return GPU_shader_get_builtin_shader(shader_id);
-       }
-
-       GPUShader **builtin_shaders = g_sh_data[slot - 1].builtin_shaders;
-
-       if (builtin_shaders[shader_id] != NULL) {
-               return builtin_shaders[shader_id];
-       }
-
-       if (slot == DRW_SHADER_SLOT_CLIPPED) {
-               builtin_shaders[shader_id] = drw_shader_get_builtin_shader_clipped(shader_id);
-               return builtin_shaders[shader_id];
-       }
-       else {
-               BLI_assert(0);
-               return NULL;
-       }
-}
-
-void DRW_shader_free_builtin_shaders(void)
-{
-       for (int j = 0; j < (DRW_SHADER_SLOT_LEN - 1); j++) {
-               GPUShader **builtin_shaders = g_sh_data[j].builtin_shaders;
-               for (int i = 0; i < GPU_NUM_BUILTIN_SHADERS; i++) {
-                       if (builtin_shaders[i]) {
-                               GPU_shader_free(builtin_shaders[i]);
-                               builtin_shaders[i] = NULL;
-                       }
-               }
-       }
-}
diff --git a/source/blender/draw/intern/draw_builtin_shader.h b/source/blender/draw/intern/draw_builtin_shader.h
deleted file mode 100644 (file)
index f8bf3c7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-
-/** \file draw_builtin_shader.h
- *  \ingroup draw
- */
-
-#ifndef __DRAW_BUILTIN_SHADER_H__
-#define __DRAW_BUILTIN_SHADER_H__
-
-struct GPUShader;
-
-struct GPUShader *DRW_shader_get_builtin_shader(eGPUBuiltinShader shader_id, eDRW_ShaderSlot slot);
-void DRW_shader_free_builtin_shaders(void);
-
-#endif  /* __DRAW_BUILTIN_SHADER_H__ */
index f43efa1..0b0510a 100644 (file)
@@ -32,7 +32,6 @@
 #include "BKE_colorband.h"
 
 #include "draw_common.h"
-#include "draw_builtin_shader.h"
 
 #if 0
 #define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \
@@ -230,7 +229,7 @@ extern char datatoc_armature_stick_frag_glsl[];
 extern char datatoc_armature_dof_vert_glsl[];
 
 extern char datatoc_common_globals_lib_glsl[];
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
@@ -261,7 +260,7 @@ typedef struct COMMON_Shaders {
        struct GPUShader *mball_handles;
 } COMMON_Shaders;
 
-static COMMON_Shaders g_shaders[DRW_SHADER_SLOT_LEN] = {{NULL}};
+static COMMON_Shaders g_shaders[GPU_SHADER_CFG_LEN] = {{NULL}};
 
 static struct {
        struct GPUVertFormat *instance_screenspace;
@@ -292,7 +291,7 @@ void DRW_globals_free(void)
                MEM_SAFE_FREE(*format);
        }
 
-       for (int j = 0; j < DRW_SHADER_SLOT_LEN; j++) {
+       for (int j = 0; j < GPU_SHADER_CFG_LEN; j++) {
                struct GPUShader **shader = &g_shaders[j].shape_outline;
                for (int i = 0; i < sizeof(g_shaders[j]) / sizeof(void *); ++i, ++shader) {
                        DRW_SHADER_FREE_SAFE(*shader);
@@ -338,49 +337,49 @@ DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(DRWPass *pass, const floa
 }
 
 DRWShadingGroup *shgroup_dynpoints_uniform_color(
-        DRWPass *pass, const float color[4], const float *size, eDRW_ShaderSlot shader_slot)
+        DRWPass *pass, const float color[4], const float *size, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, shader_slot);
+       GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA, shader_cfg);
 
        DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
        DRW_shgroup_uniform_vec4(grp, "color", color, 1);
        DRW_shgroup_uniform_float(grp, "size", size, 1);
        DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, const float color[4], eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE, shader_slot);
+       GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_GROUNDLINE, shader_cfg);
 
        DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
        DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, const float color[4], eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT, shader_slot);
+       GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_GROUNDPOINT, shader_cfg);
 
        DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
        DRW_shgroup_uniform_vec4(grp, "color", color, 1);
        DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
 DRWShadingGroup *shgroup_instance_screenspace(
-        DRWPass *pass, struct GPUBatch *geom, const float *size, eDRW_ShaderSlot shader_slot)
+        DRWPass *pass, struct GPUBatch *geom, const float *size, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR, shader_slot);
+       GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_screenspace, {
                {"world_pos", DRW_ATTR_FLOAT, 3},
@@ -391,7 +390,7 @@ DRWShadingGroup *shgroup_instance_screenspace(
        DRW_shgroup_uniform_float(grp, "size", size, 1);
        DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
        DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
@@ -428,9 +427,9 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct GPUBatch *geom)
 }
 
 DRWShadingGroup *shgroup_instance_screen_aligned(
-        DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+        DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED, shader_slot);
+       GPUShader *sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
                {"color",               DRW_ATTR_FLOAT, 3},
@@ -440,15 +439,15 @@ DRWShadingGroup *shgroup_instance_screen_aligned(
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned);
        DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_scaled, {
                {"color",               DRW_ATTR_FLOAT, 3},
@@ -457,15 +456,15 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct GPUBatch *geom, e
        });
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_scaled);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_sized, {
                {"color",               DRW_ATTR_FLOAT, 4},
@@ -475,15 +474,15 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_Sha
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized);
        DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_sized, {
                {"color",               DRW_ATTR_FLOAT, 4},
@@ -492,19 +491,19 @@ DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass, struct GPUBatch *geom, eD
        });
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       COMMON_Shaders *sh_data = &g_shaders[shader_slot];
-       const char *world_clip_lib_or_empty = (shader_slot == DRW_SHADER_SLOT_CLIPPED) ? datatoc_common_world_clip_lib_glsl : "";
-       const char *world_clip_def_or_empty = (shader_slot == DRW_SHADER_SLOT_CLIPPED) ? "#define USE_WORLD_CLIP_PLANES\n" : "";
+       COMMON_Shaders *sh_data = &g_shaders[shader_cfg];
+       const char *world_clip_lib_or_empty = (shader_cfg == GPU_SHADER_CFG_CLIPPED) ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
+       const char *world_clip_def_or_empty = (shader_cfg == GPU_SHADER_CFG_CLIPPED) ? "#define USE_WORLD_CLIP_PLANES\n" : "";
        if (sh_data->empty_axes_sh == NULL) {
-               sh_data->empty_axes_sh = DRW_shader_create_from_arrays({
+               sh_data->empty_axes_sh = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_object_empty_axes_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -519,7 +518,7 @@ DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass, struct GPUBatch *geo
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_data->empty_axes_sh, pass, geom, g_formats.instance_sized);
        DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
@@ -541,9 +540,9 @@ DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct GPUBatch *geom,
        return grp;
 }
 
-DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_CAMERA, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_CAMERA, shader_cfg);
 
        DRW_shgroup_instance_format(g_formats.instance_camera, {
                {"color",               DRW_ATTR_FLOAT, 3},
@@ -554,15 +553,15 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom, e
        });
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_camera);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_DISTANCE_LINES, shader_cfg);
        static float point_size = 4.0f;
 
        DRW_shgroup_instance_format(g_formats.instance_distance_lines, {
@@ -574,15 +573,15 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch
 
        DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_distance_lines);
        DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
-DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot)
+DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg)
 {
-       GPUShader *sh_inst = DRW_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, shader_slot);
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, shader_cfg);
        static const int True = true;
        static const int False = false;
 
@@ -595,7 +594,7 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom, eDR
        DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
        DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
        DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
@@ -603,7 +602,7 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom, eDR
 
 DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_axes == NULL) {
                sh_data->bone_axes = DRW_shader_create(
                        datatoc_armature_axes_vert_glsl, NULL,
@@ -626,7 +625,7 @@ DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass)
 
 DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_envelope_outline == NULL) {
                sh_data->bone_envelope_outline = DRW_shader_create(
                        datatoc_armature_envelope_outline_vert_glsl, NULL,
@@ -651,7 +650,7 @@ DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass)
 
 DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_envelope_distance == NULL) {
                sh_data->bone_envelope_distance = DRW_shader_create(
                        datatoc_armature_envelope_solid_vert_glsl, NULL,
@@ -674,7 +673,7 @@ DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass)
 
 DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, bool transp)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_envelope == NULL) {
                sh_data->bone_envelope = DRW_shader_create(
                        datatoc_armature_envelope_solid_vert_glsl, NULL,
@@ -700,7 +699,7 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, bool transp
 
 DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->mball_handles == NULL) {
                sh_data->mball_handles = DRW_shader_create(
                        datatoc_object_mball_handles_vert_glsl, NULL,
@@ -725,7 +724,7 @@ DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass)
 /* Only works with batches with adjacency infos. */
 DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct GPUBatch *geom)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->shape_outline == NULL) {
                sh_data->shape_outline = DRW_shader_create(
                        datatoc_armature_shape_outline_vert_glsl,
@@ -749,7 +748,7 @@ DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct GPUBa
 
 DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatch *geom, bool transp)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->shape_solid == NULL) {
                sh_data->shape_solid = DRW_shader_create(
                        datatoc_armature_shape_solid_vert_glsl, NULL,
@@ -772,7 +771,7 @@ DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatc
 
 DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass, bool transp)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_sphere == NULL) {
                sh_data->bone_sphere = DRW_shader_create(
                        datatoc_armature_sphere_solid_vert_glsl, NULL,
@@ -796,7 +795,7 @@ DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass, bool transp)
 
 DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_sphere_outline == NULL) {
                sh_data->bone_sphere_outline = DRW_shader_create(
                        datatoc_armature_sphere_outline_vert_glsl, NULL,
@@ -819,7 +818,7 @@ DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
 
 DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_stick == NULL) {
                sh_data->bone_stick = DRW_shader_create(
                        datatoc_armature_stick_vert_glsl, NULL,
@@ -847,7 +846,7 @@ DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
 
 struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct GPUBatch *geom)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->bone_dofs == NULL) {
                sh_data->bone_dofs = DRW_shader_create(
                        datatoc_armature_dof_vert_glsl, NULL,
@@ -871,7 +870,7 @@ struct DRWShadingGroup *shgroup_instance_bone_dof(struct DRWPass *pass, struct G
 
 struct GPUShader *mpath_line_shader_get(void)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->mpath_line_sh == NULL) {
                sh_data->mpath_line_sh = DRW_shader_create_with_lib(
                        datatoc_animviz_mpath_lines_vert_glsl,
@@ -886,7 +885,7 @@ struct GPUShader *mpath_line_shader_get(void)
 
 struct GPUShader *mpath_points_shader_get(void)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (sh_data->mpath_points_sh == NULL) {
                sh_data->mpath_points_sh = DRW_shader_create_with_lib(
                        datatoc_animviz_mpath_points_vert_glsl,
@@ -900,7 +899,7 @@ struct GPUShader *mpath_points_shader_get(void)
 
 struct GPUShader *volume_velocity_shader_get(bool use_needle)
 {
-       COMMON_Shaders *sh_data = &g_shaders[DRW_SHADER_SLOT_DEFAULT];
+       COMMON_Shaders *sh_data = &g_shaders[GPU_SHADER_CFG_DEFAULT];
        if (use_needle) {
                if (sh_data->volume_velocity_needle_sh == NULL) {
                        sh_data->volume_velocity_needle_sh = DRW_shader_create(
index fc9c83e..43763f5 100644 (file)
@@ -33,16 +33,6 @@ struct PTCacheEdit;
 struct ParticleSystem;
 struct ViewLayer;
 
-/**
- * Support selecting shaders with different options compiled in.
- * Needed for clipping support because it means using a separate set of shaders.
- */
-typedef enum eDRW_ShaderSlot {
-       DRW_SHADER_SLOT_DEFAULT = 0,
-       DRW_SHADER_SLOT_CLIPPED = 1,
-} eDRW_ShaderSlot;
-#define DRW_SHADER_SLOT_LEN 2
-
 #define UBO_FIRST_COLOR colorWire
 #define UBO_LAST_COLOR colorGridAxisZ
 
@@ -136,21 +126,21 @@ void DRW_shgroup_world_clip_planes_from_rv3d(struct DRWShadingGroup *shgrp, cons
 
 struct DRWShadingGroup *shgroup_dynlines_flat_color(struct DRWPass *pass);
 struct DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(struct DRWPass *pass, const float color[4]);
-struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, const float color[4], const float *size, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, const float color[4], eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct GPUBatch *geom, const float *size, eDRW_ShaderSlot shader_slot);
+struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, const float color[4], const float *size, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, const float color[4], eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, const float color[4], eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct GPUBatch *geom, const float *size, eGPUShaderConfig shader_cfg);
 struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct GPUBatch *geom);
 struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct GPUBatch *geom);
-struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_instance_empty_axes(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_instance_alpha(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
+struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_instance_empty_axes(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_instance_alpha(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
 struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct GPUBatch *geom, int *baseid);
-struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
-struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct GPUBatch *geom, eDRW_ShaderSlot shader_slot);
+struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
+struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct GPUBatch *geom, eGPUShaderConfig shader_cfg);
 struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass);
 struct DRWShadingGroup *shgroup_instance_bone_axes(struct DRWPass *pass);
 struct DRWShadingGroup *shgroup_instance_bone_envelope_distance(struct DRWPass *pass);
index 2daeccd..6021b1c 100644 (file)
@@ -72,7 +72,6 @@
 #include "draw_cache_impl.h"
 
 #include "draw_mode_engines.h"
-#include "draw_builtin_shader.h"
 #include "engines/eevee/eevee_engine.h"
 #include "engines/basic/basic_engine.h"
 #include "engines/workbench/workbench_engine.h"
@@ -538,9 +537,9 @@ static void drw_context_state_init(void)
                DST.draw_ctx.object_pose = NULL;
        }
 
-       DST.draw_ctx.shader_slot = DRW_SHADER_SLOT_DEFAULT;
+       DST.draw_ctx.shader_cfg = GPU_SHADER_CFG_DEFAULT;
        if (DST.draw_ctx.rv3d && DST.draw_ctx.rv3d->rflag & RV3D_CLIPPING) {
-               DST.draw_ctx.shader_slot = DRW_SHADER_SLOT_CLIPPED;
+               DST.draw_ctx.shader_cfg = GPU_SHADER_CFG_CLIPPED;
        }
 }
 
@@ -2602,7 +2601,6 @@ void DRW_engines_free(void)
        DRW_shape_cache_free();
        DRW_stats_free();
        DRW_globals_free();
-       DRW_shader_free_builtin_shaders();
 
        DrawEngineType *next;
        for (DrawEngineType *type = DRW_engines.first; type; type = next) {
index 35ac6e3..c91a66d 100644 (file)
@@ -40,7 +40,6 @@
 #include "WM_types.h"
 
 #include "draw_manager.h"
-#include "draw_builtin_shader.h"
 
 extern char datatoc_gpu_shader_2D_vert_glsl[];
 extern char datatoc_gpu_shader_3D_vert_glsl[];
@@ -263,72 +262,6 @@ GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *fra
        return GPU_shader_create(vert, frag, geom, NULL, defines, __func__);
 }
 
-static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
-{
-       bool is_alloc = false;
-       if (str_arr == NULL) {
-               *r_is_alloc = false;
-               return NULL;
-       }
-       /* Skip empty strings (avoid alloc if we can). */
-       while (str_arr[0] && str_arr[0][0] == '\0') {
-               str_arr++;
-       }
-       int i;
-       for (i = 0; str_arr[i]; i++) {
-               if (i != 0 && str_arr[i][0] != '\0') {
-                       is_alloc = true;
-               }
-       }
-       *r_is_alloc = is_alloc;
-       if (is_alloc) {
-               return BLI_string_join_arrayN(str_arr, i);
-       }
-       else {
-               return str_arr[0];
-       }
-}
-
-/**
- * Use via #DRW_shader_create_from_arrays macro (avoids passing in param).
- *
- * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
- *
- * It has the advantage that each item can be conditionally included
- * without having to build the string inline, then free it.
- *
- * \param params: NULL terminated arrays of strings.
- *
- * Example:
- * \code{.c}
- * sh = DRW_shader_create_from_arrays({
- *         .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
- *         .geom = (const char *[]){shader_geom_glsl, NULL},
- *         .frag = (const char *[]){shader_frag_glsl, NULL},
- *         .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
- * });
- * \endcode
- */
-struct GPUShader *DRW_shader_create_from_arrays_impl(
-        const struct DRW_ShaderCreateFromArray_Params *params)
-{
-       struct { const char *str; bool is_alloc;} str_dst[4] = {0};
-       const char **str_src[4] = {params->vert, params->geom, params->frag, params->defs};
-
-       for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
-               str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
-       }
-
-       GPUShader *sh = DRW_shader_create(str_dst[0].str, str_dst[1].str, str_dst[2].str, str_dst[3].str);
-
-       for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
-               if (str_dst[i].is_alloc) {
-                       MEM_freeN((void *)str_dst[i].str);
-               }
-       }
-       return sh;
-}
-
 GPUShader *DRW_shader_create_with_lib(
         const char *vert, const char *geom, const char *frag, const char *lib, const char *defines)
 {
@@ -379,9 +312,9 @@ GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
        return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__);
 }
 
-GPUShader *DRW_shader_create_3D_depth_only(eDRW_ShaderSlot slot)
+GPUShader *DRW_shader_create_3D_depth_only(eGPUShaderConfig shader_cfg)
 {
-       return DRW_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY, slot);
+       return GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_DEPTH_ONLY, shader_cfg);
 }
 
 GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options, bool deferred)
index 988a750..4727049 100644 (file)
@@ -30,9 +30,7 @@
 
 #include "draw_common.h"
 
-#include "draw_builtin_shader.h"
-
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 extern char datatoc_common_globals_lib_glsl[];
 
 extern char datatoc_edit_lattice_overlay_loosevert_vert_glsl[];
@@ -99,7 +97,7 @@ static struct {
         * init in EDIT_LATTICE_engine_init();
         * free in EDIT_LATTICE_engine_free(); */
 
-       EDIT_LATTICE_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       EDIT_LATTICE_Shaders sh_data[GPU_SHADER_CFG_LEN];
 
 } e_data = {NULL}; /* Engine data */
 
@@ -139,20 +137,20 @@ static void EDIT_LATTICE_engine_init(void *vedata)
         */
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
        if (is_clip) {
                DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
        }
-       const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+       const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
        const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
        if (!sh_data->wire) {
-               sh_data->wire = DRW_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR, draw_ctx->shader_slot);
+               sh_data->wire = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_SMOOTH_COLOR, draw_ctx->shader_cfg);
        }
 
        if (!sh_data->overlay_vert) {
-               sh_data->overlay_vert = DRW_shader_create_from_arrays({
+               sh_data->overlay_vert = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){
                            world_clip_lib_or_empty,
                            datatoc_common_globals_lib_glsl,
@@ -177,7 +175,7 @@ static void EDIT_LATTICE_cache_init(void *vedata)
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
        RegionView3D *rv3d = draw_ctx->rv3d;
-       EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        if (!stl->g_data) {
                /* Alloc transient pointers */
index 368edb7..e5904ab 100644 (file)
@@ -43,7 +43,7 @@
 #include "BLI_dynstr.h"
 #include "BLI_string_utils.h"
 
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 extern char datatoc_paint_weight_vert_glsl[];
 extern char datatoc_paint_weight_frag_glsl[];
@@ -120,7 +120,7 @@ typedef struct EDIT_MESH_Shaders {
 
 /* *********** STATIC *********** */
 static struct {
-       EDIT_MESH_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       EDIT_MESH_Shaders sh_data[GPU_SHADER_CFG_LEN];
 
        /* temp buffer texture */
        struct GPUTexture *occlude_wire_depth_tx;
@@ -162,7 +162,7 @@ static void EDIT_MESH_engine_init(void *vedata)
        EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
 
        const float *viewport_size = DRW_viewport_size_get();
@@ -182,11 +182,11 @@ static void EDIT_MESH_engine_init(void *vedata)
                DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
        }
 
-       const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+       const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
        const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
        if (!sh_data->weight_face) {
-               sh_data->weight_face = DRW_shader_create_from_arrays({
+               sh_data->weight_face = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -199,40 +199,40 @@ static void EDIT_MESH_engine_init(void *vedata)
                        geom_sh_code[0] = NULL;
                }
                const char *use_geom_def = use_geom_shader ? "#define USE_GEOM_SHADER\n" : "";
-               sh_data->overlay_face = DRW_shader_create_from_arrays({
+               sh_data->overlay_face = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define FACE\n", NULL},
                });
-               sh_data->overlay_edge = DRW_shader_create_from_arrays({
+               sh_data->overlay_edge = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE\n", NULL},
                        .geom = (use_geom_shader) ? geom_sh_code : NULL,
                });
-               sh_data->overlay_edge_flat = DRW_shader_create_from_arrays({
+               sh_data->overlay_edge_flat = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE\n", "#define FLAT\n", NULL},
                        .geom = (use_geom_shader) ? geom_sh_code : NULL,
                });
-               sh_data->overlay_edge_deco = DRW_shader_create_from_arrays({
+               sh_data->overlay_edge_deco = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE_DECORATION\n", "#define FLAT\n", NULL},
                        .geom = (use_geom_shader) ? geom_sh_code : NULL,
                });
-               sh_data->overlay_vert = DRW_shader_create_from_arrays({
+               sh_data->overlay_vert = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define VERT\n", NULL},
                });
-               sh_data->overlay_facedot = DRW_shader_create_from_arrays({
+               sh_data->overlay_facedot = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define FACEDOT\n", NULL},
                });
-               sh_data->overlay_facefill = DRW_shader_create_from_arrays({
+               sh_data->overlay_facefill = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL},
                        .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -241,28 +241,28 @@ static void EDIT_MESH_engine_init(void *vedata)
 
                sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
 
-               sh_data->normals_face = DRW_shader_create_from_arrays({
+               sh_data->normals_face = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define FACE_NORMALS\n", NULL},
                });
 
-               sh_data->normals_loop = DRW_shader_create_from_arrays({
+               sh_data->normals_loop = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define LOOP_NORMALS\n", NULL},
                });
 
-               sh_data->normals = DRW_shader_create_from_arrays({
+               sh_data->normals = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
 
-               sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_slot);
+               sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_cfg);
 
                sh_data->ghost_clear_depth = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL);
        }
@@ -278,7 +278,7 @@ static DRWPass *edit_mesh_create_overlay_pass(
        RegionView3D *rv3d = draw_ctx->rv3d;
        Scene *scene = draw_ctx->scene;
        ToolSettings *tsettings = scene->toolsettings;
-       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
        const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
        float winmat[4][4];
@@ -393,7 +393,7 @@ static void EDIT_MESH_cache_init(void *vedata)
        RegionView3D *rv3d = draw_ctx->rv3d;
        Scene *scene = draw_ctx->scene;
        ToolSettings *tsettings = scene->toolsettings;
-       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        static float zero = 0.0f;
 
        if (!stl->g_data) {
index cf6c9e3..95ff598 100644 (file)
 #include "draw_mode_engines.h"
 #include "draw_manager_text.h"
 #include "draw_common.h"
-#include "draw_builtin_shader.h"
 
 #include "DEG_depsgraph_query.h"
 
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 extern char datatoc_object_outline_prepass_vert_glsl[];
 extern char datatoc_object_outline_prepass_geom_glsl[];
 extern char datatoc_object_outline_prepass_frag_glsl[];
@@ -317,7 +316,7 @@ static struct {
        struct GPUVertFormat *empty_image_format;
        struct GPUVertFormat *empty_image_wire_format;
 
-       OBJECT_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       OBJECT_Shaders sh_data[GPU_SHADER_CFG_LEN];
 
        float camera_pos[3];
        float grid_settings[5];
@@ -397,20 +396,20 @@ static void OBJECT_engine_init(void *vedata)
 
        /* Shaders */
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
-       const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+       const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
        const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
        if (!sh_data->outline_resolve) {
                /* Outline */
-               sh_data->outline_prepass = DRW_shader_create_from_arrays({
+               sh_data->outline_prepass = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_gpu_shader_3D_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
-               sh_data->outline_prepass_wire = DRW_shader_create_from_arrays({
+               sh_data->outline_prepass_wire = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_object_outline_prepass_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_object_outline_prepass_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
@@ -449,12 +448,12 @@ static void OBJECT_engine_init(void *vedata)
                                "#define DEPTH_FRONT " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_FRONT) "\n"
                                "#define DEPTH_BACK " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_BACK) "\n");
 
-                       sh_data->object_empty_image = DRW_shader_create_from_arrays({
+                       sh_data->object_empty_image = GPU_shader_create_from_arrays({
                                .vert = (const char *[]){world_clip_lib_or_empty, datatoc_object_empty_image_vert_glsl, NULL},
                                .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL},
                                .defs = (const char *[]){world_clip_def_or_empty, empty_image_defs, NULL},
                        });
-                       sh_data->object_empty_image_wire = DRW_shader_create_from_arrays({
+                       sh_data->object_empty_image_wire = GPU_shader_create_from_arrays({
                                .vert = (const char *[]){world_clip_lib_or_empty, datatoc_object_empty_image_vert_glsl, NULL},
                                .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL},
                                .defs = (const char *[]){world_clip_def_or_empty, "#define USE_WIRE\n", empty_image_defs, NULL},
@@ -483,7 +482,7 @@ static void OBJECT_engine_init(void *vedata)
                        datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_flat_id_frag_glsl, NULL);
 
                /* Loose Points */
-               sh_data->loose_points = DRW_shader_create_from_arrays({
+               sh_data->loose_points = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_gpu_shader_3D_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_object_loose_points_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -661,37 +660,37 @@ static void OBJECT_engine_free(void)
        }
 }
 
-static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh, eDRW_ShaderSlot shader_slot)
+static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh, eGPUShaderConfig shader_cfg)
 {
        DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
        DRW_shgroup_uniform_int(grp, "baseId", ofs, 1);
 
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
 /* currently same as 'shgroup_outline', new function to avoid confustion */
-static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh, eDRW_ShaderSlot shader_slot)
+static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh, eGPUShaderConfig shader_cfg)
 {
        DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
        DRW_shgroup_uniform_vec4(grp, "color", col, 1);
 
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
 }
 
 /* currently same as 'shgroup_outline', new function to avoid confustion */
-static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUShader *sh, eDRW_ShaderSlot shader_slot)
+static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUShader *sh, eGPUShaderConfig shader_cfg)
 {
        DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
        DRW_shgroup_uniform_vec4(grp, "color", col, 1);
        DRW_shgroup_uniform_vec4(grp, "innerColor", G_draw.block.colorEditMeshMiddle, 1);
 
-       if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+       if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
        }
        return grp;
@@ -914,7 +913,7 @@ static void image_calc_aspect(Image *ima, const int size[2], float r_image_aspec
 
 static void DRW_shgroup_empty_image(
         OBJECT_Shaders *sh_data, OBJECT_ShadingGroupList *sgl,
-        Object *ob, const float color[3], RegionView3D *rv3d, eDRW_ShaderSlot shader_slot)
+        Object *ob, const float color[3], RegionView3D *rv3d, eGPUShaderConfig shader_cfg)
 {
        /* TODO: 'StereoViews', see draw_empty_image. */
 
@@ -954,7 +953,7 @@ static void DRW_shgroup_empty_image(
                DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
                DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
                DRW_shgroup_uniform_vec4(grp, "objectColor", ob->col, 1);
-               if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
                }
                DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat);
@@ -969,7 +968,7 @@ static void DRW_shgroup_empty_image(
                DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
                DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
                DRW_shgroup_uniform_vec3(grp, "color", color, 1);
-               if (shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
                }
                DRW_shgroup_call_add(grp, DRW_cache_image_plane_wire_get(), ob->obmat);
@@ -984,7 +983,7 @@ static void OBJECT_cache_init(void *vedata)
        DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
        OBJECT_PrivateData *g_data;
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
        const bool do_outline_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
@@ -1008,10 +1007,10 @@ static void OBJECT_cache_init(void *vedata)
                        sh = sh_data->outline_prepass_wire;
                }
 
-               g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh, draw_ctx->shader_slot);
-               g_data->outlines_select_dupli = shgroup_outline(psl->outlines, &g_data->id_ofs_select_dupli, sh, draw_ctx->shader_slot);
-               g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh, draw_ctx->shader_slot);
-               g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh, draw_ctx->shader_slot);
+               g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh, draw_ctx->shader_cfg);
+               g_data->outlines_select_dupli = shgroup_outline(psl->outlines, &g_data->id_ofs_select_dupli, sh, draw_ctx->shader_cfg);
+               g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh, draw_ctx->shader_cfg);
+               g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh, draw_ctx->shader_cfg);
 
                g_data->id_ofs_select = 0;
                g_data->id_ofs_select_dupli = 0;
@@ -1169,129 +1168,129 @@ static void OBJECT_cache_init(void *vedata)
 
                /* Empties */
                geom = DRW_cache_plain_axes_get();
-               sgl->plain_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->plain_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_cube_get();
-               sgl->cube = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->cube = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_circle_get();
-               sgl->circle = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->circle = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_sphere_get();
-               sgl->sphere = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->sphere = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_sphere_get();
                sgl->sphere_solid = shgroup_instance_solid(sgl->non_meshes, geom);
 
                geom = DRW_cache_empty_cylinder_get();
-               sgl->cylinder = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->cylinder = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_capsule_cap_get();
-               sgl->capsule_cap = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->capsule_cap = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_capsule_body_get();
-               sgl->capsule_body = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->capsule_body = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_cone_get();
-               sgl->cone = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->cone = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_arrow_get();
-               sgl->single_arrow = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->single_arrow = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_line_get();
-               sgl->single_arrow_line = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->single_arrow_line = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_bone_arrows_get();
-               sgl->empty_axes = shgroup_instance_empty_axes(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->empty_axes = shgroup_instance_empty_axes(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Force Field */
                geom = DRW_cache_field_wind_get();
-               sgl->field_wind = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_wind = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_field_force_get();
-               sgl->field_force = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_force = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_field_vortex_get();
-               sgl->field_vortex = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_vortex = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_screenspace_circle_get();
-               sgl->field_curve_sta = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_curve_sta = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Grease Pencil */
                geom = DRW_cache_gpencil_axes_get();
-               sgl->gpencil_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->gpencil_axes = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Speaker */
                geom = DRW_cache_speaker_get();
-               sgl->speaker = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->speaker = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Probe */
                static float probeSize = 14.0f;
                geom = DRW_cache_lightprobe_cube_get();
-               sgl->probe_cube = shgroup_instance_screenspace(sgl->non_meshes, geom, &probeSize, draw_ctx->shader_slot);
+               sgl->probe_cube = shgroup_instance_screenspace(sgl->non_meshes, geom, &probeSize, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lightprobe_grid_get();
-               sgl->probe_grid = shgroup_instance_screenspace(sgl->non_meshes, geom, &probeSize, draw_ctx->shader_slot);
+               sgl->probe_grid = shgroup_instance_screenspace(sgl->non_meshes, geom, &probeSize, draw_ctx->shader_cfg);
 
                static float probePlanarSize = 20.0f;
                geom = DRW_cache_lightprobe_planar_get();
-               sgl->probe_planar = shgroup_instance_screenspace(sgl->non_meshes, geom, &probePlanarSize, draw_ctx->shader_slot);
+               sgl->probe_planar = shgroup_instance_screenspace(sgl->non_meshes, geom, &probePlanarSize, draw_ctx->shader_cfg);
 
                /* Camera */
                geom = DRW_cache_camera_get();
-               sgl->camera = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_camera_frame_get();
-               sgl->camera_frame = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_frame = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_camera_tria_get();
-               sgl->camera_tria = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_tria = shgroup_camera_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_plain_axes_get();
-               sgl->camera_focus = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_focus = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_line_get();
-               sgl->camera_clip = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
-               sgl->camera_mist = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_clip = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
+               sgl->camera_mist = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_line_endpoints_get();
-               sgl->camera_clip_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
-               sgl->camera_mist_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_clip_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
+               sgl->camera_mist_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_quad_get();
-               sgl->camera_stereo_plane = shgroup_instance_alpha(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_stereo_plane = shgroup_instance_alpha(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_cube_get();
-               sgl->camera_stereo_volume = shgroup_instance_alpha(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_stereo_volume = shgroup_instance_alpha(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_empty_cube_get();
-               sgl->camera_stereo_volume_wires = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->camera_stereo_volume_wires = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                BLI_listbase_clear(&sgl->camera_path);
 
                /* Texture Space */
                geom = DRW_cache_empty_cube_get();
-               sgl->texspace = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->texspace = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Wires (for loose edges) */
-               sh = DRW_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR, draw_ctx->shader_slot);
-               sgl->wire = shgroup_wire(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_slot);
-               sgl->wire_select = shgroup_wire(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_slot);
-               sgl->wire_transform = shgroup_wire(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_slot);
-               sgl->wire_active = shgroup_wire(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_slot);
+               sh = GPU_shader_get_builtin_shader_with_config(GPU_SHADER_3D_UNIFORM_COLOR, draw_ctx->shader_cfg);
+               sgl->wire = shgroup_wire(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_cfg);
+               sgl->wire_select = shgroup_wire(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_cfg);
+               sgl->wire_transform = shgroup_wire(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_cfg);
+               sgl->wire_active = shgroup_wire(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_cfg);
                /* Wire (duplicator) */
-               sgl->wire_dupli = shgroup_wire(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_slot);
-               sgl->wire_dupli_select = shgroup_wire(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_slot);
+               sgl->wire_dupli = shgroup_wire(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_cfg);
+               sgl->wire_dupli_select = shgroup_wire(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_cfg);
 
                /* Points (loose points) */
                sh = sh_data->loose_points;
-               sgl->points = shgroup_points(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_slot);
-               sgl->points_select = shgroup_points(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_slot);
-               sgl->points_transform = shgroup_points(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_slot);
-               sgl->points_active = shgroup_points(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_slot);
+               sgl->points = shgroup_points(sgl->non_meshes, gb->colorWire, sh, draw_ctx->shader_cfg);
+               sgl->points_select = shgroup_points(sgl->non_meshes, gb->colorSelect, sh, draw_ctx->shader_cfg);
+               sgl->points_transform = shgroup_points(sgl->non_meshes, gb->colorTransform, sh, draw_ctx->shader_cfg);
+               sgl->points_active = shgroup_points(sgl->non_meshes, gb->colorActive, sh, draw_ctx->shader_cfg);
                /* Points (duplicator) */
-               sgl->points_dupli = shgroup_points(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_slot);
-               sgl->points_dupli_select = shgroup_points(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_slot);
+               sgl->points_dupli = shgroup_points(sgl->non_meshes, gb->colorDupli, sh, draw_ctx->shader_cfg);
+               sgl->points_dupli_select = shgroup_points(sgl->non_meshes, gb->colorDupliSelect, sh, draw_ctx->shader_cfg);
                DRW_shgroup_state_disable(sgl->points, DRW_STATE_BLEND);
                DRW_shgroup_state_disable(sgl->points_select, DRW_STATE_BLEND);
                DRW_shgroup_state_disable(sgl->points_transform, DRW_STATE_BLEND);
@@ -1309,50 +1308,50 @@ static void OBJECT_cache_init(void *vedata)
 
                /* start with buflimit because we don't want stipples */
                geom = DRW_cache_single_line_get();
-               sgl->lamp_buflimit = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_buflimit = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
-               sgl->lamp_center = shgroup_dynpoints_uniform_color(sgl->non_meshes, gb->colorLampNoAlpha, &gb->sizeLampCenter, draw_ctx->shader_slot);
+               sgl->lamp_center = shgroup_dynpoints_uniform_color(sgl->non_meshes, gb->colorLampNoAlpha, &gb->sizeLampCenter, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_get();
-               sgl->lamp_circle = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircle, draw_ctx->shader_slot);
+               sgl->lamp_circle = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircle, draw_ctx->shader_cfg);
                geom = DRW_cache_lamp_shadows_get();
-               sgl->lamp_circle_shadow = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircleShadow, draw_ctx->shader_slot);
+               sgl->lamp_circle_shadow = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircleShadow, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_sunrays_get();
-               sgl->lamp_sunrays = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircle, draw_ctx->shader_slot);
+               sgl->lamp_sunrays = shgroup_instance_screenspace(sgl->non_meshes, geom, &gb->sizeLampCircle, draw_ctx->shader_cfg);
 
-               sgl->lamp_groundline = shgroup_groundlines_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_slot);
-               sgl->lamp_groundpoint = shgroup_groundpoints_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_slot);
+               sgl->lamp_groundline = shgroup_groundlines_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_cfg);
+               sgl->lamp_groundpoint = shgroup_groundpoints_uniform_color(sgl->non_meshes, gb->colorLamp, draw_ctx->shader_cfg);
 
                geom = DRW_cache_screenspace_circle_get();
-               sgl->lamp_area_sphere = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_area_sphere = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_area_square_get();
-               sgl->lamp_area_square = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_area_square = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_area_disk_get();
-               sgl->lamp_area_disk = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_area_disk = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_hemi_get();
-               sgl->lamp_hemi = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_hemi = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_line_get();
-               sgl->lamp_distance = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_distance = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_single_line_endpoints_get();
-               sgl->lamp_buflimit_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_buflimit_points = shgroup_distance_lines_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_spot_get();
-               sgl->lamp_spot_cone = shgroup_spot_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_cone = shgroup_spot_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_circle_get();
-               sgl->lamp_spot_blend = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_blend = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_spot_square_get();
-               sgl->lamp_spot_pyramid = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_pyramid = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_square_get();
-               sgl->lamp_spot_blend_rect = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_blend_rect = shgroup_instance(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* -------- STIPPLES ------- */
 
@@ -1363,34 +1362,34 @@ static void OBJECT_cache_init(void *vedata)
                /* Force Field Curve Guide End (here because of stipple) */
                /* TODO port to shader stipple */
                geom = DRW_cache_screenspace_circle_get();
-               sgl->field_curve_end = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_curve_end = shgroup_instance_screen_aligned(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Force Field Limits */
                /* TODO port to shader stipple */
                geom = DRW_cache_field_tube_limit_get();
-               sgl->field_tube_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_tube_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* TODO port to shader stipple */
                geom = DRW_cache_field_cone_limit_get();
-               sgl->field_cone_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_slot);
+               sgl->field_cone_limit = shgroup_instance_scaled(sgl->non_meshes, geom, draw_ctx->shader_cfg);
 
                /* Spot shapes */
                state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_CULL_FRONT;
                sgl->spot_shapes = psl->spot_shapes[i] = DRW_pass_create("Spot Shape Pass", state);
 
                geom = DRW_cache_lamp_spot_volume_get();
-               sgl->lamp_spot_volume = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_volume = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_spot_square_volume_get();
-               sgl->lamp_spot_volume_rect = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_volume_rect = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_cfg);
 
                geom = DRW_cache_lamp_spot_volume_get();
-               sgl->lamp_spot_volume_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_volume_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_cfg);
                DRW_shgroup_state_disable(sgl->lamp_spot_volume_outside, DRW_STATE_CULL_FRONT);
                DRW_shgroup_state_enable(sgl->lamp_spot_volume_outside, DRW_STATE_CULL_BACK);
 
                geom = DRW_cache_lamp_spot_square_volume_get();
-               sgl->lamp_spot_volume_rect_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_slot);
+               sgl->lamp_spot_volume_rect_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, draw_ctx->shader_cfg);
                DRW_shgroup_state_disable(sgl->lamp_spot_volume_rect_outside, DRW_STATE_CULL_FRONT);
                DRW_shgroup_state_enable(sgl->lamp_spot_volume_rect_outside, DRW_STATE_CULL_BACK);
        }
@@ -1406,8 +1405,8 @@ static void OBJECT_cache_init(void *vedata)
                outlineWidth = 1.0f * U.pixelsize;
                size = U.obcenter_dia * U.pixelsize + outlineWidth;
 
-               GPUShader *sh = DRW_shader_get_builtin_shader(
-                       GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, draw_ctx->shader_slot);
+               GPUShader *sh = GPU_shader_get_builtin_shader_with_config(
+                       GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, draw_ctx->shader_cfg);
 
                /* Active */
                grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
@@ -1415,7 +1414,7 @@ static void OBJECT_cache_init(void *vedata)
                DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
                DRW_shgroup_uniform_vec4(grp, "color", gb->colorActive, 1);
                DRW_shgroup_uniform_vec4(grp, "outlineColor", gb->colorOutline, 1);
-               if (draw_ctx->shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (draw_ctx->shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
                }
                stl->g_data->center_active = grp;
@@ -1423,7 +1422,7 @@ static void OBJECT_cache_init(void *vedata)
                /* Select */
                grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
                DRW_shgroup_uniform_vec4(grp, "color", gb->colorSelect, 1);
-               if (draw_ctx->shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (draw_ctx->shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
                }
                stl->g_data->center_selected = grp;
@@ -1431,7 +1430,7 @@ static void OBJECT_cache_init(void *vedata)
                /* Deselect */
                grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
                DRW_shgroup_uniform_vec4(grp, "color", gb->colorDeselect, 1);
-               if (draw_ctx->shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (draw_ctx->shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
                }
                stl->g_data->center_deselected = grp;
@@ -1439,7 +1438,7 @@ static void OBJECT_cache_init(void *vedata)
                /* Select (library) */
                grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
                DRW_shgroup_uniform_vec4(grp, "color", gb->colorLibrarySelect, 1);
-               if (draw_ctx->shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (draw_ctx->shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
                }
                stl->g_data->center_selected_lib = grp;
@@ -1447,7 +1446,7 @@ static void OBJECT_cache_init(void *vedata)
                /* Deselect (library) */
                grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
                DRW_shgroup_uniform_vec4(grp, "color", gb->colorLibrary, 1);
-               if (draw_ctx->shader_slot == DRW_SHADER_SLOT_CLIPPED) {
+               if (draw_ctx->shader_cfg == GPU_SHADER_CFG_CLIPPED) {
                        DRW_shgroup_world_clip_planes_from_rv3d(grp, draw_ctx->rv3d);
                }
                stl->g_data->center_deselected_lib = grp;
@@ -2120,7 +2119,7 @@ static void DRW_shgroup_empty_ex(
 
 static void DRW_shgroup_empty(
         OBJECT_Shaders *sh_data, OBJECT_ShadingGroupList *sgl,
-        Object *ob, ViewLayer *view_layer, RegionView3D *rv3d, eDRW_ShaderSlot shader_slot)
+        Object *ob, ViewLayer *view_layer, RegionView3D *rv3d, eGPUShaderConfig shader_cfg)
 {
        float *color;
        DRW_object_wire_theme_get(ob, view_layer, &color);
@@ -2136,7 +2135,7 @@ static void DRW_shgroup_empty(
                        DRW_shgroup_empty_ex(sgl, ob->obmat, &ob->empty_drawsize, ob->empty_drawtype, color);
                        break;
                case OB_EMPTY_IMAGE:
-                       DRW_shgroup_empty_image(sh_data, sgl, ob, color, rv3d, shader_slot);
+                       DRW_shgroup_empty_image(sh_data, sgl, ob, color, rv3d, shader_cfg);
                        break;
        }
 }
@@ -2896,7 +2895,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
        ModifierData *md = NULL;
        int theme_id = TH_UNDEFINED;
        const int ob_visibility = DRW_object_visibility_in_active_context(ob);
-       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        /* Handle particles first in case the emitter itself shouldn't be rendered. */
        if (ob_visibility & OB_VISIBLE_PARTICLES) {
@@ -3054,7 +3053,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
                        if (hide_object_extra) {
                                break;
                        }
-                       DRW_shgroup_empty(sh_data, sgl, ob, view_layer, rv3d, draw_ctx->shader_slot);
+                       DRW_shgroup_empty(sh_data, sgl, ob, view_layer, rv3d, draw_ctx->shader_cfg);
                        break;
                case OB_GPENCIL:
                        if (hide_object_extra) {
index 243acc2..dc022fb 100644 (file)
@@ -71,10 +71,10 @@ typedef struct OVERLAY_Shaders {
 
 /* *********** STATIC *********** */
 static struct {
-       OVERLAY_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN];
 } e_data = {NULL};
 
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 /* Shaders */
 extern char datatoc_overlay_face_orientation_frag_glsl[];
@@ -92,7 +92,7 @@ static void overlay_engine_init(void *vedata)
        OVERLAY_StorageList *stl = data->stl;
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
 
        if (is_clip) {
@@ -105,12 +105,12 @@ static void overlay_engine_init(void *vedata)
        }
        stl->g_data->ghost_stencil_test = false;
 
-       const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+       const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
        const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
        if (!sh_data->face_orientation) {
                /* Face orientation */
-               sh_data->face_orientation = DRW_shader_create_from_arrays({
+               sh_data->face_orientation = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_orientation_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_overlay_face_orientation_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -118,18 +118,18 @@ static void overlay_engine_init(void *vedata)
        }
 
        if (!sh_data->face_wireframe) {
-               sh_data->select_wireframe = DRW_shader_create_from_arrays({
+               sh_data->select_wireframe = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_depth_only_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define SELECT_EDGES\n", NULL},
                });
-               sh_data->face_wireframe = DRW_shader_create_from_arrays({
+               sh_data->face_wireframe = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
-               sh_data->face_wireframe_sculpt = DRW_shader_create_from_arrays({
+               sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
                        .geom = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
@@ -147,7 +147,7 @@ static void overlay_cache_init(void *vedata)
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
        RegionView3D *rv3d = draw_ctx->rv3d;
-       OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        const DRWContextState *DCS = DRW_context_state_get();
 
index 95c9c4b..de59249 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "DEG_depsgraph_query.h"
 
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 extern char datatoc_paint_vertex_vert_glsl[];
 extern char datatoc_paint_vertex_frag_glsl[];
@@ -76,7 +76,7 @@ typedef struct PAINT_VERTEX_Shaders {
 /* *********** STATIC *********** */
 
 static struct {
-       PAINT_VERTEX_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       PAINT_VERTEX_Shaders sh_data[GPU_SHADER_CFG_LEN];
 } e_data = {{{NULL}}}; /* Engine data */
 
 typedef struct PAINT_VERTEX_PrivateData {
@@ -91,7 +91,7 @@ typedef struct PAINT_VERTEX_PrivateData {
 static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
 {
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
 
        if (is_clip) {
@@ -99,25 +99,25 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
        }
 
        if (!sh_data->vcolor_face) {
-               const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+               const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
                const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
-               sh_data->vcolor_face = DRW_shader_create_from_arrays({
+               sh_data->vcolor_face = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_vertex_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_paint_vertex_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
-               sh_data->wire_overlay = DRW_shader_create_from_arrays({
+               sh_data->wire_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_MODE\n", NULL},
                });
-               sh_data->face_overlay = DRW_shader_create_from_arrays({
+               sh_data->face_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_face_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
-               sh_data->vert_overlay = DRW_shader_create_from_arrays({
+               sh_data->vert_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_paint_vert_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -132,7 +132,7 @@ static void PAINT_VERTEX_cache_init(void *vedata)
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const View3D *v3d = draw_ctx->v3d;
        const RegionView3D *rv3d = draw_ctx->rv3d;
-       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       PAINT_VERTEX_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        if (!stl->g_data) {
                /* Alloc transient pointers */
index c8b8e08..ed45734 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "DEG_depsgraph_query.h"
 
-extern char datatoc_common_world_clip_lib_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 extern char datatoc_paint_face_vert_glsl[];
 extern char datatoc_paint_weight_vert_glsl[];
@@ -75,7 +75,7 @@ typedef struct PAINT_WEIGHT_Shaders {
 /* *********** STATIC *********** */
 
 static struct {
-       PAINT_WEIGHT_Shaders sh_data[DRW_SHADER_SLOT_LEN];
+       PAINT_WEIGHT_Shaders sh_data[GPU_SHADER_CFG_LEN];
 
        int actdef;
 } e_data = {NULL}; /* Engine data */
@@ -92,7 +92,7 @@ typedef struct PAINT_WEIGHT_PrivateData {
 static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
 {
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
        const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
 
        if (is_clip) {
@@ -100,28 +100,28 @@ static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
        }
 
        if (!sh_data->weight_face) {
-               const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+               const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
                const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
 
-               sh_data->weight_face = DRW_shader_create_from_arrays({
+               sh_data->weight_face = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
 
-               sh_data->wire_overlay = DRW_shader_create_from_arrays({
+               sh_data->wire_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, "#define WEIGHT_MODE\n", NULL},
                });
 
-               sh_data->face_overlay = DRW_shader_create_from_arrays({
+               sh_data->face_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_face_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
                });
 
-               sh_data->vert_overlay = DRW_shader_create_from_arrays({
+               sh_data->vert_overlay = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
                        .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_vert_frag_glsl, NULL},
                        .defs = (const char *[]){world_clip_def_or_empty, NULL},
@@ -136,7 +136,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const View3D *v3d = draw_ctx->v3d;
        RegionView3D *rv3d = draw_ctx->rv3d;
-       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
+       PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
 
        if (!stl->g_data) {
                /* Alloc transient pointers */
index b65b2e6..b76edf4 100644 (file)
@@ -242,6 +242,8 @@ data_to_c_simple(shaders/gpu_shader_gpencil_stroke_geom.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_gpencil_fill_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_gpencil_fill_frag.glsl SRC)
 
+data_to_c_simple(shaders/gpu_shader_cfg_world_clip_lib.glsl SRC)
+
 
 if(WITH_MOD_SMOKE)
        add_definitions(-DWITH_SMOKE)
index d2380d2..428c763 100644 (file)
@@ -60,6 +60,12 @@ GPUShader *GPU_shader_create_ex(
         const char **tf_names,
         const int tf_count,
         const char *shader_name);
+struct GPU_ShaderCreateFromArray_Params { const char **vert, **geom, **frag, **defs; };
+struct GPUShader *GPU_shader_create_from_arrays_impl(
+        const struct GPU_ShaderCreateFromArray_Params *params);
+#define GPU_shader_create_from_arrays(...) \
+       GPU_shader_create_from_arrays_impl(&(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__)
+
 void GPU_shader_free(GPUShader *shader);
 
 void GPU_shader_bind(GPUShader *shader);
@@ -350,9 +356,15 @@ typedef enum eGPUBuiltinShader {
        /* Selection */
        GPU_SHADER_3D_FLAT_SELECT_ID,
        GPU_SHADER_3D_UNIFORM_SELECT_ID,
-
-       GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
 } eGPUBuiltinShader;
+#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_UNIFORM_SELECT_ID + 1)
+
+/** Support multiple configurations. */
+typedef enum eGPUShaderConfig {
+       GPU_SHADER_CFG_DEFAULT     = 0,
+       GPU_SHADER_CFG_CLIPPED     = 1,
+} eGPUShaderConfig;
+#define GPU_SHADER_CFG_LEN (GPU_SHADER_CFG_CLIPPED + 1)
 
 /** Keep these in sync with:
  * - `gpu_shader_image_interlace_frag.glsl`
@@ -364,7 +376,10 @@ typedef enum eGPUInterlaceShader {
        GPU_SHADER_INTERLACE_CHECKER           = 2,
 } eGPUInterlaceShader;
 
-GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader);
+GPUShader *GPU_shader_get_builtin_shader_with_config(
+        eGPUBuiltinShader shader, eGPUShaderConfig shader_cfg);
+GPUShader *GPU_shader_get_builtin_shader(
+        eGPUBuiltinShader shader);
 
 void GPU_shader_get_builtin_shader_code(
         eGPUBuiltinShader shader,
index 7c69938..99f4df2 100644 (file)
@@ -28,6 +28,7 @@
 #include "BLI_math_vector.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
+#include "BLI_string_utils.h"
 
 #include "BKE_appdir.h"
 #include "BKE_global.h"
@@ -169,9 +170,10 @@ extern char datatoc_gpu_shader_gpencil_stroke_geom_glsl[];
 
 extern char datatoc_gpu_shader_gpencil_fill_vert_glsl[];
 extern char datatoc_gpu_shader_gpencil_fill_frag_glsl[];
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
 
 /* cache of built-in shaders (each is created on first use) */
-static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL };
+static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {NULL};
 
 #ifndef NDEBUG
 static uint g_shaderid = 0;
@@ -500,6 +502,73 @@ GPUShader *GPU_shader_create_ex(
 #undef DEBUG_SHADER_VERTEX
 #undef DEBUG_SHADER_NONE
 
+static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
+{
+       bool is_alloc = false;
+       if (str_arr == NULL) {
+               *r_is_alloc = false;
+               return NULL;
+       }
+       /* Skip empty strings (avoid alloc if we can). */
+       while (str_arr[0] && str_arr[0][0] == '\0') {
+               str_arr++;
+       }
+       int i;
+       for (i = 0; str_arr[i]; i++) {
+               if (i != 0 && str_arr[i][0] != '\0') {
+                       is_alloc = true;
+               }
+       }
+       *r_is_alloc = is_alloc;
+       if (is_alloc) {
+               return BLI_string_join_arrayN(str_arr, i);
+       }
+       else {
+               return str_arr[0];
+       }
+}
+
+/**
+ * Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
+ *
+ * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
+ *
+ * It has the advantage that each item can be conditionally included
+ * without having to build the string inline, then free it.
+ *
+ * \param params: NULL terminated arrays of strings.
+ *
+ * Example:
+ * \code{.c}
+ * sh = GPU_shader_create_from_arrays({
+ *         .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
+ *         .geom = (const char *[]){shader_geom_glsl, NULL},
+ *         .frag = (const char *[]){shader_frag_glsl, NULL},
+ *         .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
+ * });
+ * \endcode
+ */
+struct GPUShader *GPU_shader_create_from_arrays_impl(
+        const struct GPU_ShaderCreateFromArray_Params *params)
+{
+       struct { const char *str; bool is_alloc;} str_dst[4] = {0};
+       const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs};
+
+       for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
+               str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
+       }
+
+       GPUShader *sh = GPU_shader_create(
+               str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
+
+       for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
+               if (str_dst[i].is_alloc) {
+                       MEM_freeN((void *)str_dst[i].str);
+               }
+       }
+       return sh;
+}
+
 void GPU_shader_bind(GPUShader *shader)
 {
        BLI_assert(shader && shader->program);
@@ -670,7 +739,7 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
        return attr ? attr->location : -1;
 }
 
-static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = {
+static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
        [GPU_SHADER_TEXT] = {
                .vert = datatoc_gpu_shader_text_vert_glsl,
                .geom = datatoc_gpu_shader_text_geom_glsl,
@@ -1101,11 +1170,14 @@ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = {
        },
 };
 
-GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
+GPUShader *GPU_shader_get_builtin_shader_with_config(
+        eGPUBuiltinShader shader, eGPUShaderConfig shader_cfg)
 {
-       BLI_assert(shader < GPU_NUM_BUILTIN_SHADERS);
+       BLI_assert(shader < GPU_SHADER_BUILTIN_LEN);
+       BLI_assert(shader_cfg < GPU_SHADER_CFG_LEN);
+       GPUShader **sh_p = &builtin_shaders[shader_cfg][shader];
 
-       if (builtin_shaders[shader] == NULL) {
+       if (*sh_p == NULL) {
                GPUShaderStages stages_legacy = {NULL};
                const GPUShaderStages *stages = &builtin_shader_stages[shader];
 
@@ -1128,11 +1200,46 @@ GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
                }
 
                /* common case */
-               builtin_shaders[shader] = GPU_shader_create(
-                       stages->vert, stages->frag, stages->geom, NULL, stages->defs, __func__);
+               if (shader_cfg == GPU_SHADER_CFG_DEFAULT) {
+                       *sh_p = GPU_shader_create(stages->vert, stages->frag, stages->geom, NULL, stages->defs, __func__);
+               }
+               else if (shader_cfg == GPU_SHADER_CFG_CLIPPED) {
+                       /* Remove eventually, for now ensure support for each shader has been added. */
+                       BLI_assert(ELEM(shader,
+                                       GPU_SHADER_3D_UNIFORM_COLOR,
+                                       GPU_SHADER_3D_SMOOTH_COLOR,
+                                       GPU_SHADER_3D_DEPTH_ONLY,
+                                       GPU_SHADER_CAMERA,
+                                       GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE,
+                                       GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE,
+                                       GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
+                                       GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
+                                       GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR,
+                                       GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED,
+                                       GPU_SHADER_3D_GROUNDLINE,
+                                       GPU_SHADER_3D_GROUNDPOINT,
+                                       GPU_SHADER_DISTANCE_LINES,
+                                       GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR));
+                       const char *world_clip_lib = datatoc_gpu_shader_cfg_world_clip_lib_glsl;
+                       const char *world_clip_def = "#define USE_WORLD_CLIP_PLANES\n";
+                       /* In rare cases geometry shaders calculate clipping themselves. */
+                       *sh_p = GPU_shader_create_from_arrays({
+                               .vert = (const char *[]){world_clip_lib, stages->vert, NULL},
+                               .geom = (const char *[]){stages->geom ? world_clip_lib : NULL, stages->geom, NULL},
+                               .frag = (const char *[]){stages->frag, NULL},
+                               .defs = (const char *[]){world_clip_def, stages->defs, NULL},
+                       });
+               }
+               else {
+                       BLI_assert(0);
+               }
        }
 
-       return builtin_shaders[shader];
+       return *sh_p;
+}
+GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
+{
+       return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT);
 }
 
 void GPU_shader_get_builtin_shader_code(
@@ -1149,10 +1256,12 @@ void GPU_shader_get_builtin_shader_code(
 
 void GPU_shader_free_builtin_shaders(void)
 {
-       for (int i = 0; i < GPU_NUM_BUILTIN_SHADERS; ++i) {
-               if (builtin_shaders[i]) {
-                       GPU_shader_free(builtin_shaders[i]);
-                       builtin_shaders[i] = NULL;
+       for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) {
+               for (int j = 0; j < GPU_SHADER_BUILTIN_LEN; j++) {
+                       if (builtin_shaders[i][j]) {
+                               GPU_shader_free(builtin_shaders[i][j]);
+                               builtin_shaders[i][j] = NULL;
+                       }
                }
        }
 }