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_codegen.c')
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c219
1 files changed, 123 insertions, 96 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 113ed8e341c..944011879b5 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -46,7 +46,7 @@
#include "GPU_material.h"
#include "GPU_extensions.h"
-#include "BLI_sys_types.h" // for intptr_t support
+#include "BLI_sys_types.h" /* for intptr_t support */
#include "gpu_codegen.h"
@@ -90,9 +90,11 @@ static const char *GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
/* GLSL code parsing for finding function definitions.
* These are stored in a hash for lookup when creating a material. */
-static GHash *FUNCTION_HASH= NULL;
-/* static char *FUNCTION_PROTOTYPES= NULL;
- * static GPUShader *FUNCTION_LIB= NULL;*/
+static GHash *FUNCTION_HASH = NULL;
+#if 0
+static char *FUNCTION_PROTOTYPES = NULL;
+static GPUShader *FUNCTION_LIB = NULL;
+#endif
static int gpu_str_prefix(const char *str, const char *prefix)
{
@@ -116,8 +118,8 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
if (ELEM(*str, ' ', '(', ')', ',', '\t', '\n', '\r'))
break;
else {
- if (token && len < max-1) {
- *token= *str;
+ if (token && len < max - 1) {
+ *token = *str;
token++;
len++;
}
@@ -126,7 +128,7 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
}
if (token)
- *token= '\0';
+ *token = '\0';
/* skip the next special characters:
* note the missing ')' */
@@ -165,10 +167,10 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
code = gpu_str_skip_token(code, NULL, 0);
/* test for type */
- type= GPU_NONE;
- for (i=1; i<=16; i++) {
+ type = GPU_NONE;
+ for (i = 1; i <= 16; i++) {
if (GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
- type= i;
+ type = i;
break;
}
}
@@ -182,8 +184,8 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
/* add parameter */
code = gpu_str_skip_token(code, NULL, 0);
code = gpu_str_skip_token(code, NULL, 0);
- function->paramqual[function->totparam]= qual;
- function->paramtype[function->totparam]= type;
+ function->paramqual[function->totparam] = qual;
+ function->paramtype[function->totparam] = type;
function->totparam++;
}
else {
@@ -220,7 +222,7 @@ static char *gpu_generate_function_prototyps(GHash *hash)
function = BLI_ghashIterator_getValue(ghi);
BLI_dynstr_appendf(ds, "void %s(", name);
- for (a=0; a<function->totparam; a++) {
+ for (a = 0; a < function->totparam; a++) {
if (function->paramqual[a] == FUNCTION_QUAL_OUT)
BLI_dynstr_append(ds, "out ");
else if (function->paramqual[a] == FUNCTION_QUAL_INOUT)
@@ -232,10 +234,11 @@ static char *gpu_generate_function_prototyps(GHash *hash)
BLI_dynstr_append(ds, "sampler2DShadow");
else
BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]);
-
- //BLI_dynstr_appendf(ds, " param%d", a);
-
- if (a != function->totparam-1)
+# if 0
+ BLI_dynstr_appendf(ds, " param%d", a);
+# endif
+
+ if (a != function->totparam - 1)
BLI_dynstr_append(ds, ", ");
}
BLI_dynstr_append(ds, ");\n");
@@ -267,7 +270,7 @@ void gpu_codegen_init(void)
void gpu_codegen_exit(void)
{
- extern Material defmaterial; // render module abuse...
+ extern Material defmaterial; /* render module abuse... */
if (defmaterial.gpumaterial.first)
GPU_material_free(&defmaterial.gpumaterial);
@@ -284,14 +287,16 @@ void gpu_codegen_exit(void)
glsl_material_library = NULL;
}
- /*if (FUNCTION_PROTOTYPES) {
+#if 0
+ if (FUNCTION_PROTOTYPES) {
MEM_freeN(FUNCTION_PROTOTYPES);
FUNCTION_PROTOTYPES = NULL;
- }*/
- /*if (FUNCTION_LIB) {
+ }
+ if (FUNCTION_LIB) {
GPU_shader_free(FUNCTION_LIB);
FUNCTION_LIB = NULL;
- }*/
+ }
+#endif
}
/* GLSL code generation */
@@ -306,18 +311,16 @@ static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *t
BLI_dynstr_append(ds, name);
}
else if (to == GPU_FLOAT) {
- if (from == GPU_VEC4)
- BLI_dynstr_appendf(ds, "dot(%s.rgb, vec3(0.35, 0.45, 0.2))", name);
- else if (from == GPU_VEC3)
- BLI_dynstr_appendf(ds, "dot(%s, vec3(0.33))", name);
+ if (from == GPU_VEC4 || from == GPU_VEC3)
+ BLI_dynstr_appendf(ds, "(%s.r + %s.g + %s.b) / 3.0", name, name, name);
else if (from == GPU_VEC2)
BLI_dynstr_appendf(ds, "%s.r", name);
}
else if (to == GPU_VEC2) {
if (from == GPU_VEC4)
- BLI_dynstr_appendf(ds, "vec2(dot(%s.rgb, vec3(0.35, 0.45, 0.2)), %s.a)", name, name);
+ BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, %s.a)", name, name, name, name);
else if (from == GPU_VEC3)
- BLI_dynstr_appendf(ds, "vec2(dot(%s.rgb, vec3(0.33)), 1.0)", name);
+ BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, 1.0)", name, name, name);
else if (from == GPU_FLOAT)
BLI_dynstr_appendf(ds, "vec2(%s, 1.0)", name);
}
@@ -345,9 +348,9 @@ static void codegen_print_datatype(DynStr *ds, const GPUType type, float *data)
BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]);
- for (i=0; i<type; i++) {
+ for (i = 0; i < type; i++) {
BLI_dynstr_appendf(ds, "%f", data[i]);
- if (i == type-1)
+ if (i == type - 1)
BLI_dynstr_append(ds, ")");
else
BLI_dynstr_append(ds, ", ");
@@ -412,11 +415,11 @@ static void codegen_set_unique_ids(ListBase *nodes)
GPUOutput *output;
int id = 1, texid = 0;
- bindhash= BLI_ghash_ptr_new("codegen_set_unique_ids1 gh");
- definehash= BLI_ghash_ptr_new("codegen_set_unique_ids2 gh");
+ bindhash = BLI_ghash_ptr_new("codegen_set_unique_ids1 gh");
+ definehash = BLI_ghash_ptr_new("codegen_set_unique_ids2 gh");
- for (node=nodes->first; node; node=node->next) {
- for (input=node->inputs.first; input; input=input->next) {
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
/* set id for unique names of uniform variables */
input->id = id++;
input->bindtex = false;
@@ -463,7 +466,7 @@ static void codegen_set_unique_ids(ListBase *nodes)
}
}
- for (output=node->outputs.first; output; output=output->next)
+ for (output = node->outputs.first; output; output = output->next)
/* set id for unique names of tmp variables storing output */
output->id = id++;
}
@@ -480,8 +483,8 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
int builtins = 0;
/* print uniforms */
- for (node=nodes->first; node; node=node->next) {
- for (input=node->inputs.first; input; input=input->next) {
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) {
/* create exactly one sampler for each texture */
if (codegen_input_has_texture(input) && input->bindtex)
@@ -537,9 +540,9 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
GPUInput *input;
GPUOutput *output;
- for (node=nodes->first; node; node=node->next) {
+ for (node = nodes->first; node; node = node->next) {
/* load pixels from textures */
- for (input=node->inputs.first; input; input=input->next) {
+ for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_TEX_PIXEL) {
if (codegen_input_has_texture(input) && input->definetex) {
BLI_dynstr_appendf(ds, "\tvec4 tex%d = texture2D(", input->texid);
@@ -550,7 +553,7 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
}
/* declare temporary variables for node output storage */
- for (output=node->outputs.first; output; output=output->next)
+ for (output = node->outputs.first; output; output = output->next)
BLI_dynstr_appendf(ds, "\t%s tmp%d;\n",
GPU_DATATYPE_STR[output->type], output->id);
}
@@ -564,10 +567,10 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
GPUInput *input;
GPUOutput *output;
- for (node=nodes->first; node; node=node->next) {
+ for (node = nodes->first; node; node = node->next) {
BLI_dynstr_appendf(ds, "\t%s(", node->name);
- for (input=node->inputs.first; input; input=input->next) {
+ for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_TEX) {
BLI_dynstr_appendf(ds, "samp%d", input->texid);
if (input->link)
@@ -602,7 +605,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ", ");
}
- for (output=node->outputs.first; output; output=output->next) {
+ for (output = node->outputs.first; output; output = output->next) {
BLI_dynstr_appendf(ds, "tmp%d", output->id);
if (output->next)
BLI_dynstr_append(ds, ", ");
@@ -622,13 +625,17 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
char *code;
int builtins;
- /*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/
+#if 0
+ BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
+#endif
codegen_set_unique_ids(nodes);
builtins = codegen_print_uniforms_functions(ds, nodes);
- //if (G.debug & G_DEBUG)
- // BLI_dynstr_appendf(ds, "/* %s */\n", name);
+#if 0
+ if (G.debug & G_DEBUG)
+ BLI_dynstr_appendf(ds, "/* %s */\n", name);
+#endif
BLI_dynstr_append(ds, "void main(void)\n");
BLI_dynstr_append(ds, "{\n");
@@ -645,7 +652,9 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
- //if (G.debug & G_DEBUG) printf("%s\n", code);
+#if 0
+ if (G.debug & G_DEBUG) printf("%s\n", code);
+#endif
return code;
}
@@ -658,8 +667,8 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
char *code;
char *vertcode;
- for (node=nodes->first; node; node=node->next) {
- for (input=node->inputs.first; input; input=input->next) {
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
BLI_dynstr_appendf(ds, "attribute %s att%d;\n",
GPU_DATATYPE_STR[input->type], input->attribid);
@@ -685,8 +694,8 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
BLI_dynstr_append(ds, vertcode);
- for (node=nodes->first; node; node=node->next)
- for (input=node->inputs.first; input; input=input->next)
+ for (node = nodes->first; node; node = node->next)
+ for (input = node->inputs.first; input; input = input->next)
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
if (input->attribtype == CD_TANGENT) { /* silly exception */
BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n", input->attribid, input->attribid);
@@ -714,7 +723,9 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
BLI_dynstr_free(ds);
- //if (G.debug & G_DEBUG) printf("%s\n", code);
+#if 0
+ if (G.debug & G_DEBUG) printf("%s\n", code);
+#endif
return code;
}
@@ -760,9 +771,9 @@ static void gpu_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
GPU_shader_bind(shader);
- for (node=nodes->first; node; node=node->next) {
+ for (node = nodes->first; node; node = node->next) {
z = 0;
- for (input=node->inputs.first; input; input=next, z++) {
+ for (input = node->inputs.first; input; input = next, z++) {
next = input->next;
/* attributes don't need to be bound, they already have
@@ -815,7 +826,7 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
GPU_shader_bind(shader);
/* now bind the textures */
- for (input=inputs->first; input; input=input->next) {
+ for (input = inputs->first; input; input = input->next) {
if (input->ima)
input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
else if (input->prv)
@@ -839,10 +850,19 @@ void GPU_pass_update_uniforms(GPUPass *pass)
return;
/* pass dynamic inputs to opengl, others were removed */
- for (input=inputs->first; input; input=input->next)
- if (!(input->ima || input->tex || input->prv))
- GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
- input->dynamicvec);
+ for (input = inputs->first; input; input = input->next) {
+ if (!(input->ima || input->tex || input->prv)) {
+ if (input->dynamictype == GPU_DYNAMIC_MAT_HARD) {
+ // The hardness is actually a short pointer, so we convert it here
+ float val = (float)(*(short*)input->dynamicvec);
+ GPU_shader_uniform_vector(shader, input->shaderloc, 1, 1, &val);
+ }
+ else {
+ GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
+ input->dynamicvec);
+ }
+ }
+ }
}
void GPU_pass_unbind(GPUPass *pass)
@@ -854,7 +874,7 @@ void GPU_pass_unbind(GPUPass *pass)
if (!shader)
return;
- for (input=inputs->first; input; input=input->next) {
+ for (input = inputs->first; input; input = input->next) {
if (input->tex && input->bindtex)
GPU_texture_unbind(input->tex);
@@ -896,7 +916,7 @@ static GPUNode *GPU_node_begin(const char *name)
{
GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
- node->name= name;
+ node->name = name;
return node;
}
@@ -910,8 +930,11 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
if (link->output) {
outnode = link->output->node;
name = outnode->name;
+ input = outnode->inputs.first;
- if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) {
+ if ((STREQ(name, "set_value") || STREQ(name, "set_rgb")) &&
+ (input->type == type))
+ {
input = MEM_dupallocN(outnode->inputs.first);
input->type = type;
if (input->link)
@@ -965,7 +988,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
input->source = GPU_SOURCE_TEX;
input->textype = type;
- //input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
+#if 0
+ input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
+#endif
input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, GPU_HDR_NONE, NULL);
input->textarget = GL_TEXTURE_2D;
@@ -1004,9 +1029,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
memcpy(input->vec, link->ptr1, type*sizeof(float));
if (link->dynamic) {
- input->dynamicvec= link->ptr1;
- input->dynamictype= link->dynamictype;
- input->dynamicdata= link->ptr2;
+ input->dynamicvec = link->ptr1;
+ input->dynamictype = link->dynamictype;
+ input->dynamicdata = link->ptr2;
}
MEM_freeN(link);
}
@@ -1040,7 +1065,7 @@ static void gpu_node_output(GPUNode *node, const GPUType type, GPUNodeLink **lin
output->link->type = type;
output->link->output = output;
- /* note: the caller owns the reference to the linkfer, GPUOutput
+ /* note: the caller owns the reference to the link, GPUOutput
* merely points to it, and if the node is destroyed it will
* set that pointer to NULL */
}
@@ -1052,7 +1077,7 @@ static void gpu_inputs_free(ListBase *inputs)
{
GPUInput *input;
- for (input=inputs->first; input; input=input->next) {
+ for (input = inputs->first; input; input = input->next) {
if (input->link)
gpu_node_link_free(input->link);
else if (input->tex && !input->dynamictex)
@@ -1068,7 +1093,7 @@ static void gpu_node_free(GPUNode *node)
gpu_inputs_free(&node->inputs);
- for (output=node->outputs.first; output; output=output->next)
+ for (output = node->outputs.first; output; output = output->next)
if (output->link) {
output->link->output = NULL;
gpu_node_link_free(output->link);
@@ -1100,10 +1125,10 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a
memset(attribs, 0, sizeof(*attribs));
- for (node=nodes->first; node; node=node->next) {
- for (input=node->inputs.first; input; input=input->next) {
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_ATTRIB) {
- for (a=0; a<attribs->totlayer; a++) {
+ for (a = 0; a < attribs->totlayer; a++) {
if (attribs->layer[a].type == input->attribtype &&
STREQ(attribs->layer[a].name, input->attribname))
{
@@ -1135,10 +1160,10 @@ static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
GPUNode *node;
GPUInput *input;
- *builtin= 0;
+ *builtin = 0;
- for (node=nodes->first; node; node=node->next)
- for (input=node->inputs.first; input; input=input->next)
+ for (node = nodes->first; node; node = node->next)
+ for (input = node->inputs.first; input; input = input->next)
if (input->source == GPU_SOURCE_BUILTIN)
*builtin |= input->builtin;
}
@@ -1149,8 +1174,8 @@ GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
{
GPUNodeLink *link = GPU_node_link_create();
- link->attribtype= type;
- link->attribname= name;
+ link->attribtype = type;
+ link->attribname = name;
return link;
}
@@ -1159,8 +1184,8 @@ GPUNodeLink *GPU_uniform(float *num)
{
GPUNodeLink *link = GPU_node_link_create();
- link->ptr1= num;
- link->ptr2= NULL;
+ link->ptr1 = num;
+ link->ptr2 = NULL;
return link;
}
@@ -1169,9 +1194,9 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *d
{
GPUNodeLink *link = GPU_node_link_create();
- link->ptr1= num;
- link->ptr2= data;
- link->dynamic= true;
+ link->ptr1 = num;
+ link->ptr2 = data;
+ link->dynamic = true;
link->dynamictype = dynamictype;
@@ -1194,8 +1219,8 @@ GPUNodeLink *GPU_image_preview(PreviewImage *prv)
{
GPUNodeLink *link = GPU_node_link_create();
- link->image= GPU_NODE_LINK_IMAGE_PREVIEW;
- link->ptr1= prv;
+ link->image = GPU_NODE_LINK_IMAGE_PREVIEW;
+ link->ptr1 = prv;
return link;
}
@@ -1207,7 +1232,7 @@ GPUNodeLink *GPU_texture(int size, float *pixels)
link->texture = true;
link->texturesize = size;
- link->ptr1= pixels;
+ link->ptr1 = pixels;
return link;
}
@@ -1259,13 +1284,13 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
node = GPU_node_begin(name);
va_start(params, name);
- for (i=0; i<function->totparam; i++) {
+ for (i = 0; i<function->totparam; i++) {
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
- linkptr= va_arg(params, GPUNodeLink**);
+ linkptr = va_arg(params, GPUNodeLink**);
gpu_node_output(node, function->paramtype[i], linkptr);
}
else {
- link= va_arg(params, GPUNodeLink*);
+ link = va_arg(params, GPUNodeLink*);
gpu_node_input_link(node, link, function->paramtype[i]);
}
}
@@ -1309,10 +1334,10 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
}
va_start(params, out);
- for (i=0; i<function->totparam; i++) {
+ for (i = 0; i<function->totparam; i++) {
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
if (totout == 0) {
- linkptr= va_arg(params, GPUNodeLink**);
+ linkptr = va_arg(params, GPUNodeLink**);
gpu_node_output(node, function->paramtype[i], linkptr);
}
else
@@ -1320,7 +1345,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
}
else {
if (totin == 0) {
- link= va_arg(params, GPUNodeLink*);
+ link = va_arg(params, GPUNodeLink*);
if (link->socket)
gpu_node_input_socket(node, link->socket);
else
@@ -1373,7 +1398,7 @@ static void gpu_nodes_tag(GPUNodeLink *link)
return;
node->tag = true;
- for (input=node->inputs.first; input; input=input->next)
+ for (input = node->inputs.first; input; input = input->next)
if (input->link)
gpu_nodes_tag(input->link);
}
@@ -1382,12 +1407,12 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
{
GPUNode *node, *next;
- for (node=nodes->first; node; node=node->next)
+ for (node = nodes->first; node; node = node->next)
node->tag = false;
gpu_nodes_tag(outlink);
- for (node=nodes->first; node; node=next) {
+ for (node = nodes->first; node; node = next) {
next = node->next;
if (!node->tag) {
@@ -1405,10 +1430,12 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink,
GPUPass *pass;
char *vertexcode, *fragmentcode;
- /*if (!FUNCTION_LIB) {
+#if 0
+ if (!FUNCTION_LIB) {
GPU_nodes_free(nodes);
return NULL;
- }*/
+ }
+#endif
/* prune unused nodes */
gpu_nodes_prune(nodes, outlink);