1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup gpu
22  */
23 
24 #pragma once
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 struct GPUTexture;
31 struct GPUUniformBuf;
32 struct GPUVertBuf;
33 
34 /** Opaque type hidding blender::gpu::Shader */
35 typedef struct GPUShader GPUShader;
36 
37 typedef enum eGPUShaderTFBType {
38   GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */
39   GPU_SHADER_TFB_POINTS = 1,
40   GPU_SHADER_TFB_LINES = 2,
41   GPU_SHADER_TFB_TRIANGLES = 3,
42 } eGPUShaderTFBType;
43 
44 GPUShader *GPU_shader_create(const char *vertcode,
45                              const char *fragcode,
46                              const char *geomcode,
47                              const char *libcode,
48                              const char *defines,
49                              const char *shname);
50 GPUShader *GPU_shader_create_from_python(const char *vertcode,
51                                          const char *fragcode,
52                                          const char *geomcode,
53                                          const char *libcode,
54                                          const char *defines);
55 GPUShader *GPU_shader_create_ex(const char *vertcode,
56                                 const char *fragcode,
57                                 const char *geomcode,
58                                 const char *libcode,
59                                 const char *defines,
60                                 const eGPUShaderTFBType tf_type,
61                                 const char **tf_names,
62                                 const int tf_count,
63                                 const char *shname);
64 
65 struct GPU_ShaderCreateFromArray_Params {
66   const char **vert, **geom, **frag, **defs;
67 };
68 struct GPUShader *GPU_shader_create_from_arrays_impl(
69     const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line);
70 
71 #define GPU_shader_create_from_arrays(...) \
72   GPU_shader_create_from_arrays_impl( \
73       &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, __func__, __LINE__)
74 
75 #define GPU_shader_create_from_arrays_named(name, ...) \
76   GPU_shader_create_from_arrays_impl( \
77       &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, name, 0)
78 
79 void GPU_shader_free(GPUShader *shader);
80 
81 void GPU_shader_bind(GPUShader *shader);
82 void GPU_shader_unbind(void);
83 
84 /* Returns true if transform feedback was successfully enabled. */
85 bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf);
86 void GPU_shader_transform_feedback_disable(GPUShader *shader);
87 
88 int GPU_shader_get_program(GPUShader *shader);
89 
90 typedef enum {
91   GPU_UNIFORM_MODEL = 0,      /* mat4 ModelMatrix */
92   GPU_UNIFORM_VIEW,           /* mat4 ViewMatrix */
93   GPU_UNIFORM_MODELVIEW,      /* mat4 ModelViewMatrix */
94   GPU_UNIFORM_PROJECTION,     /* mat4 ProjectionMatrix */
95   GPU_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */
96   GPU_UNIFORM_MVP,            /* mat4 ModelViewProjectionMatrix */
97 
98   GPU_UNIFORM_MODEL_INV,          /* mat4 ModelMatrixInverse */
99   GPU_UNIFORM_VIEW_INV,           /* mat4 ViewMatrixInverse */
100   GPU_UNIFORM_MODELVIEW_INV,      /* mat4 ModelViewMatrixInverse */
101   GPU_UNIFORM_PROJECTION_INV,     /* mat4 ProjectionMatrixInverse */
102   GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */
103 
104   GPU_UNIFORM_NORMAL,     /* mat3 NormalMatrix */
105   GPU_UNIFORM_ORCO,       /* vec4 OrcoTexCoFactors[] */
106   GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */
107 
108   GPU_UNIFORM_COLOR,          /* vec4 color */
109   GPU_UNIFORM_BASE_INSTANCE,  /* int baseInstance */
110   GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */
111   GPU_UNIFORM_RESOURCE_ID,    /* int resourceId */
112   GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */
113 
114   GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */
115 } GPUUniformBuiltin;
116 
117 typedef enum {
118   GPU_UNIFORM_BLOCK_VIEW = 0, /* viewBlock */
119   GPU_UNIFORM_BLOCK_MODEL,    /* modelBlock */
120   GPU_UNIFORM_BLOCK_INFO,     /* infoBlock */
121 
122   GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */
123 } GPUUniformBlockBuiltin;
124 
125 void GPU_shader_set_srgb_uniform(GPUShader *shader);
126 
127 int GPU_shader_get_uniform(GPUShader *shader, const char *name);
128 int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
129 int GPU_shader_get_builtin_block(GPUShader *shader, int builtin);
130 int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
131 
132 int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name);
133 int GPU_shader_get_texture_binding(GPUShader *shader, const char *name);
134 
135 void GPU_shader_uniform_vector(
136     GPUShader *shader, int location, int length, int arraysize, const float *value);
137 void GPU_shader_uniform_vector_int(
138     GPUShader *shader, int location, int length, int arraysize, const int *value);
139 
140 void GPU_shader_uniform_float(GPUShader *shader, int location, float value);
141 void GPU_shader_uniform_int(GPUShader *shader, int location, int value);
142 
143 void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value);
144 void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value);
145 void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value);
146 void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y);
147 void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z);
148 void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w);
149 void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]);
150 void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]);
151 void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]);
152 void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]);
153 void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]);
154 void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]);
155 
156 int GPU_shader_get_attribute(GPUShader *shader, const char *name);
157 
158 void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear);
159 
160 /* Builtin/Non-generated shaders */
161 typedef enum eGPUBuiltinShader {
162   /* specialized drawing */
163   GPU_SHADER_TEXT,
164   GPU_SHADER_KEYFRAME_DIAMOND,
165   GPU_SHADER_SIMPLE_LIGHTING,
166   /* for simple 2D drawing */
167   /**
168    * Take a single color for all the vertices and a 2D position for each vertex.
169    *
170    * \param color: uniform vec4
171    * \param pos: in vec2
172    */
173   GPU_SHADER_2D_UNIFORM_COLOR,
174   /**
175    * Take a 2D position and color for each vertex without color interpolation.
176    *
177    * \param color: in vec4
178    * \param pos: in vec2
179    */
180   GPU_SHADER_2D_FLAT_COLOR,
181   /**
182    * Take a 2D position and color for each vertex with linear interpolation in window space.
183    *
184    * \param color: in vec4
185    * \param pos: in vec2
186    */
187   GPU_SHADER_2D_SMOOTH_COLOR,
188   GPU_SHADER_2D_IMAGE,
189   GPU_SHADER_2D_IMAGE_COLOR,
190   GPU_SHADER_2D_IMAGE_DESATURATE_COLOR,
191   GPU_SHADER_2D_IMAGE_RECT_COLOR,
192   GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR,
193   GPU_SHADER_2D_CHECKER,
194   GPU_SHADER_2D_DIAG_STRIPES,
195   /* for simple 3D drawing */
196   /**
197    * Take a single color for all the vertices and a 3D position for each vertex.
198    *
199    * \param color: uniform vec4
200    * \param pos: in vec3
201    */
202   GPU_SHADER_3D_UNIFORM_COLOR,
203   GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
204   /**
205    * Take a 3D position and color for each vertex without color interpolation.
206    *
207    * \param color: in vec4
208    * \param pos: in vec3
209    */
210   GPU_SHADER_3D_FLAT_COLOR,
211   /**
212    * Take a 3D position and color for each vertex with perspective correct interpolation.
213    *
214    * \param color: in vec4
215    * \param pos: in vec3
216    */
217   GPU_SHADER_3D_SMOOTH_COLOR,
218   /**
219    * Take a single color for all the vertices and a 3D position for each vertex.
220    * Used for drawing wide lines.
221    *
222    * \param color: uniform vec4
223    * \param pos: in vec3
224    */
225   GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR,
226   GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR,
227   /**
228    * Take a 3D position and color for each vertex without color interpolation.
229    * Used for drawing wide lines.
230    *
231    * \param color: in vec4
232    * \param pos: in vec3
233    */
234   GPU_SHADER_3D_POLYLINE_FLAT_COLOR,
235   /**
236    * Take a 3D position and color for each vertex with perspective correct interpolation.
237    * Used for drawing wide lines.
238    *
239    * \param color: in vec4
240    * \param pos: in vec3
241    */
242   GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR,
243   /**
244    * Take a 3D position for each vertex and output only depth.
245    * Used for drawing wide lines.
246    *
247    * \param pos: in vec3
248    */
249   GPU_SHADER_3D_DEPTH_ONLY,
250   /* basic image drawing */
251   GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
252   GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE,
253   GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
254   /* points */
255   /**
256    * Draw round points with a hardcoded size.
257    * Take a single color for all the vertices and a 2D position for each vertex.
258    *
259    * \param color: uniform vec4
260    * \param pos: in vec2
261    */
262   GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR,
263   /**
264    * Draw round points with a constant size.
265    * Take a single color for all the vertices and a 2D position for each vertex.
266    *
267    * \param size: uniform float
268    * \param color: uniform vec4
269    * \param pos: in vec2
270    */
271   GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
272   /**
273    * Draw round points with a constant size and an outline.
274    * Take a single color for all the vertices and a 2D position for each vertex.
275    *
276    * \param size: uniform float
277    * \param outlineWidth: uniform float
278    * \param color: uniform vec4
279    * \param outlineColor: uniform vec4
280    * \param pos: in vec2
281    */
282   GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
283   /**
284    * Draw round points with a constant size and an outline.
285    * Take a 2D position and a color for each vertex.
286    *
287    * \param size: uniform float
288    * \param outlineWidth: uniform float
289    * \param outlineColor: uniform vec4
290    * \param color: in vec4
291    * \param pos: in vec2
292    */
293   GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA,
294   /**
295    * Draw round points with a constant size and an outline.
296    * Take a 2D position and a color for each vertex.
297    *
298    * \param size: in float
299    * \param color: in vec4
300    * \param pos: in vec2
301    */
302   GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR,
303   /**
304    * Draw round points with a hardcoded size.
305    * Take a single color for all the vertices and a 3D position for each vertex.
306    *
307    * \param color: uniform vec4
308    * \param pos: in vec3
309    */
310   GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR,
311   /**
312    * Draw round points with a hardcoded size.
313    * Take a single color for all the vertices and a 3D position for each vertex.
314    *
315    * \param color: uniform vec4
316    * \param pos: in vec3
317    */
318   GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR,
319   /**
320    * Draw round points with a constant size.
321    * Take a single color for all the vertices and a 3D position for each vertex.
322    *
323    * \param size: uniform float
324    * \param color: uniform vec4
325    * \param pos: in vec3
326    */
327   GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA,
328   /**
329    * Draw round points with a constant size and an outline.
330    * Take a single color for all the vertices and a 3D position for each vertex.
331    *
332    * \param size: uniform float
333    * \param outlineWidth: uniform float
334    * \param color: uniform vec4
335    * \param outlineColor: uniform vec4
336    * \param pos: in vec3
337    */
338   GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA,
339   /**
340    * Draw round points with a constant size and an outline.
341    * Take a single color for all the vertices and a 3D position for each vertex.
342    *
343    * \param color: uniform vec4
344    * \param size: in float
345    * \param pos: in vec3
346    */
347   GPU_SHADER_3D_POINT_VARYING_SIZE_UNIFORM_COLOR,
348   /**
349    * Draw round points with a constant size and an outline.
350    * Take a 3D position and a color for each vertex.
351    *
352    * \param size: in float
353    * \param color: in vec4
354    * \param pos: in vec3
355    */
356   GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR,
357   /* lines */
358   GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR,
359   GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR,
360   /* instance */
361   GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */
362   /* grease pencil drawing */
363   GPU_SHADER_GPENCIL_STROKE,
364   GPU_SHADER_GPENCIL_FILL,
365   /* specialized for widget drawing */
366   GPU_SHADER_2D_AREA_EDGES,
367   GPU_SHADER_2D_WIDGET_BASE,
368   GPU_SHADER_2D_WIDGET_BASE_INST,
369   GPU_SHADER_2D_WIDGET_SHADOW,
370   GPU_SHADER_2D_NODELINK,
371   GPU_SHADER_2D_NODELINK_INST,
372   /* specialized for edituv drawing */
373   GPU_SHADER_2D_UV_UNIFORM_COLOR,
374   GPU_SHADER_2D_UV_VERTS,
375   GPU_SHADER_2D_UV_FACEDOTS,
376   GPU_SHADER_2D_UV_EDGES,
377   GPU_SHADER_2D_UV_EDGES_SMOOTH,
378   GPU_SHADER_2D_UV_FACES,
379   GPU_SHADER_2D_UV_FACES_STRETCH_AREA,
380   GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE,
381 } eGPUBuiltinShader;
382 #define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE + 1)
383 
384 /** Support multiple configurations. */
385 typedef enum eGPUShaderConfig {
386   GPU_SHADER_CFG_DEFAULT = 0,
387   GPU_SHADER_CFG_CLIPPED = 1,
388 } eGPUShaderConfig;
389 #define GPU_SHADER_CFG_LEN (GPU_SHADER_CFG_CLIPPED + 1)
390 
391 typedef struct GPUShaderConfigData {
392   const char *lib;
393   const char *def;
394 } GPUShaderConfigData;
395 /* gpu_shader.c */
396 extern const GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN];
397 
398 GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
399                                                      eGPUShaderConfig sh_cfg);
400 GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader);
401 
402 void GPU_shader_get_builtin_shader_code(eGPUBuiltinShader shader,
403                                         const char **r_vert,
404                                         const char **r_frag,
405                                         const char **r_geom,
406                                         const char **r_defines);
407 
408 void GPU_shader_free_builtin_shaders(void);
409 
410 /* Vertex attributes for shaders */
411 
412 /* Hardware limit is 16. Position attribute is always needed so we reduce to 15.
413  * This makes sure the GPUVertexFormat name buffer does not overflow. */
414 #define GPU_MAX_ATTR 15
415 
416 #ifdef __cplusplus
417 }
418 #endif
419