Merge branch 'blender2.7'
[blender.git] / source / blender / gpu / intern / gpu_codegen.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Brecht Van Lommel.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/gpu/intern/gpu_codegen.h
29  *  \ingroup gpu
30  */
31
32
33 #ifndef __GPU_CODEGEN_H__
34 #define __GPU_CODEGEN_H__
35
36 #include "DNA_customdata_types.h"
37 #include "DNA_listBase.h"
38 #include "GPU_material.h"
39 #include "GPU_glew.h"
40
41 struct ListBase;
42 struct GPUShader;
43 struct GPUOutput;
44 struct GPUNode;
45 struct GPUVertexAttribs;
46 struct PreviewImage;
47
48 /* Pass Generation
49  * - Takes a list of nodes and a desired output, and makes a pass. This
50  *   will take ownership of the nodes and free them early if unused or
51  *   at the end if used.
52  */
53
54 typedef enum GPUDataSource {
55         GPU_SOURCE_OUTPUT,
56         GPU_SOURCE_CONSTANT,
57         GPU_SOURCE_UNIFORM,
58         GPU_SOURCE_ATTRIB,
59         GPU_SOURCE_BUILTIN,
60         GPU_SOURCE_STRUCT,
61         GPU_SOURCE_TEX,
62 } GPUDataSource;
63
64 typedef enum {
65         GPU_NODE_LINK_NONE = 0,
66         GPU_NODE_LINK_ATTRIB,
67         GPU_NODE_LINK_BUILTIN,
68         GPU_NODE_LINK_COLORBAND,
69         GPU_NODE_LINK_CONSTANT,
70         GPU_NODE_LINK_IMAGE_BLENDER,
71         GPU_NODE_LINK_OUTPUT,
72         GPU_NODE_LINK_UNIFORM,
73 } GPUNodeLinkType;
74
75 struct GPUNode {
76         struct GPUNode *next, *prev;
77
78         const char *name;
79
80         /* Internal flag to mark nodes during pruning */
81         bool tag;
82
83         ListBase inputs;
84         ListBase outputs;
85 };
86
87 struct GPUNodeLink {
88         GPUNodeStack *socket;
89
90         GPUNodeLinkType link_type;
91         int users; /* Refcount */
92
93         union {
94                 /* GPU_NODE_LINK_CONSTANT | GPU_NODE_LINK_UNIFORM */
95                 float *data;
96                 /* GPU_NODE_LINK_BUILTIN */
97                 GPUBuiltin builtin;
98                 /* GPU_NODE_LINK_COLORBAND */
99                 struct GPUTexture **coba;
100                 /* GPU_NODE_LINK_OUTPUT */
101                 struct GPUOutput *output;
102                 /* GPU_NODE_LINK_ATTRIB */
103                 struct {
104                         const char *attribname;
105                         CustomDataType attribtype;
106                 };
107                 /* GPU_NODE_LINK_IMAGE_BLENDER */
108                 struct {
109                         struct Image *ima;
110                         struct ImageUser *iuser;
111                         bool image_isdata;
112                 };
113         };
114 };
115
116 typedef struct GPUOutput {
117         struct GPUOutput *next, *prev;
118
119         GPUNode *node;
120         GPUType type;      /* data type = length of vector/matrix */
121         GPUNodeLink *link; /* output link */
122         int id;            /* unique id as created by code generator */
123 } GPUOutput;
124
125 typedef struct GPUInput {
126         struct GPUInput *next, *prev;
127
128         GPUNode *node;
129         GPUType type;                /* datatype */
130         GPUNodeLink *link;
131         int id;                      /* unique id as created by code generator */
132
133         GPUDataSource source;        /* data source */
134
135         int shaderloc;               /* id from opengl */
136         char shadername[32];         /* name in shader */
137
138         /* Content based on GPUDataSource */
139         union {
140                 /* GPU_SOURCE_CONSTANT | GPU_SOURCE_UNIFORM */
141                 float vec[16];                   /* vector data */
142                 /* GPU_SOURCE_BUILTIN */
143                 GPUBuiltin builtin;              /* builtin uniform */
144                 /* GPU_SOURCE_TEX */
145                 struct {
146                         struct GPUTexture **coba;    /* input texture, only set at runtime */
147                         struct Image *ima;           /* image */
148                         struct ImageUser *iuser;     /* image user */
149                         bool image_isdata;           /* image does not contain color data */
150                         bool bindtex;                /* input is responsible for binding the texture? */
151                         int texid;                   /* number for multitexture, starting from zero */
152                         GPUType textype;             /* texture type (2D, 1D Array ...) */
153                 };
154                 /* GPU_SOURCE_ATTRIB */
155                 struct {
156                         char attribname[MAX_CUSTOMDATA_LAYER_NAME]; /* attribute name */
157                         int attribid;                /* id for vertex attributes */
158                         bool attribfirst;            /* this is the first one that is bound */
159                         CustomDataType attribtype;   /* attribute type */
160                 };
161         };
162 } GPUInput;
163
164 struct GPUPass {
165         struct GPUPass *next;
166
167         struct GPUShader *shader;
168         char *fragmentcode;
169         char *geometrycode;
170         char *vertexcode;
171         char *defines;
172         uint refcount;               /* Orphaned GPUPasses gets freed by the garbage collector. */
173         uint32_t hash;               /* Identity hash generated from all GLSL code. */
174         bool compiled;               /* Did we already tried to compile the attached GPUShader. */
175 };
176
177 typedef struct GPUPass GPUPass;
178
179 GPUPass *GPU_generate_pass(
180         GPUMaterial *material,
181         GPUNodeLink *frag_outlink, struct GPUVertexAttribs *attribs,
182         ListBase *nodes, int *builtins,
183         const char *vert_code, const char *geom_code,
184         const char *frag_lib, const char *defines);
185
186 struct GPUShader *GPU_pass_shader_get(GPUPass *pass);
187
188 void GPU_nodes_extract_dynamic_inputs(struct GPUShader *shader, ListBase *inputs, ListBase *nodes);
189 void GPU_nodes_get_vertex_attributes(ListBase *nodes, struct GPUVertexAttribs *attribs);
190 void GPU_nodes_prune(ListBase *nodes, struct GPUNodeLink *outlink);
191
192 void GPU_pass_compile(GPUPass *pass, const char *shname);
193 void GPU_pass_release(GPUPass *pass);
194 void GPU_pass_free_nodes(ListBase *nodes);
195
196 void GPU_inputs_free(ListBase *inputs);
197
198 void gpu_codegen_init(void);
199 void gpu_codegen_exit(void);
200
201 /* Material calls */
202
203 const char *GPU_builtin_name(GPUBuiltin builtin);
204 void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
205 struct GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row);
206
207 #endif