diff options
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); } |