Blender V4.5
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 (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 return GPU_VEC3;
57 case SOCK_RGBA:
58 return GPU_VEC4;
59 default:
60 /* The GPU material compiler will skip unsupported sockets if GPU_NONE is provided. So this
61 * is an appropriate and a valid type for unsupported sockets. */
62 return GPU_NONE;
63 }
64}
65
66static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack)
67{
68 /* Make sure this stack is not marked as the end of the stack array. */
69 stack.end = false;
70 /* This will be initialized later by the GPU material compiler or the compile method. */
71 stack.link = nullptr;
72 /* This will be initialized by the GPU material compiler if needed. */
73 zero_v4(stack.vec);
74
75 stack.sockettype = socket->type;
77
78 stack.hasinput = socket->is_logically_linked();
79 stack.hasoutput = socket->is_logically_linked();
80}
81
82void ShaderNode::populate_inputs()
83{
84 /* Reserve a stack for each input in addition to an extra stack at the end to mark the end of the
85 * array, as this is what the GPU module functions expect. */
86 const int num_input_sockets = node_->input_sockets().size();
87 inputs_.resize(num_input_sockets + 1);
88 inputs_.last().end = true;
89
90 for (int i = 0; i < num_input_sockets; i++) {
91 populate_gpu_node_stack(node_.input(i), inputs_[i]);
92 }
93}
94
95void ShaderNode::populate_outputs()
96{
97 /* Reserve a stack for each output in addition to an extra stack at the end to mark the end of
98 * the array, as this is what the GPU module functions expect. */
99 const int num_output_sockets = node_->output_sockets().size();
100 outputs_.resize(num_output_sockets + 1);
101 outputs_.last().end = true;
102
103 for (int i = 0; i < num_output_sockets; i++) {
104 populate_gpu_node_stack(node_.output(i), outputs_[i]);
105 }
106}
107
108} // namespace blender::compositor
MINLINE void zero_v4(float r[4])
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_RGBA
eGPUType
@ GPU_VEC4
@ GPU_NONE
@ GPU_VEC3
@ GPU_FLOAT
const T & last(const int64_t n=0) const
void resize(const int64_t new_size)
GPUNodeStack & get_input(StringRef identifier)
void compile(GPUMaterial *material)
GPUNodeStack & get_output(StringRef identifier)
GPUNodeStack & get_shader_node_input(const bNode &node, GPUNodeStack inputs[], StringRef identifier)
static eGPUType gpu_type_from_socket_type(eNodeSocketDatatype type)
GPUNodeStack & get_shader_node_output(const bNode &node, GPUNodeStack outputs[], StringRef identifier)
static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack)
GPUNodeLink * link
i
Definition text_draw.cc:230