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:
-rw-r--r--source/blender/draw/intern/draw_manager_data.c38
-rw-r--r--source/blender/gpu/GPU_material.h19
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c411
-rw-r--r--source/blender/gpu/intern/gpu_material.c9
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c178
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h52
-rw-r--r--source/blender/nodes/shader/node_shader_util.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.c2
18 files changed, 377 insertions, 401 deletions
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index fbdabb44b15..43e8e2a4733 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -1203,6 +1203,19 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
return grp;
}
+static void drw_shgroup_material_texture(DRWShadingGroup *grp,
+ GPUMaterialTexture *tex,
+ const char *name,
+ int textarget)
+{
+ GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
+ DRW_shgroup_uniform_texture(grp, name, gputex);
+
+ GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
+ *gputex_ref = gputex;
+ GPU_texture_ref(gputex);
+}
+
static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
struct GPUMaterial *material)
{
@@ -1210,35 +1223,20 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
/* Bind all textures needed by the material. */
for (GPUMaterialTexture *tex = textures.first; tex; tex = tex->next) {
- GPUTexture *gputex;
-
if (tex->ima) {
/* Image */
- GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
-
- int textarget;
- if (tex->type == GPU_TEX2D_ARRAY) {
- textarget = GL_TEXTURE_2D_ARRAY;
- }
- else if (tex->type == GPU_TEX1D_ARRAY) {
- textarget = GL_TEXTURE_1D_ARRAY;
+ if (tex->tiled_mapping_name[0]) {
+ drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D_ARRAY);
+ drw_shgroup_material_texture(grp, tex, tex->tiled_mapping_name, GL_TEXTURE_1D_ARRAY);
}
else {
- textarget = GL_TEXTURE_2D;
+ drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D);
}
- *gputex_ref = gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
-
- GPU_texture_ref(gputex);
}
else if (tex->colorband) {
/* Color Ramp */
- gputex = *tex->colorband;
+ DRW_shgroup_uniform_texture(grp, tex->sampler_name, *tex->colorband);
}
- else {
- continue;
- }
-
- DRW_shgroup_uniform_texture(grp, tex->shadername, gputex);
}
GPUUniformBuffer *ubo = GPU_material_uniform_buffer_get(material);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 800843dd851..37fe30bc96b 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -64,6 +64,7 @@ typedef enum eGPUType {
GPU_VEC4 = 4,
GPU_MAT3 = 9,
GPU_MAT4 = 16,
+ GPU_MAX_CONSTANT_DATA = GPU_MAT4,
/* Values not in GPU_DATATYPE_STR */
GPU_TEX1D_ARRAY = 1001,
@@ -137,10 +138,12 @@ typedef enum eGPUMaterialStatus {
GPU_MAT_SUCCESS,
} eGPUMaterialStatus;
-GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
-GPUNodeLink *GPU_constant(float *num);
-GPUNodeLink *GPU_uniform(float *num);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_constant(const float *num);
+GPUNodeLink *GPU_uniform(const float *num);
+GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name);
+GPUNodeLink *GPU_image(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *layer);
GPUNodeLink *GPU_builtin(eGPUBuiltin builtin);
@@ -212,17 +215,19 @@ typedef struct GPUMaterialAttribute {
struct GPUMaterialAttribute *next, *prev;
int type; /* CustomDataType */
char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ eGPUType gputype;
int id;
+ int users;
} GPUMaterialAttribute;
typedef struct GPUMaterialTexture {
struct GPUMaterialTexture *next, *prev;
- eGPUType type;
struct Image *ima;
struct ImageUser *iuser;
struct GPUTexture **colorband;
- char shadername[32]; /* Name of sampler in GLSL. */
- int id;
+ char sampler_name[32]; /* Name of sampler in GLSL. */
+ char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */
+ int users;
} GPUMaterialTexture;
ListBase GPU_material_attributes(GPUMaterial *material);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 6c14d918816..553ecb65529 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -216,16 +216,6 @@ static void codegen_print_datatype(DynStr *ds, const eGPUType type, float *data)
}
}
-static int codegen_input_has_texture(GPUInput *input)
-{
- if (input->link) {
- return 0;
- }
- else {
- return (input->source == GPU_SOURCE_TEX);
- }
-}
-
static const char *gpu_builtin_name(eGPUBuiltin builtin)
{
if (builtin == GPU_VIEW_MATRIX) {
@@ -299,14 +289,14 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin)
}
}
-static void codegen_set_unique_ids(ListBase *nodes)
+static void codegen_set_unique_ids(GPUNodeGraph *graph)
{
GPUNode *node;
GPUInput *input;
GPUOutput *output;
int id = 1;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->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++;
@@ -322,7 +312,9 @@ static void codegen_set_unique_ids(ListBase *nodes)
/**
* It will create an UBO for GPUMaterial if there is any GPU_DYNAMIC_UBO.
*/
-static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, ListBase *nodes)
+static int codegen_process_uniforms_functions(GPUMaterial *material,
+ DynStr *ds,
+ GPUNodeGraph *graph)
{
GPUNode *node;
GPUInput *input;
@@ -330,27 +322,29 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
int builtins = 0;
ListBase ubo_inputs = {NULL, NULL};
- /* print uniforms */
- for (node = nodes->first; node; node = node->next) {
+ /* Attributes */
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+
+ /* Textures */
+ for (GPUMaterialTexture *tex = graph->textures.first; tex; tex = tex->next) {
+ if (tex->colorband) {
+ BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->sampler_name);
+ }
+ else if (tex->tiled_mapping_name[0]) {
+ BLI_dynstr_appendf(ds, "uniform sampler2DArray %s;\n", tex->sampler_name);
+ BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->tiled_mapping_name);
+ }
+ else {
+ BLI_dynstr_appendf(ds, "uniform sampler2D %s;\n", tex->sampler_name);
+ }
+ }
+
+ /* Print other uniforms */
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_TEX) {
- /* create exactly one sampler for each texture */
- if (codegen_input_has_texture(input) && input->bindtex) {
- const char *type;
- if (input->colorband || input->type == GPU_TEX1D_ARRAY) {
- type = "sampler1DArray";
- }
- else if (input->type == GPU_TEX2D_ARRAY) {
- type = "sampler2DArray";
- }
- else {
- BLI_assert(input->type == GPU_TEX2D);
- type = "sampler2D";
- }
- BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", type, input->texid);
- }
- }
- else if (input->source == GPU_SOURCE_BUILTIN) {
+ if (input->source == GPU_SOURCE_BUILTIN) {
/* only define each builtin uniform/varying once */
if (!(builtins & input->builtin)) {
builtins |= input->builtin;
@@ -385,10 +379,6 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
codegen_print_datatype(ds, input->type, input->vec);
BLI_dynstr_append(ds, ";\n");
}
- else if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- BLI_dynstr_appendf(
- ds, "in %s var%d;\n", gpu_data_type_to_string(input->type), input->attr_id);
- }
}
}
@@ -412,12 +402,12 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
return builtins;
}
-static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
+static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph)
{
GPUNode *node;
GPUOutput *output;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
/* declare temporary variables for node output storage */
for (output = node->outputs.first; output; output = output->next) {
if (output->type == GPU_CLOSURE) {
@@ -432,18 +422,21 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
BLI_dynstr_append(ds, "\n");
}
-static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
+static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput)
{
GPUNode *node;
GPUInput *input;
GPUOutput *output;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
BLI_dynstr_appendf(ds, "\t%s(", node->name);
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_TEX) {
- BLI_dynstr_appendf(ds, "samp%d", input->texid);
+ BLI_dynstr_append(ds, input->texture->sampler_name);
+ }
+ else if (input->source == GPU_SOURCE_TEX_TILED_MAPPING) {
+ BLI_dynstr_append(ds, input->texture->tiled_mapping_name);
}
else if (input->source == GPU_SOURCE_OUTPUT) {
codegen_convert_datatype(
@@ -507,7 +500,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_appendf(ds, "cons%d", input->id);
}
else if (input->source == GPU_SOURCE_ATTR) {
- BLI_dynstr_appendf(ds, "var%d", input->attr_id);
+ BLI_dynstr_appendf(ds, "var%d", input->attr->id);
}
BLI_dynstr_append(ds, ", ");
@@ -527,7 +520,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUOutput *output)
+static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -537,8 +530,8 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO
BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
#endif
- codegen_set_unique_ids(nodes);
- builtins = codegen_process_uniforms_functions(material, ds, nodes);
+ codegen_set_unique_ids(graph);
+ builtins = codegen_process_uniforms_functions(material, ds, graph);
if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) {
BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
@@ -614,8 +607,8 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO
BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
}
- codegen_declare_tmps(ds, nodes);
- codegen_call_functions(ds, nodes, output);
+ codegen_declare_tmps(ds, graph);
+ codegen_call_functions(ds, graph, graph->outlink->output);
BLI_dynstr_append(ds, "}\n");
@@ -666,7 +659,7 @@ static const char *attr_prefix_get(CustomDataType type)
}
}
-static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool use_geom)
+static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
@@ -682,48 +675,44 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
"#define DEFINE_ATTR(type, attr) in type attr\n"
"#endif\n");
- for (node = nodes->first; node; node = node->next) {
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ /* XXX FIXME : see notes in mesh_render_data_create() */
+ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
+ if (attr->type == CD_ORCO) {
+ /* OPTI : orco is computed from local positions, but only if no modifier is present. */
+ BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
+ BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
+ }
+ else if (attr->name[0] == '\0') {
+ BLI_dynstr_appendf(ds,
+ "DEFINE_ATTR(%s, %s);\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr_prefix_get(attr->type));
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, attr_prefix_get(attr->type));
+ }
+ else {
+ char attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
+ GPU_vertformat_safe_attrib_name(attr->name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
+ BLI_dynstr_appendf(ds,
+ "DEFINE_ATTR(%s, %s%s);\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr_prefix_get(attr->type),
+ attr_safe_name);
+ BLI_dynstr_appendf(
+ ds, "#define att%d %s%s\n", attr->id, attr_prefix_get(attr->type), attr_safe_name);
+ }
+ BLI_dynstr_appendf(ds,
+ "out %s var%d%s;\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr->id,
+ use_geom ? "g" : "");
+ }
+
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_BUILTIN) {
builtins |= input->builtin;
}
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- /* XXX FIXME : see notes in mesh_render_data_create() */
- /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
- if (input->attr_type == CD_ORCO) {
- /* OPTI : orco is computed from local positions, but only if no modifier is present. */
- BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
- BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
- }
- else if (input->attr_name[0] == '\0') {
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s);\n",
- gpu_data_type_to_string(input->type),
- attr_prefix_get(input->attr_type));
- BLI_dynstr_appendf(
- ds, "#define att%d %s\n", input->attr_id, attr_prefix_get(input->attr_type));
- }
- else {
- char attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
- GPU_vertformat_safe_attrib_name(
- input->attr_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s%s);\n",
- gpu_data_type_to_string(input->type),
- attr_prefix_get(input->attr_type),
- attr_safe_name);
- BLI_dynstr_appendf(ds,
- "#define att%d %s%s\n",
- input->attr_id,
- attr_prefix_get(input->attr_type),
- attr_safe_name);
- }
- BLI_dynstr_appendf(ds,
- "out %s var%d%s;\n",
- gpu_data_type_to_string(input->type),
- input->attr_id,
- use_geom ? "g" : "");
- }
}
}
@@ -800,30 +789,26 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- if (input->attr_type == CD_TANGENT) {
- /* Not supported by hairs */
- BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", input->attr_id, use_geom ? "g" : "");
- }
- else if (input->attr_type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
- "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
- input->attr_id,
- use_geom ? "g" : "");
- /* TODO: fix ORCO with modifiers. */
- }
- else {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
- input->attr_id,
- use_geom ? "g" : "",
- gpu_data_type_to_string(input->type),
- input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ if (attr->type == CD_TANGENT) {
+ /* Not supported by hairs */
+ BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : "");
+ }
+ else if (attr->type == CD_ORCO) {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
+ "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
+ attr->id,
+ use_geom ? "g" : "");
+ /* TODO: fix ORCO with modifiers. */
+ }
+ else {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
+ attr->id,
+ use_geom ? "g" : "",
+ gpu_data_type_to_string(attr->gputype),
+ attr->id);
}
}
@@ -837,49 +822,43 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- if (input->attr_type == CD_TANGENT) { /* silly exception */
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id);
- BLI_dynstr_appendf(
- ds, "\tvar%d%s.w = att%d.w;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
- /* Normalize only if vector is not null. */
- BLI_dynstr_appendf(ds,
- "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
- input->attr_id,
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id,
- use_geom ? "g" : "");
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id,
- input->attr_id);
- }
- else if (input->attr_type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
- " OrcoTexCoFactors[1].xyz;\n",
- input->attr_id,
- use_geom ? "g" : "");
- /* See mesh_create_loop_orco() for explanation. */
- BLI_dynstr_appendf(ds,
- "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
- input->attr_id,
- use_geom ? "g" : "");
- }
- else {
- BLI_dynstr_appendf(
- ds, "\tvar%d%s = att%d;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ if (attr->type == CD_TANGENT) { /* silly exception */
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id);
+ BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id);
+ /* Normalize only if vector is not null. */
+ BLI_dynstr_appendf(ds,
+ "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
+ attr->id,
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id,
+ use_geom ? "g" : "");
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id,
+ attr->id);
+ }
+ else if (attr->type == CD_ORCO) {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
+ " OrcoTexCoFactors[1].xyz;\n",
+ attr->id,
+ use_geom ? "g" : "");
+ /* See mesh_create_loop_orco() for explanation. */
+ BLI_dynstr_appendf(ds,
+ "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
+ attr->id,
+ use_geom ? "g" : "");
+ }
+ else {
+ BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", attr->id, use_geom ? "g" : "", attr->id);
}
}
BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n");
@@ -899,7 +878,9 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
return code;
}
-static char *code_generate_geometry(ListBase *nodes, const char *geom_code, const char *defines)
+static char *code_generate_geometry(GPUNodeGraph *graph,
+ const char *geom_code,
+ const char *defines)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
@@ -916,20 +897,19 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
BLI_dynstr_append(ds, "#define USE_ATTR\n");
/* Generate varying declarations. */
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_BUILTIN) {
builtins |= input->builtin;
}
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- BLI_dynstr_appendf(
- ds, "in %s var%dg[];\n", gpu_data_type_to_string(input->type), input->attr_id);
- BLI_dynstr_appendf(
- ds, "out %s var%d;\n", gpu_data_type_to_string(input->type), input->attr_id);
- }
}
}
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+
if (builtins & GPU_BARYCENTRIC_TEXCO) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n");
@@ -1032,13 +1012,9 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
BLI_dynstr_append(ds, "#endif\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- /* TODO let shader choose what to do depending on what the attribute is. */
- BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", input->attr_id, input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ /* TODO let shader choose what to do depending on what the attribute is. */
+ BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id);
}
BLI_dynstr_append(ds, "}\n");
@@ -1053,94 +1029,6 @@ GPUShader *GPU_pass_shader_get(GPUPass *pass)
return pass->shader;
}
-/* Requested Attributes */
-
-static ListBase gpu_nodes_requested_attributes(ListBase *nodes)
-{
- ListBase attributes = {NULL};
- int num_attributes = 0;
-
- /* Convert attributes requested by node inputs to list, checking for
- * checking for duplicates and assigning id's starting from zero. */
- for (GPUNode *node = nodes->first; node; node = node->next) {
- for (GPUInput *input = node->inputs.first; input; input = input->next) {
- if (input->source != GPU_SOURCE_ATTR) {
- continue;
- }
-
- GPUMaterialAttribute *attr = attributes.first;
- for (; attr; attr = attr->next) {
- if (attr->type == input->attr_type && STREQ(attr->name, input->attr_name)) {
- break;
- }
- }
-
- /* Add new requested attribute if it's within GPU limits. */
- if (attr == NULL && num_attributes < GPU_MAX_ATTR) {
- attr = MEM_callocN(sizeof(*attr), __func__);
- attr->type = input->attr_type;
- STRNCPY(attr->name, input->attr_name);
- attr->id = num_attributes++;
- BLI_addtail(&attributes, attr);
-
- input->attr_id = attr->id;
- input->attr_first = true;
- }
- else if (attr != NULL) {
- input->attr_id = attr->id;
- }
- }
- }
-
- return attributes;
-}
-
-/* Requested Textures */
-
-static ListBase gpu_nodes_requested_textures(ListBase *nodes)
-{
- ListBase textures = {NULL};
- int num_textures = 0;
-
- /* Convert textures requested by node inputs to list, checking for
- * checking for duplicates and assigning id's starting from zero. */
- for (GPUNode *node = nodes->first; node; node = node->next) {
- for (GPUInput *input = node->inputs.first; input; input = input->next) {
- if (!codegen_input_has_texture(input)) {
- continue;
- }
-
- GPUMaterialTexture *tex = textures.first;
- for (; tex; tex = tex->next) {
- if (tex->ima == input->ima && tex->colorband == input->colorband &&
- tex->type == input->type) {
- break;
- }
- }
-
- if (tex == NULL) {
- tex = MEM_callocN(sizeof(*tex), __func__);
- tex->ima = input->ima;
- tex->iuser = input->iuser;
- tex->colorband = input->colorband;
- tex->id = num_textures++;
- tex->type = input->type;
- BLI_snprintf(tex->shadername, sizeof(tex->shadername), "samp%d", tex->id);
- BLI_addtail(&textures, tex);
-
- input->texid = tex->id;
- input->bindtex = true;
- }
- else {
- input->texid = tex->id;
- input->bindtex = false;
- }
- }
- }
-
- return textures;
-}
-
/* Pass create/free */
static bool gpu_pass_is_valid(GPUPass *pass)
@@ -1160,11 +1048,8 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
* generated VBOs are ready to accept the future shader. */
gpu_node_graph_prune_unused(graph);
- graph->attributes = gpu_nodes_requested_attributes(&graph->nodes);
- graph->textures = gpu_nodes_requested_textures(&graph->nodes);
-
/* generate code */
- char *fragmentgen = code_generate_fragment(material, &graph->nodes, graph->outlink->output);
+ char *fragmentgen = code_generate_fragment(material, graph);
/* Cache lookup: Reuse shaders already compiled */
uint32_t hash = gpu_pass_hash(fragmentgen, defines, &graph->attributes);
@@ -1186,8 +1071,8 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
GSet *used_libraries = gpu_material_used_libraries(material);
char *tmp = gpu_material_library_generate_code(used_libraries, frag_lib);
- char *geometrycode = code_generate_geometry(&graph->nodes, geom_code, defines);
- char *vertexcode = code_generate_vertex(&graph->nodes, vert_code, (geometrycode != NULL));
+ char *geometrycode = code_generate_geometry(graph, geom_code, defines);
+ char *vertexcode = code_generate_vertex(graph, vert_code, (geometrycode != NULL));
char *fragmentcode = BLI_strdupcat(tmp, fragmentgen);
MEM_freeN(fragmentgen);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index d8d3e5a2ff2..b2658839d67 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -207,11 +207,6 @@ GPUPass *GPU_material_get_pass(GPUMaterial *material)
return material->pass;
}
-ListBase *GPU_material_get_inputs(GPUMaterial *material)
-{
- return &material->graph.inputs;
-}
-
/* Return can be NULL if it's a world material. */
Material *GPU_material_get_material(GPUMaterial *material)
{
@@ -579,9 +574,9 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
}
}
-void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
+GPUNodeGraph *gpu_material_node_graph(GPUMaterial *material)
{
- BLI_addtail(&material->graph.nodes, node);
+ return &material->graph;
}
GSet *gpu_material_used_libraries(GPUMaterial *material)
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index b271ac48f75..de35b43109f 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -109,20 +109,20 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
input->link = link;
link->users++;
break;
+ case GPU_NODE_LINK_IMAGE:
+ case GPU_NODE_LINK_IMAGE_TILED:
case GPU_NODE_LINK_COLORBAND:
input->source = GPU_SOURCE_TEX;
- input->colorband = link->colorband;
+ input->texture = link->texture;
break;
- case GPU_NODE_LINK_IMAGE_BLENDER:
- case GPU_NODE_LINK_IMAGE_TILEMAP:
- input->source = GPU_SOURCE_TEX;
- input->ima = link->ima;
- input->iuser = link->iuser;
+ case GPU_NODE_LINK_IMAGE_TILED_MAPPING:
+ input->source = GPU_SOURCE_TEX_TILED_MAPPING;
+ input->texture = link->texture;
break;
case GPU_NODE_LINK_ATTR:
input->source = GPU_SOURCE_ATTR;
- input->attr_type = link->attr_type;
- BLI_strncpy(input->attr_name, link->attr_name, sizeof(input->attr_name));
+ input->attr = link->attr;
+ input->attr->gputype = type;
break;
case GPU_NODE_LINK_CONSTANT:
input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT;
@@ -249,24 +249,97 @@ static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **li
BLI_addtail(&node->outputs, output);
}
-/* Creating Inputs */
+/* Attributes and Textures */
-GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
+static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph,
+ CustomDataType type,
+ const char *name)
{
- GPUNodeLink *link = gpu_node_link_create();
- link->link_type = GPU_NODE_LINK_ATTR;
- link->attr_name = name;
/* Fall back to the UV layer, which matches old behavior. */
if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
- link->attr_type = CD_MTFACE;
+ type = CD_MTFACE;
}
- else {
- link->attr_type = type;
+
+ /* Find existing attribute. */
+ int num_attributes = 0;
+ GPUMaterialAttribute *attr = graph->attributes.first;
+ for (; attr; attr = attr->next) {
+ if (attr->type == type && STREQ(attr->name, name)) {
+ break;
+ }
+ num_attributes++;
+ }
+
+ /* Add new requested attribute if it's within GPU limits. */
+ if (attr == NULL && num_attributes < GPU_MAX_ATTR) {
+ attr = MEM_callocN(sizeof(*attr), __func__);
+ attr->type = type;
+ STRNCPY(attr->name, name);
+ attr->id = num_attributes;
+ BLI_addtail(&graph->attributes, attr);
+ }
+
+ if (attr != NULL) {
+ attr->users++;
+ }
+
+ return attr;
+}
+
+static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
+ Image *ima,
+ ImageUser *iuser,
+ struct GPUTexture **colorband,
+ GPUNodeLinkType link_type)
+{
+ /* Find existing texture. */
+ int num_textures = 0;
+ GPUMaterialTexture *tex = graph->textures.first;
+ for (; tex; tex = tex->next) {
+ if (tex->ima == ima && tex->colorband == colorband) {
+ break;
+ }
+ num_textures++;
}
+
+ /* Add new requested texture. */
+ if (tex == NULL) {
+ tex = MEM_callocN(sizeof(*tex), __func__);
+ tex->ima = ima;
+ tex->iuser = iuser;
+ tex->colorband = colorband;
+ BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
+ if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) {
+ BLI_snprintf(
+ tex->tiled_mapping_name, sizeof(tex->tiled_mapping_name), "tsamp%d", num_textures);
+ }
+ BLI_addtail(&graph->textures, tex);
+ }
+
+ tex->users++;
+
+ return tex;
+}
+
+/* Creating Inputs */
+
+GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name);
+
+ if (attr == NULL) {
+ static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
+ return GPU_constant(zero_data);
+ }
+
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_ATTR;
+ link->attr = attr;
return link;
}
-GPUNodeLink *GPU_constant(float *num)
+GPUNodeLink *GPU_constant(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_CONSTANT;
@@ -274,7 +347,7 @@ GPUNodeLink *GPU_constant(float *num)
return link;
}
-GPUNodeLink *GPU_uniform(float *num)
+GPUNodeLink *GPU_uniform(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_UNIFORM;
@@ -282,21 +355,42 @@ GPUNodeLink *GPU_uniform(float *num)
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser)
+GPUNodeLink *GPU_image(GPUMaterial *mat, Image *ima, ImageUser *iuser)
{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
- link->link_type = GPU_NODE_LINK_IMAGE_BLENDER;
- link->ima = ima;
- link->iuser = iuser;
+ link->link_type = GPU_NODE_LINK_IMAGE;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
+ return link;
+}
+
+GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, Image *ima, ImageUser *iuser)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_TILED;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
+ return link;
+}
+
+GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iuser)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
return link;
}
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
{
+ struct GPUTexture **colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
+ MEM_freeN(pixels);
+
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
- link->colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
- MEM_freeN(pixels);
+ link->texture = gpu_node_graph_add_texture(graph, NULL, NULL, colorband, link->link_type);
return link;
}
@@ -340,7 +434,8 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
}
va_end(params);
- gpu_material_add_node(mat, node);
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ BLI_addtail(&graph->nodes, node);
return true;
}
@@ -415,7 +510,8 @@ bool GPU_stack_link(GPUMaterial *material,
}
va_end(params);
- gpu_material_add_node(material, node);
+ GPUNodeGraph *graph = gpu_material_node_graph(material);
+ BLI_addtail(&graph->nodes, node);
return true;
}
@@ -435,6 +531,13 @@ static void gpu_inputs_free(ListBase *inputs)
GPUInput *input;
for (input = inputs->first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTR) {
+ input->attr->users--;
+ }
+ else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) {
+ input->texture->users--;
+ }
+
if (input->link) {
gpu_node_link_free(input->link);
}
@@ -469,7 +572,6 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
gpu_node_free(node);
}
- gpu_inputs_free(&graph->inputs);
graph->outlink = NULL;
}
@@ -477,8 +579,8 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
void gpu_node_graph_free(GPUNodeGraph *graph)
{
gpu_node_graph_free_nodes(graph);
- BLI_freelistN(&graph->attributes);
BLI_freelistN(&graph->textures);
+ BLI_freelistN(&graph->attributes);
}
/* Prune Unused Nodes */
@@ -507,15 +609,13 @@ static void gpu_nodes_tag(GPUNodeLink *link)
void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
{
- GPUNode *node, *next;
-
- for (node = graph->nodes.first; node; node = node->next) {
+ for (GPUNode *node = graph->nodes.first; node; node = node->next) {
node->tag = false;
}
gpu_nodes_tag(graph->outlink);
- for (node = graph->nodes.first; node; node = next) {
+ for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
next = node->next;
if (!node->tag) {
@@ -523,4 +623,18 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
gpu_node_free(node);
}
}
+
+ for (GPUMaterialAttribute *attr = graph->attributes.first, *next = NULL; attr; attr = next) {
+ next = attr->next;
+ if (attr->users == 0) {
+ BLI_freelinkN(&graph->attributes, attr);
+ }
+ }
+
+ for (GPUMaterialTexture *tex = graph->textures.first, *next = NULL; tex; tex = next) {
+ next = tex->next;
+ if (tex->users == 0) {
+ BLI_freelinkN(&graph->textures, tex);
+ }
+ }
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 2ffde8dba39..9214bd7f1ba 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -19,6 +19,8 @@
/** \file
* \ingroup gpu
+ *
+ * Intermediate node graph for generating GLSL shaders.
*/
#ifndef __GPU_NODE_GRAPH_H__
@@ -45,6 +47,7 @@ typedef enum eGPUDataSource {
GPU_SOURCE_BUILTIN,
GPU_SOURCE_STRUCT,
GPU_SOURCE_TEX,
+ GPU_SOURCE_TEX_TILED_MAPPING,
} eGPUDataSource;
typedef enum {
@@ -53,8 +56,9 @@ typedef enum {
GPU_NODE_LINK_BUILTIN,
GPU_NODE_LINK_COLORBAND,
GPU_NODE_LINK_CONSTANT,
- GPU_NODE_LINK_IMAGE_BLENDER,
- GPU_NODE_LINK_IMAGE_TILEMAP,
+ GPU_NODE_LINK_IMAGE,
+ GPU_NODE_LINK_IMAGE_TILED,
+ GPU_NODE_LINK_IMAGE_TILED_MAPPING,
GPU_NODE_LINK_OUTPUT,
GPU_NODE_LINK_UNIFORM,
} GPUNodeLinkType;
@@ -79,7 +83,7 @@ struct GPUNodeLink {
union {
/* GPU_NODE_LINK_CONSTANT | GPU_NODE_LINK_UNIFORM */
- float *data;
+ const float *data;
/* GPU_NODE_LINK_BUILTIN */
eGPUBuiltin builtin;
/* GPU_NODE_LINK_COLORBAND */
@@ -87,15 +91,9 @@ struct GPUNodeLink {
/* GPU_NODE_LINK_OUTPUT */
struct GPUOutput *output;
/* GPU_NODE_LINK_ATTR */
- struct {
- const char *attr_name;
- CustomDataType attr_type;
- };
- /* GPU_NODE_LINK_IMAGE_BLENDER | GPU_NODE_LINK_IMAGE_TILEMAP */
- struct {
- struct Image *ima;
- struct ImageUser *iuser;
- };
+ struct GPUMaterialAttribute *attr;
+ /* GPU_NODE_LINK_IMAGE_BLENDER */
+ struct GPUMaterialTexture *texture;
};
};
@@ -118,35 +116,16 @@ typedef struct GPUInput {
eGPUDataSource source; /* data source */
- int shaderloc; /* id from opengl */
- char shadername[32]; /* name in shader */
-
/* Content based on eGPUDataSource */
union {
/* GPU_SOURCE_CONSTANT | GPU_SOURCE_UNIFORM */
float vec[16]; /* vector data */
/* GPU_SOURCE_BUILTIN */
eGPUBuiltin builtin; /* builtin uniform */
- /* GPU_SOURCE_TEX */
- struct {
- struct GPUTexture **colorband; /* input texture, only set at runtime */
- struct Image *ima; /* image */
- struct ImageUser *iuser; /* image user */
- bool bindtex; /* input is responsible for binding the texture? */
- int texid; /* number for multitexture, starting from zero */
- eGPUType textype; /* texture type (2D, 1D Array ...) */
- };
+ /* GPU_SOURCE_TEX | GPU_SOURCE_TEX_TILED_MAPPING */
+ struct GPUMaterialTexture *texture;
/* GPU_SOURCE_ATTR */
- struct {
- /** Attribute name. */
- char attr_name[MAX_CUSTOMDATA_LAYER_NAME];
- /** ID for vertex attributes. */
- int attr_id;
- /** This is the first one that is bound. */
- bool attr_first;
- /** Attribute type. */
- CustomDataType attr_type;
- };
+ struct GPUMaterialAttribute *attr;
};
} GPUInput;
@@ -154,8 +133,7 @@ typedef struct GPUNodeGraph {
/* Nodes */
ListBase nodes;
- /* Inputs and output. */
- ListBase inputs;
+ /* Output. */
GPUNodeLink *outlink;
/* Requested attributes and textures. */
@@ -171,7 +149,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph);
/* Material calls */
-void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
+struct GPUNodeGraph *gpu_material_node_graph(struct GPUMaterial *material);
struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
int size,
float *pixels,
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 9615c6f01e0..93d03720058 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -276,7 +276,7 @@ void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink *
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
{
if (!*link) {
- *link = GPU_attribute(CD_ORCO, "");
+ *link = GPU_attribute(mat, CD_ORCO, "");
GPU_link(mat, "generated_texco", GPU_builtin(GPU_VIEW_POSITION), *link, link);
node_shader_gpu_bump_tex_coord(mat, node, link);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c
index ecb8c53c312..757db5fe8b3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.c
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c
@@ -66,7 +66,7 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
GPU_builtin(GPU_VOLUME_TEMPERATURE));
}
else {
- GPUNodeLink *cd_attr = GPU_attribute(CD_AUTO_FROM_NAME, attr->name);
+ GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name);
GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
/* for each output. */
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 6b23fec5f18..b1ee3c4806a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -46,7 +46,8 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
GPUNodeLink *bary_link = (!out[5].hasoutput) ? GPU_constant(val) :
GPU_builtin(GPU_BARYCENTRIC_TEXCO);
/* Opti: don't request orco if not needed. */
- GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) : GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) :
+ GPU_attribute(mat, CD_ORCO, "");
const bool success = GPU_stack_link(mat,
node,
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index 006f15f40a1..0f3ffe51706 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -92,7 +92,7 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
GPU_link(mat,
"node_normal_map",
GPU_builtin(GPU_OBJECT_INFO),
- GPU_attribute(CD_TANGENT, nm->uv_map),
+ GPU_attribute(mat, CD_TANGENT, nm->uv_map),
GPU_builtin(GPU_WORLD_NORMAL),
newnormal,
&newnormal);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index 478b9524737..474db465d87 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -43,10 +43,10 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
if (attr->direction_type == SHD_TANGENT_UVMAP) {
return GPU_stack_link(
- mat, node, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, attr->uv_map));
+ mat, node, "node_tangentmap", in, out, GPU_attribute(mat, CD_TANGENT, attr->uv_map));
}
else {
- GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, "");
if (attr->axis == SHD_TANGENT_AXIS_X) {
GPU_link(mat, "tangent_orco_x", orco, &orco);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 3c1a2280aae..81a5ee31f7d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -47,8 +47,8 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
/* Opti: don't request orco if not needed. */
GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant((float[4]){0.0f, 0.0f, 0.0f, 0.0f}) :
- GPU_attribute(CD_ORCO, "");
- GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
+ GPU_attribute(mat, CD_ORCO, "");
+ GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, "");
GPUNodeLink *viewpos = GPU_builtin(GPU_VIEW_POSITION);
GPUNodeLink *worldnor = GPU_builtin(GPU_WORLD_NORMAL);
GPUNodeLink *texcofacs = GPU_builtin(GPU_CAMERA_TEXCO_FACTORS);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 6c380efe0b2..d2615d76345 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -88,7 +88,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
"node_tex_environment_equirectangular",
in[0].link,
GPU_constant(&clamp_size),
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&in[0].link);
}
else {
@@ -103,7 +103,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_linear_no_mip",
in[0].link,
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&out[0].link,
&outalpha);
break;
@@ -111,13 +111,17 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_nearest",
in[0].link,
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&out[0].link,
&outalpha);
break;
default:
- GPU_link(
- mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser), &out[0].link, &outalpha);
+ GPU_link(mat,
+ "node_tex_image_cubic",
+ in[0].link,
+ GPU_image(mat, ima, iuser),
+ &out[0].link,
+ &outalpha);
break;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 781fd1eb579..ebc852486dc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -123,26 +123,21 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
}
if (!*texco) {
- *texco = GPU_attribute(CD_MTFACE, "");
+ *texco = GPU_attribute(mat, CD_MTFACE, "");
node_shader_gpu_bump_tex_coord(mat, node, texco);
}
node_shader_gpu_tex_mapping(mat, node, in, out);
if (ima->source == IMA_SRC_TILED) {
- /* The tiled shader needs both the tile array itself as well as the mapping from tile to array
- * position. Which of these to allocate is automatically decided based on the shader argument
- * type, so here the first GPU_image(ima, iuser) will resolve to the array and the second to
- * the mapping since the third argument in the shader has type sampler2DArray while
- * the fourth is sampler1DArray.
- */
+ /* UDIM tiles needs a samper2DArray and sampler1DArray for tile mapping. */
GPU_stack_link(mat,
node,
names_tiled[tex->interpolation],
in,
out,
- GPU_image(ima, iuser),
- GPU_image(ima, iuser));
+ GPU_image_tiled(mat, ima, iuser),
+ GPU_image_tiled_mapping(mat, ima, iuser));
}
else {
switch (tex->projection) {
@@ -157,20 +152,21 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
case SHD_PROJ_BOX:
vnor = GPU_builtin(GPU_WORLD_NORMAL);
ob_mat = GPU_builtin(GPU_OBJECT_MATRIX);
blend = GPU_uniform(&tex->projection_blend);
- gpu_image = GPU_image(ima, iuser);
+ gpu_image = GPU_image(mat, ima, iuser);
/* equivalent to normal_world_to_object */
GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
- GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser), &col1, &col2, &col3);
+ GPU_link(
+ mat, gpu_node_name, *texco, norm, GPU_image(mat, ima, iuser), &col1, &col2, &col3);
GPU_stack_link(
mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend);
break;
@@ -184,9 +180,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
case SHD_PROJ_TUBE:
@@ -198,9 +194,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
}
@@ -208,7 +204,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (do_texco_clip) {
gpu_node_name = names_clip[tex->interpolation];
in[0].link = input_coords;
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser), out[0].link);
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser), out[0].link);
}
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index b1fb0cad4b2..0a576e465fa 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -63,7 +63,7 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPUNodeStack *out)
{
if (!in[0].link) {
- in[0].link = GPU_attribute(CD_ORCO, "");
+ in[0].link = GPU_attribute(mat, CD_ORCO, "");
}
node_shader_gpu_tex_mapping(mat, node, in, out);
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.c b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
index a2e47735490..f01542be44a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvmap.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
@@ -41,7 +41,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderUVMap *attr = node->storage;
- GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, attr->uv_map);
+ GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, attr->uv_map);
GPU_stack_link(mat, node, "node_uvmap", in, out, mtface);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
index ac8b49c4572..df303b2d3f1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
@@ -60,7 +60,7 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat,
"node_vector_displacement_tangent",
in,
out,
- GPU_attribute(CD_TANGENT, ""),
+ GPU_attribute(mat, CD_TANGENT, ""),
GPU_builtin(GPU_WORLD_NORMAL),
GPU_builtin(GPU_OBJECT_MATRIX),
GPU_builtin(GPU_VIEW_MATRIX));
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
index 8848fc37c66..98d575cece2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
@@ -39,7 +39,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
- GPUNodeLink *vertexColorLink = GPU_attribute(CD_MCOL, vertexColor->layer_name);
+ GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}