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:
authorBrecht Van Lommel <brecht@blender.org>2020-02-27 15:55:29 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-02-27 18:14:21 +0300
commite88a715364981af39353073c6d96b9056fafca6b (patch)
tree5deb475604760b1e5a59fc3ef4409f38d8ecfd11 /source/blender/gpu/intern/gpu_node_graph.c
parent1ec11363bd93cf6bd43e5da33322b3f88a9be210 (diff)
Cleanup: more refactoring of GPU material attributes and textures
This further separates requested attributes and textures from the actual node graph, that can be retained after the graph has been compiled and freed. It makes it easier to add volume grids as a native concept, which sits somewhere between an attribute and a texture. It also adds explicit link types for UDIM tile mapping, rather than relying on fairly hidden logic.
Diffstat (limited to 'source/blender/gpu/intern/gpu_node_graph.c')
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c178
1 files changed, 146 insertions, 32 deletions
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);
+ }
+ }
}