Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_shader.c')
-rw-r--r--source/blender/gpu/intern/gpu_shader.c1062
1 files changed, 646 insertions, 416 deletions
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 66945b13aba..97be9c79811 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -25,81 +25,172 @@
* ***** END GPL LICENSE BLOCK *****
*/
+/** \file blender/gpu/intern/gpu_shader.c
+ * \ingroup gpu
+ */
+
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
#include "BLI_math_vector.h"
#include "BLI_path_util.h"
+#include "BLI_string.h"
#include "BKE_appdir.h"
#include "BKE_global.h"
-#include "GPU_compositing.h"
-#include "GPU_debug.h"
+#include "DNA_space_types.h"
+
#include "GPU_extensions.h"
-#include "GPU_glew.h"
+#include "GPU_context.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
-#include "GPU_material.h"
+#include "GPU_uniformbuffer.h"
-/* TODO(sergey): Find better default values for this constants. */
-#define MAX_DEFINE_LENGTH 1024
-#define MAX_EXT_DEFINE_LENGTH 1024
+#include "gpu_shader_private.h"
+
+/* Adjust these constants as needed. */
+#define MAX_DEFINE_LENGTH 256
+#define MAX_EXT_DEFINE_LENGTH 256
/* Non-generated shaders */
+extern char datatoc_gpu_shader_depth_only_frag_glsl[];
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_checker_frag_glsl[];
+extern char datatoc_gpu_shader_diag_stripes_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_flat_color_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl[];
+extern char datatoc_gpu_shader_flat_color_frag_glsl[];
+extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[];
+extern char datatoc_gpu_shader_flat_id_frag_glsl[];
+extern char datatoc_gpu_shader_2D_area_borders_vert_glsl[];
+extern char datatoc_gpu_shader_2D_vert_glsl[];
+extern char datatoc_gpu_shader_2D_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_uniform_alpha_vert_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl[];
+extern char datatoc_gpu_shader_2D_image_vert_glsl[];
+extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[];
+extern char datatoc_gpu_shader_2D_image_multi_rect_vert_glsl[];
+extern char datatoc_gpu_shader_2D_widget_base_vert_glsl[];
+extern char datatoc_gpu_shader_2D_widget_base_frag_glsl[];
+extern char datatoc_gpu_shader_2D_widget_shadow_vert_glsl[];
+extern char datatoc_gpu_shader_2D_widget_shadow_frag_glsl[];
+extern char datatoc_gpu_shader_2D_nodelink_frag_glsl[];
+extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[];
+
+extern char datatoc_gpu_shader_3D_image_vert_glsl[];
+extern char datatoc_gpu_shader_image_frag_glsl[];
+extern char datatoc_gpu_shader_image_linear_frag_glsl[];
+extern char datatoc_gpu_shader_image_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_desaturate_frag_glsl[];
+extern char datatoc_gpu_shader_image_varying_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_interlace_frag_glsl[];
+extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
+extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
+extern char datatoc_gpu_shader_image_depth_copy_frag_glsl[];
+extern char datatoc_gpu_shader_image_multisample_resolve_frag_glsl[];
+extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
+extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_flat_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
+extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
+
+extern char datatoc_gpu_shader_instance_vert_glsl[];
+extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_variying_size_variying_id_vert_glsl[];
+extern char datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screen_aligned_vert_glsl[];
+extern char datatoc_gpu_shader_instance_camera_vert_glsl[];
+extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
+extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
+extern char datatoc_gpu_shader_instance_mball_handles_vert_glsl[];
+
+extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
+
+extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl[];
+extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_varying_size_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl[];
+extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl[];
+
+extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[];
+extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[];
+extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[];
+extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl[];
+extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_vert_glsl[];
+
+extern char datatoc_gpu_shader_edges_front_back_persp_vert_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_persp_geom_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl[];
+extern char datatoc_gpu_shader_edges_front_back_ortho_vert_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_vert_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_geom_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_simple_geom_glsl[];
+extern char datatoc_gpu_shader_edges_overlay_frag_glsl[];
+extern char datatoc_gpu_shader_text_vert_glsl[];
+extern char datatoc_gpu_shader_text_geom_glsl[];
+extern char datatoc_gpu_shader_text_frag_glsl[];
+extern char datatoc_gpu_shader_text_simple_vert_glsl[];
+extern char datatoc_gpu_shader_text_simple_geom_glsl[];
+extern char datatoc_gpu_shader_keyframe_diamond_vert_glsl[];
+extern char datatoc_gpu_shader_keyframe_diamond_frag_glsl[];
+
extern char datatoc_gpu_shader_fire_frag_glsl[];
extern char datatoc_gpu_shader_smoke_vert_glsl[];
extern char datatoc_gpu_shader_smoke_frag_glsl[];
-extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
-extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
-extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
-extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
-extern char datatoc_gpu_shader_fx_vert_glsl[];
-extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
-extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
-extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
-extern char datatoc_gpu_shader_fx_dof_hq_frag_glsl[];
-extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[];
-extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
-extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
-extern char datatoc_gpu_shader_fx_lib_glsl[];
-
-static struct GPUShadersGlobal {
- struct {
- GPUShader *vsm_store;
- GPUShader *sep_gaussian_blur;
- GPUShader *smoke;
- GPUShader *smoke_fire;
- GPUShader *smoke_coba;
- /* cache for shader fx. Those can exist in combinations so store them here */
- GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
- } shaders;
-} GG = {{NULL}};
-
-/* GPUShader */
-
-struct GPUShader {
- GLuint program; /* handle for full program (links shader stages below) */
-
- GLuint vertex; /* handle for vertex shader */
- GLuint geometry; /* handle for geometry shader */
- GLuint fragment; /* handle for fragment shader */
-
- int totattrib; /* total number of attributes */
- int uniforms; /* required uniforms */
-
- void *uniform_interface; /* cached uniform interface for shader. Data depends on shader */
-};
+
+extern char datatoc_gpu_shader_gpencil_stroke_vert_glsl[];
+extern char datatoc_gpu_shader_gpencil_stroke_frag_glsl[];
+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[];
+
+/* cache of built-in shaders (each is created on first use) */
+static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL };
+
+#ifndef NDEBUG
+static uint g_shaderid = 0;
+#endif
+
+typedef struct {
+ const char *vert;
+ const char *frag;
+ const char *geom; /* geometry stage runs between vert & frag, but is less common, so it goes last */
+} GPUShaderStages;
static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
{
- int i;
int line = 1;
fprintf(stderr, "GPUShader: %s error:\n", task);
- for (i = 0; i < totcode; i++) {
+ for (int i = 0; i < totcode; i++) {
const char *c, *pos, *end = code[i] + strlen(code[i]);
if (G.debug & G_DEBUG) {
@@ -122,143 +213,70 @@ static void shader_print_errors(const char *task, const char *log, const char **
static const char *gpu_shader_version(void)
{
- if (GLEW_VERSION_3_2) {
- if (GLEW_ARB_compatibility) {
- return "#version 150 compatibility\n";
- /* highest version that is widely supported
- * gives us native geometry shaders!
- * use compatibility profile so we can continue using builtin shader input/output names
- */
- }
- else {
- return "#version 130\n";
- /* latest version that is compatible with existing shaders */
- }
- }
- else if (GLEW_VERSION_3_1) {
- if (GLEW_ARB_compatibility) {
- return "#version 140\n";
- /* also need the ARB_compatibility extension, handled below */
- }
- else {
- return "#version 130\n";
- /* latest version that is compatible with existing shaders */
- }
- }
- else if (GLEW_VERSION_3_0) {
- return "#version 130\n";
- /* GLSL 1.3 has modern syntax/keywords/datatypes so use if available
- * older features are deprecated but still available without compatibility extension or profile
- */
- }
- else {
- return "#version 120\n";
- /* minimum supported */
- }
+ return "#version 330\n";
}
-
-static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH], bool use_geometry_shader)
+static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
{
/* enable extensions for features that are not part of our base GLSL version
* don't use an extension for something already available!
*/
+ if (GLEW_ARB_texture_gather) {
+ /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
+ * is reported to be supported but yield a compile error (see T55802). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
+ strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
+
+ /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
+ * shader so double check the preprocessor define (see T56544). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ strcat(defines, "#ifdef GL_ARB_texture_gather\n");
+ strcat(defines, "# define GPU_ARB_texture_gather\n");
+ strcat(defines, "#endif\n");
+ }
+ else {
+ strcat(defines, "#define GPU_ARB_texture_gather\n");
+ }
+ }
+ }
if (GLEW_ARB_texture_query_lod) {
- /* a #version 400 feature, but we use #version 150 maximum so use extension */
+ /* a #version 400 feature, but we use #version 330 maximum so use extension */
strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
}
-
- if (use_geometry_shader && GPU_geometry_shader_support_via_extension()) {
- strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
- }
-
- if (GLEW_VERSION_3_1 && !GLEW_VERSION_3_2 && GLEW_ARB_compatibility) {
- strcat(defines, "#extension GL_ARB_compatibility: enable\n");
- }
-
- if (!GLEW_VERSION_3_1) {
- if (GLEW_ARB_draw_instanced) {
- strcat(defines, "#extension GL_ARB_draw_instanced: enable\n");
- }
-
- if (!GLEW_VERSION_3_0 && GLEW_EXT_gpu_shader4) {
- strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n");
- /* TODO: maybe require this? shaders become so much nicer */
- }
- }
}
-static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
- bool use_opensubdiv,
- bool use_new_shading)
+static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
{
/* some useful defines to detect GPU type */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY))
strcat(defines, "#define GPU_ATI\n");
- if (GLEW_VERSION_3_0) {
- /* TODO(merwin): revisit this version check; GLEW_VERSION_3_0 means GL 3.0 or newer */
- strcat(defines, "#define CLIP_WORKAROUND\n");
- }
- }
else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
strcat(defines, "#define GPU_NVIDIA\n");
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
strcat(defines, "#define GPU_INTEL\n");
- if (GPU_bicubic_bump_support())
- strcat(defines, "#define BUMP_BICUBIC\n");
-
- if (GLEW_VERSION_3_0) {
- strcat(defines, "#define BIT_OPERATIONS\n");
- }
-
-#ifdef WITH_OPENSUBDIV
- /* TODO(sergey): Check whether we actually compiling shader for
- * the OpenSubdiv mesh.
- */
- if (use_opensubdiv) {
- strcat(defines, "#define USE_OPENSUBDIV\n");
-
- /* TODO(sergey): not strictly speaking a define, but this is
- * a global typedef which we don't have better place to define
- * in yet.
- */
- strcat(defines, "struct VertexData {\n"
- " vec4 position;\n"
- " vec3 normal;\n"
- " vec2 uv;"
- "};\n");
- }
-#else
- UNUSED_VARS(use_opensubdiv);
-#endif
-
- if (use_new_shading) {
- strcat(defines, "#define USE_NEW_SHADING\n");
- }
-
return;
}
-GPUShader *GPU_shader_create(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- int input,
- int output,
- int number)
+GPUShader *GPU_shader_create(
+ const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const char *shname)
{
- return GPU_shader_create_ex(vertexcode,
- fragcode,
- geocode,
- libcode,
- defines,
- input,
- output,
- number,
- GPU_SHADER_FLAGS_NONE);
+ return GPU_shader_create_ex(
+ vertexcode,
+ fragcode,
+ geocode,
+ libcode,
+ defines,
+ GPU_SHADER_TFB_NONE,
+ NULL,
+ 0,
+ shname);
}
#define DEBUG_SHADER_NONE ""
@@ -308,26 +326,17 @@ static void gpu_dump_shaders(const char **code, const int num_shaders, const cha
printf("Shader file written to disk: %s\n", shader_path);
}
-GPUShader *GPU_shader_create_ex(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- int input,
- int output,
- int number,
- const int flags)
+GPUShader *GPU_shader_create_ex(
+ const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const GPUShaderTFBType tf_type,
+ const char **tf_names,
+ const int tf_count,
+ const char *shname)
{
-#ifdef WITH_OPENSUBDIV
- /* TODO(sergey): used to add #version 150 to the geometry shader.
- * Could safely be renamed to "use_geometry_code" since it's very
- * likely any of geometry code will want to use GLSL 1.5.
- */
- bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0;
-#else
- UNUSED_VARS(flags);
- bool use_opensubdiv = false;
-#endif
GLint status;
GLchar log[5000];
GLsizei length = 0;
@@ -335,12 +344,15 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
char standard_defines[MAX_DEFINE_LENGTH] = "";
char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
- if (geocode && !GPU_geometry_shader_support())
- return NULL;
-
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
+#ifndef NDEBUG
+ BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
+#else
+ UNUSED_VARS(shname);
+#endif
+
if (vertexcode)
shader->vertex = glCreateShader(GL_VERTEX_SHADER);
if (fragcode)
@@ -360,10 +372,8 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
return NULL;
}
- gpu_shader_standard_defines(standard_defines,
- use_opensubdiv,
- (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0);
- gpu_shader_standard_extensions(standard_extensions, geocode != NULL);
+ gpu_shader_standard_defines(standard_defines);
+ gpu_shader_standard_extensions(standard_extensions);
if (vertexcode) {
const char *source[5];
@@ -402,18 +412,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
source[num_source++] = standard_extensions;
source[num_source++] = standard_defines;
-#ifdef WITH_OPENSUBDIV
- /* TODO(sergey): Move to fragment shader source code generation. */
- if (use_opensubdiv) {
- source[num_source++] =
- "#ifdef USE_OPENSUBDIV\n"
- "in block {\n"
- " VertexData v;\n"
- "} inpt;\n"
- "#endif\n";
- }
-#endif
-
if (defines) source[num_source++] = defines;
if (libcode) source[num_source++] = libcode;
source[num_source++] = fragcode;
@@ -461,22 +459,14 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
GPU_shader_free(shader);
return NULL;
}
-
- if (!use_opensubdiv) {
- GPU_shader_geometry_stage_primitive_io(shader, input, output, number);
- }
}
-#ifdef WITH_OPENSUBDIV
- if (use_opensubdiv) {
- glBindAttribLocation(shader->program, 0, "position");
- glBindAttribLocation(shader->program, 1, "normal");
- GPU_shader_geometry_stage_primitive_io(shader,
- GL_LINES_ADJACENCY_EXT,
- GL_TRIANGLE_STRIP,
- 4);
+ if (tf_names != NULL) {
+ glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
+ /* Primitive type must be setup */
+ BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
+ shader->feedback_transform_type = tf_type;
}
-#endif
glLinkProgram(shader->program);
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
@@ -492,18 +482,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
return NULL;
}
-#ifdef WITH_OPENSUBDIV
- /* TODO(sergey): Find a better place for this. */
- if (use_opensubdiv && GLEW_VERSION_4_1) {
- glProgramUniform1i(shader->program,
- glGetUniformLocation(shader->program, "FVarDataOffsetBuffer"),
- 30); /* GL_TEXTURE30 */
-
- glProgramUniform1i(shader->program,
- glGetUniformLocation(shader->program, "FVarDataBuffer"),
- 31); /* GL_TEXTURE31 */
- }
-#endif
+ shader->interface = GPU_shaderinterface_create(shader->program);
return shader;
}
@@ -515,20 +494,46 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
void GPU_shader_bind(GPUShader *shader)
{
- GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
+ BLI_assert(shader && shader->program);
+
glUseProgram(shader->program);
- GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
+ GPU_matrix_bind(shader->interface);
}
void GPU_shader_unbind(void)
{
- GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
glUseProgram(0);
- GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
+}
+
+bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
+{
+ if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
+ return false;
+ }
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
+
+ switch (shader->feedback_transform_type) {
+ case GPU_SHADER_TFB_POINTS: glBeginTransformFeedback(GL_POINTS); return true;
+ case GPU_SHADER_TFB_LINES: glBeginTransformFeedback(GL_LINES); return true;
+ case GPU_SHADER_TFB_TRIANGLES: glBeginTransformFeedback(GL_TRIANGLES); return true;
+ default: return false;
+ }
+}
+
+void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
+{
+ glEndTransformFeedback();
}
void GPU_shader_free(GPUShader *shader)
{
+#if 0 /* Would be nice to have, but for now the Deferred compilation
+ * does not have a GPUContext. */
+ BLI_assert(GPU_context_active_get() != NULL);
+#endif
+ BLI_assert(shader);
+
if (shader->vertex)
glDeleteShader(shader->vertex);
if (shader->geometry)
@@ -538,25 +543,43 @@ void GPU_shader_free(GPUShader *shader)
if (shader->program)
glDeleteProgram(shader->program);
- if (shader->uniform_interface)
- MEM_freeN(shader->uniform_interface);
+ if (shader->interface)
+ GPU_shaderinterface_discard(shader->interface);
MEM_freeN(shader);
}
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
{
- return glGetUniformLocation(shader->program, name);
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
+ return uniform ? uniform->location : -1;
+}
+
+int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(shader->interface, builtin);
+ return uniform ? uniform->location : -1;
+}
+
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+
+ const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ return ubo ? ubo->location : -1;
}
void *GPU_shader_get_interface(GPUShader *shader)
{
- return shader->uniform_interface;
+ return shader->interface;
}
-void GPU_shader_set_interface(GPUShader *shader, void *interface)
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
{
- shader->uniform_interface = interface;
+ return (int)shader->program;
}
void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
@@ -564,16 +587,12 @@ void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int leng
if (location == -1 || value == NULL)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
-
if (length == 1) glUniform1fv(location, arraysize, value);
else if (length == 2) glUniform2fv(location, arraysize, value);
else if (length == 3) glUniform3fv(location, arraysize, value);
else if (length == 4) glUniform4fv(location, arraysize, value);
else if (length == 9) glUniformMatrix3fv(location, arraysize, 0, value);
else if (length == 16) glUniformMatrix4fv(location, arraysize, 0, value);
-
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
@@ -581,14 +600,10 @@ void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int
if (location == -1)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
-
if (length == 1) glUniform1iv(location, arraysize, value);
else if (length == 2) glUniform2iv(location, arraysize, value);
else if (length == 3) glUniform3iv(location, arraysize, value);
else if (length == 4) glUniform4iv(location, arraysize, value);
-
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
@@ -596,223 +611,438 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
if (location == -1)
return;
- GPU_CHECK_ERRORS_AROUND(glUniform1i(location, value));
+ glUniform1i(location, value);
}
-void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, GPUUniformBuffer *ubo)
{
- if (GPU_geometry_shader_support_via_extension()) {
- /* geometry shaders must provide this info themselves for #version 150 and up */
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_INPUT_TYPE_EXT, input);
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
- glProgramParameteriEXT(shader->program, GL_GEOMETRY_VERTICES_OUT_EXT, number);
+ int bindpoint = GPU_uniformbuffer_bindpoint(ubo);
+
+ if (location == -1) {
+ return;
}
+
+ glUniformBlockBinding(shader->program, location, bindpoint);
}
void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
{
- GLenum arbnumber;
int number = GPU_texture_bound_number(tex);
- int bindcode = GPU_texture_opengl_bindcode(tex);
- int target = GPU_texture_target(tex);
- if (number >= GPU_max_textures()) {
- fprintf(stderr, "Not enough texture slots.\n");
+ if (number == -1) {
+ fprintf(stderr, "Texture is not bound.\n");
+ BLI_assert(0);
return;
}
- if (number == -1)
- return;
-
if (location == -1)
return;
- GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
-
- arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
-
- if (number != 0) glActiveTexture(arbnumber);
- if (bindcode != 0)
- glBindTexture(target, bindcode);
- else
- GPU_invalid_tex_bind(target);
glUniform1i(location, number);
- glEnable(target);
- if (number != 0) glActiveTexture(GL_TEXTURE0);
-
- GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
- int index;
-
- GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocation(shader->program, name));
-
- return index;
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *attrib = GPU_shaderinterface_attr(shader->interface, name);
+ return attrib ? attrib->location : -1;
}
-GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
-{
- GPUShader *retval = NULL;
+static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = {
+ [GPU_SHADER_SMOKE] =
+ { datatoc_gpu_shader_smoke_vert_glsl,
+ datatoc_gpu_shader_smoke_frag_glsl },
+ [GPU_SHADER_SMOKE_FIRE] =
+ { datatoc_gpu_shader_smoke_vert_glsl,
+ datatoc_gpu_shader_smoke_frag_glsl },
+ [GPU_SHADER_SMOKE_COBA] =
+ { datatoc_gpu_shader_smoke_vert_glsl,
+ datatoc_gpu_shader_smoke_frag_glsl },
+
+ [GPU_SHADER_TEXT] =
+ { datatoc_gpu_shader_text_vert_glsl,
+ datatoc_gpu_shader_text_frag_glsl,
+ datatoc_gpu_shader_text_geom_glsl },
+ [GPU_SHADER_TEXT_SIMPLE] =
+ { datatoc_gpu_shader_text_simple_vert_glsl,
+ datatoc_gpu_shader_text_frag_glsl,
+ datatoc_gpu_shader_text_simple_geom_glsl },
+ [GPU_SHADER_KEYFRAME_DIAMOND] =
+ { datatoc_gpu_shader_keyframe_diamond_vert_glsl,
+ datatoc_gpu_shader_keyframe_diamond_frag_glsl },
+ [GPU_SHADER_EDGES_FRONT_BACK_PERSP] =
+ { datatoc_gpu_shader_edges_front_back_persp_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl, /* this version is */
+ datatoc_gpu_shader_edges_front_back_persp_geom_glsl }, /* magical but slooow */
+ [GPU_SHADER_EDGES_FRONT_BACK_ORTHO] =
+ { datatoc_gpu_shader_edges_front_back_ortho_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_EDGES_OVERLAY_SIMPLE] =
+ { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_edges_overlay_frag_glsl,
+ datatoc_gpu_shader_edges_overlay_simple_geom_glsl },
+ [GPU_SHADER_EDGES_OVERLAY] =
+ { datatoc_gpu_shader_edges_overlay_vert_glsl,
+ datatoc_gpu_shader_edges_overlay_frag_glsl,
+ datatoc_gpu_shader_edges_overlay_geom_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING] =
+ { datatoc_gpu_shader_3D_normal_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl },
+ /* Use 'USE_FLAT_NORMAL' to make flat shader from smooth */
+ [GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR] =
+ { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR] =
+ { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA] =
+ { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl },
+
+ [GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_mask_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] =
+ { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_DEPTH] =
+ { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_depth_linear_frag_glsl },
+ [GPU_SHADER_3D_IMAGE_DEPTH_COPY] =
+ { datatoc_gpu_shader_3D_image_vert_glsl,
+ datatoc_gpu_shader_image_depth_copy_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_2] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_image_multisample_resolve_frag_glsl },
+
+ [GPU_SHADER_2D_IMAGE_INTERLACE] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_interlace_frag_glsl },
+ [GPU_SHADER_2D_CHECKER] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_checker_frag_glsl },
+
+ [GPU_SHADER_2D_DIAG_STRIPES] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_diag_stripes_frag_glsl },
+
+ [GPU_SHADER_2D_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_2D_FLAT_COLOR] =
+ { datatoc_gpu_shader_2D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_2D_SMOOTH_COLOR] =
+ { datatoc_gpu_shader_2D_smooth_color_vert_glsl,
+ datatoc_gpu_shader_2D_smooth_color_frag_glsl },
+ [GPU_SHADER_2D_SMOOTH_COLOR_DITHER] =
+ { datatoc_gpu_shader_2D_smooth_color_vert_glsl,
+ datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_linear_frag_glsl },
+ [GPU_SHADER_2D_IMAGE] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_COLOR] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_DESATURATE_COLOR] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_desaturate_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_ALPHA_COLOR] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_alpha_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] =
+ { datatoc_gpu_shader_2D_image_vert_glsl,
+ datatoc_gpu_shader_image_shuffle_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_RECT_COLOR] =
+ { datatoc_gpu_shader_2D_image_rect_vert_glsl,
+ datatoc_gpu_shader_image_color_frag_glsl },
+ [GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR] =
+ { datatoc_gpu_shader_2D_image_multi_rect_vert_glsl,
+ datatoc_gpu_shader_image_varying_color_frag_glsl },
+
+ [GPU_SHADER_3D_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR_U32] =
+ { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_FLAT_COLOR] =
+ { datatoc_gpu_shader_3D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_3D_FLAT_COLOR_U32] =
+ { datatoc_gpu_shader_3D_flat_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_3D_SMOOTH_COLOR] =
+ { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
+ datatoc_gpu_shader_3D_smooth_color_frag_glsl },
+ [GPU_SHADER_3D_DEPTH_ONLY] =
+ { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_depth_only_frag_glsl },
+ [GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+
+ [GPU_SHADER_3D_GROUNDPOINT] =
+ { datatoc_gpu_shader_3D_groundpoint_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_GROUNDLINE] =
+ { datatoc_gpu_shader_3D_passthrough_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ datatoc_gpu_shader_3D_groundline_geom_glsl },
+
+ [GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl,
+ datatoc_gpu_shader_2D_line_dashed_geom_glsl },
+ [GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_line_dashed_uniform_color_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl,
+ datatoc_gpu_shader_2D_line_dashed_geom_glsl },
+
+ [GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl},
+ [GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] =
+ { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED] =
+ { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+
+ [GPU_SHADER_CAMERA] =
+ { datatoc_gpu_shader_instance_camera_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+ [GPU_SHADER_DISTANCE_LINES] =
+ { datatoc_gpu_shader_instance_distance_line_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl},
+
+ [GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_2D_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR] =
+ { datatoc_gpu_shader_2D_point_varying_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
+ [GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_outline_aa_frag_glsl },
+ [GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR] =
+ { datatoc_gpu_shader_3D_point_fixed_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_3D_point_varying_size_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR] =
+ { datatoc_gpu_shader_3D_point_varying_size_varying_color_vert_glsl,
+ datatoc_gpu_shader_point_varying_color_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_aa_frag_glsl },
+ [GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
+ { datatoc_gpu_shader_3D_point_uniform_size_outline_aa_vert_glsl,
+ datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
+
+ [GPU_SHADER_INSTANCE_UNIFORM_COLOR] =
+ { datatoc_gpu_shader_instance_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE] =
+ { datatoc_gpu_shader_instance_variying_size_variying_id_vert_glsl,
+ datatoc_gpu_shader_flat_id_frag_glsl },
+ [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] =
+ { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE] =
+ { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR] =
+ { datatoc_gpu_shader_instance_edges_variying_color_vert_glsl,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ datatoc_gpu_shader_instance_edges_variying_color_geom_glsl},
+
+ [GPU_SHADER_2D_AREA_EDGES] =
+ { datatoc_gpu_shader_2D_area_borders_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl},
+ [GPU_SHADER_2D_WIDGET_BASE] =
+ { datatoc_gpu_shader_2D_widget_base_vert_glsl,
+ datatoc_gpu_shader_2D_widget_base_frag_glsl},
+ [GPU_SHADER_2D_WIDGET_BASE_INST] =
+ { datatoc_gpu_shader_2D_widget_base_vert_glsl,
+ datatoc_gpu_shader_2D_widget_base_frag_glsl},
+ [GPU_SHADER_2D_WIDGET_SHADOW] =
+ { datatoc_gpu_shader_2D_widget_shadow_vert_glsl,
+ datatoc_gpu_shader_2D_widget_shadow_frag_glsl },
+ [GPU_SHADER_2D_NODELINK] =
+ { datatoc_gpu_shader_2D_nodelink_vert_glsl,
+ datatoc_gpu_shader_2D_nodelink_frag_glsl },
+ [GPU_SHADER_2D_NODELINK_INST] =
+ { datatoc_gpu_shader_2D_nodelink_vert_glsl,
+ datatoc_gpu_shader_2D_nodelink_frag_glsl },
+
+ [GPU_SHADER_GPENCIL_STROKE] =
+ { datatoc_gpu_shader_gpencil_stroke_vert_glsl,
+ datatoc_gpu_shader_gpencil_stroke_frag_glsl,
+ datatoc_gpu_shader_gpencil_stroke_geom_glsl },
+
+ [GPU_SHADER_GPENCIL_FILL] =
+ { datatoc_gpu_shader_gpencil_fill_vert_glsl,
+ datatoc_gpu_shader_gpencil_fill_frag_glsl },
+};
+/* just a few special cases */
+static const char *gpu_shader_get_builtin_shader_defines(
+ GPUBuiltinShader shader)
+{
switch (shader) {
- case GPU_SHADER_VSM_STORE:
- if (!GG.shaders.vsm_store)
- GG.shaders.vsm_store = GPU_shader_create(
- datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.vsm_store;
- break;
- case GPU_SHADER_SEP_GAUSSIAN_BLUR:
- if (!GG.shaders.sep_gaussian_blur)
- GG.shaders.sep_gaussian_blur = GPU_shader_create(
- datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
- datatoc_gpu_shader_sep_gaussian_blur_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.sep_gaussian_blur;
- break;
- case GPU_SHADER_SMOKE:
- if (!GG.shaders.smoke)
- GG.shaders.smoke = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke;
- break;
- case GPU_SHADER_SMOKE_FIRE:
- if (!GG.shaders.smoke_fire)
- GG.shaders.smoke_fire = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke_fire;
- break;
- case GPU_SHADER_SMOKE_COBA:
- if (!GG.shaders.smoke_coba)
- GG.shaders.smoke_coba = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
- NULL, NULL, "#define USE_COBA;\n", 0, 0, 0);
- retval = GG.shaders.smoke_coba;
- break;
- }
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_2:
+ return "#define SAMPLES 2\n";
- if (retval == NULL)
- printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST:
+ return "#define SAMPLES 2\n"
+ "#define USE_DEPTH\n";
- return retval;
-}
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_4:
+ return "#define SAMPLES 4\n";
-#define MAX_DEFINES 100
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST:
+ return "#define SAMPLES 4\n"
+ "#define USE_DEPTH\n";
-GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
-{
- int offset;
- char defines[MAX_DEFINES] = "";
- /* avoid shaders out of range */
- if (effect >= MAX_FX_SHADERS)
- return NULL;
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_8:
+ return "#define SAMPLES 8\n";
- offset = 2 * effect;
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST:
+ return "#define SAMPLES 8\n"
+ "#define USE_DEPTH\n";
- if (persp) {
- offset += 1;
- strcat(defines, "#define PERSP_MATRIX\n");
- }
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_16:
+ return "#define SAMPLES 16\n";
- if (!GG.shaders.fx_shaders[offset]) {
- GPUShader *shader = NULL;
-
- switch (effect) {
- case GPU_SHADER_FX_SSAO:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
- strcat(defines, "#define FIRST_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
- strcat(defines, "#define SECOND_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
- strcat(defines, "#define THIRD_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
- strcat(defines, "#define FOURTH_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
- strcat(defines, "#define FIFTH_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE:
- strcat(defines, "#define FIRST_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO:
- strcat(defines, "#define SECOND_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl,
- defines, GL_POINTS, GL_TRIANGLE_STRIP, 4);
- break;
-
- case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE:
- strcat(defines, "#define THIRD_PASS\n");
- shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
- break;
-
- case GPU_SHADER_FX_DEPTH_RESOLVE:
- shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
- break;
- }
+ case GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST:
+ return "#define SAMPLES 16\n"
+ "#define USE_DEPTH\n";
- GG.shaders.fx_shaders[offset] = shader;
- GPU_fx_shader_init_interface(shader, effect);
- }
+ case GPU_SHADER_2D_WIDGET_BASE_INST:
+ case GPU_SHADER_2D_NODELINK_INST:
+ return "#define USE_INSTANCE\n";
- return GG.shaders.fx_shaders[offset];
-}
+ case GPU_SHADER_SMOKE_COBA:
+ return "#define USE_COBA\n";
+ case GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE:
+ case GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE:
+ return "#define UNIFORM_SCALE\n";
-void GPU_shader_free_builtin_shaders(void)
-{
- int i;
+ case GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS:
+ return "#define AXIS_NAME\n";
- if (GG.shaders.vsm_store) {
- GPU_shader_free(GG.shaders.vsm_store);
- GG.shaders.vsm_store = NULL;
- }
+ case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR:
+ return "#define USE_INSTANCE_COLOR\n";
- if (GG.shaders.sep_gaussian_blur) {
- GPU_shader_free(GG.shaders.sep_gaussian_blur);
- GG.shaders.sep_gaussian_blur = NULL;
- }
+ case GPU_SHADER_3D_FLAT_COLOR_U32:
+ case GPU_SHADER_3D_UNIFORM_COLOR_U32:
+ return "#define USE_COLOR_U32\n";
- if (GG.shaders.smoke) {
- GPU_shader_free(GG.shaders.smoke);
- GG.shaders.smoke = NULL;
- }
+ case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
+ return "#define USE_FLAT_NORMAL\n";
- if (GG.shaders.smoke_fire) {
- GPU_shader_free(GG.shaders.smoke_fire);
- GG.shaders.smoke_fire = NULL;
+ default:
+ return NULL;
}
+}
+
+GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
+{
+ BLI_assert(shader != GPU_NUM_BUILTIN_SHADERS); /* don't be a troll */
+
+ if (builtin_shaders[shader] == NULL) {
+ const char *defines = gpu_shader_get_builtin_shader_defines(shader);
- if (GG.shaders.smoke_coba) {
- GPU_shader_free(GG.shaders.smoke_coba);
- GG.shaders.smoke_coba = NULL;
+ const GPUShaderStages *stages = builtin_shader_stages + shader;
+
+ if (shader == GPU_SHADER_EDGES_FRONT_BACK_PERSP && !GLEW_VERSION_3_2) {
+ /* TODO: remove after switch to core profile (maybe) */
+ static const GPUShaderStages legacy_fancy_edges = {
+ datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl,
+ datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl,
+ };
+ stages = &legacy_fancy_edges;
+ }
+
+ if (shader == GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR && !GLEW_VERSION_3_2) {
+ /* Dashed need geometry shader, which are not supported by legacy OpenGL, fallback to solid lines. */
+ /* TODO: remove after switch to core profile (maybe) */
+ static const GPUShaderStages legacy_dashed_lines = {
+ datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl,
+ datatoc_gpu_shader_2D_line_dashed_frag_glsl,
+ };
+ stages = &legacy_dashed_lines;
+ }
+
+ /* common case */
+ builtin_shaders[shader] = GPU_shader_create(stages->vert, stages->frag, stages->geom, NULL, defines, __func__);
}
- for (i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
- if (GG.shaders.fx_shaders[i]) {
- GPU_shader_free(GG.shaders.fx_shaders[i]);
- GG.shaders.fx_shaders[i] = NULL;
+ return builtin_shaders[shader];
+}
+
+void GPU_shader_get_builtin_shader_code(
+ GPUBuiltinShader shader,
+ const char **r_vert, const char **r_frag,
+ const char **r_geom, const char **r_defines)
+{
+ const GPUShaderStages *stages = builtin_shader_stages + shader;
+ *r_vert = stages->vert;
+ *r_frag = stages->frag;
+ *r_geom = stages->geom;
+ *r_defines = gpu_shader_get_builtin_shader_defines(shader);
+}
+
+#define MAX_DEFINES 100
+
+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;
}
}
}