Blender V5.0
shader_node.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_vector.h"
6#include "BLI_string_ref.hh"
7
8#include "DNA_node_types.h"
9
11
12#include "GPU_material.hh"
13
14#include "COM_shader_node.hh"
15#include "COM_utilities.hh"
17
18namespace blender::compositor {
19
20using namespace nodes::derived_node_tree_types;
21
22ShaderNode::ShaderNode(DNode node) : node_(node)
23{
24 this->populate_inputs();
25 this->populate_outputs();
26}
27
29{
30 node_->typeinfo->gpu_fn(
31 material, const_cast<bNode *>(node_.bnode()), nullptr, inputs_.data(), outputs_.data());
32}
33
35{
36 return get_shader_node_input(*node_, inputs_.data(), identifier);
37}
38
40{
41 return get_shader_node_output(*node_, outputs_.data(), identifier);
42}
43
45{
46 switch (eNodeSocketDatatype(socket->type)) {
47 case SOCK_FLOAT:
48 return GPU_FLOAT;
49 case SOCK_INT:
50 /* GPUMaterial doesn't support int, so it is passed as a float. */
51 return GPU_FLOAT;
52 case SOCK_BOOLEAN:
53 /* GPUMaterial doesn't support boolean, so it is passed as a float. */
54 return GPU_FLOAT;
55 case SOCK_VECTOR:
56 switch (socket->default_value_typed<bNodeSocketValueVector>()->dimensions) {
57 case 2:
58 return GPU_VEC2;
59 case 3:
60 return GPU_VEC3;
61 case 4:
62 return GPU_VEC4;
63 default:
65 return GPU_NONE;
66 }
67 case SOCK_RGBA:
68 return GPU_VEC4;
69 case SOCK_MENU:
70 /* GPUMaterial doesn't support int, so it is passed as a float. */
71 return GPU_FLOAT;
72 case SOCK_STRING:
73 /* Single only types do not support GPU code path. */
76 return GPU_NONE;
77 default:
78 /* The GPU material compiler will skip unsupported sockets if GPU_NONE is provided. So this
79 * is an appropriate and a valid type for unsupported sockets. */
80 return GPU_NONE;
81 }
82}
83
84static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack)
85{
86 /* Make sure this stack is not marked as the end of the stack array. */
87 stack.end = false;
88 /* This will be initialized later by the GPU material compiler or the compile method. */
89 stack.link = nullptr;
90 /* This will be initialized by the GPU material compiler if needed. */
91 zero_v4(stack.vec);
92
93 stack.sockettype = socket->type;
94 stack.type = gpu_type_from_socket(socket);
95
96 stack.hasinput = socket->is_logically_linked();
97 stack.hasoutput = socket->is_logically_linked();
98}
99
100void ShaderNode::populate_inputs()
101{
102 /* Reserve a stack for each input in addition to an extra stack at the end to mark the end of the
103 * array, as this is what the GPU module functions expect. */
104 const int num_input_sockets = node_->input_sockets().size();
105 inputs_.resize(num_input_sockets + 1);
106 inputs_.last().end = true;
107
108 for (int i = 0; i < num_input_sockets; i++) {
109 populate_gpu_node_stack(node_.input(i), inputs_[i]);
110 }
111}
112
113void ShaderNode::populate_outputs()
114{
115 /* Reserve a stack for each output in addition to an extra stack at the end to mark the end of
116 * the array, as this is what the GPU module functions expect. */
117 const int num_output_sockets = node_->output_sockets().size();
118 outputs_.resize(num_output_sockets + 1);
119 outputs_.last().end = true;
120
121 for (int i = 0; i < num_output_sockets; i++) {
122 populate_gpu_node_stack(node_.output(i), outputs_[i]);
123 }
124}
125
126} // namespace blender::compositor
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE void zero_v4(float r[4])
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
GPUType
@ GPU_VEC2
@ GPU_VEC4
@ GPU_NONE
@ GPU_VEC3
@ GPU_FLOAT
const T & last(const int64_t n=0) const
void resize(const int64_t new_size)
static bool is_single_value_only_type(ResultType type)
Definition result.cc:44
GPUNodeStack & get_input(StringRef identifier)
void compile(GPUMaterial *material)
GPUNodeStack & get_output(StringRef identifier)
const bNodeSocket * bsocket() const
GPUNodeStack & get_shader_node_input(const bNode &node, GPUNodeStack inputs[], StringRef identifier)
GPUNodeStack & get_shader_node_output(const bNode &node, GPUNodeStack outputs[], StringRef identifier)
ResultType get_node_socket_result_type(const bNodeSocket *socket)
Definition utilities.cc:102
static GPUType gpu_type_from_socket(DSocket socket)
static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack)
GPUNodeLink * link
i
Definition text_draw.cc:230