diff options
author | Omar Emara <mail@OmarEmara.dev> | 2022-04-11 10:44:27 +0300 |
---|---|---|
committer | Omar Emara <mail@OmarEmara.dev> | 2022-04-11 10:44:27 +0300 |
commit | b96035aabdd46f6d1c99eee310a215a1fef8ac7d (patch) | |
tree | f3d6177389a62786199011e290d2ef733ec88408 | |
parent | 5f5ee2718e63efad28c1951db17751df65817eea (diff) |
Viewport Compositor: Move GPU material node to its own file
5 files changed, 200 insertions, 166 deletions
diff --git a/source/blender/viewport_compositor/CMakeLists.txt b/source/blender/viewport_compositor/CMakeLists.txt index 58cf7567d83..19ddb3e2141 100644 --- a/source/blender/viewport_compositor/CMakeLists.txt +++ b/source/blender/viewport_compositor/CMakeLists.txt @@ -20,6 +20,7 @@ set(SRC intern/context.cc intern/conversion_processor_operation.cc intern/domain.cc + intern/gpu_material_node.cc intern/node_operation.cc intern/operation.cc intern/processor_operation.cc @@ -34,6 +35,7 @@ set(SRC VPC_context.hh VPC_conversion_processor_operation.hh VPC_domain.hh + VPC_gpu_material_node.hh VPC_input_descriptor.hh VPC_node_operation.hh VPC_operation.hh diff --git a/source/blender/viewport_compositor/VPC_compositor_execute.hh b/source/blender/viewport_compositor/VPC_compositor_execute.hh index b0c37017db1..76748ccf67d 100644 --- a/source/blender/viewport_compositor/VPC_compositor_execute.hh +++ b/source/blender/viewport_compositor/VPC_compositor_execute.hh @@ -23,6 +23,7 @@ #include "VPC_context.hh" #include "VPC_domain.hh" +#include "VPC_gpu_material_node.hh" #include "VPC_node_operation.hh" #include "VPC_operation.hh" #include "VPC_result.hh" @@ -34,57 +35,6 @@ namespace blender::viewport_compositor { using namespace nodes::derived_node_tree_types; /* -------------------------------------------------------------------- - * GPU Material Node. - */ - -/* A class that represents a node in a GPU material. The GPU node stacks for inputs and outputs are - * stored and populated during construction. Derived class should implement the compile method to - * implement the node and link it to the GPU material. The GPU material compiler is expected to - * initialize the input links of node before invoking the compile method. */ -class GPUMaterialNode { - private: - /* The node that this operation represents. */ - DNode node_; - /* The GPU node stacks of the inputs of the node. Those are populated during construction in the - * populate_inputs method. The links of the inputs are initialized by the GPU material compiler - * prior to calling the compile method. There is an extra stack at the end to mark the end of the - * array, as this is what the GPU module functions expect. */ - Vector<GPUNodeStack> inputs_; - /* The GPU node stacks of the outputs of the node. Those are populated during construction in the - * populate_outputs method. There is an extra stack at the end to mark the end of the array, as - * this is what the GPU module functions expect. */ - Vector<GPUNodeStack> outputs_; - - public: - /* Construct the node by populating both its inputs and outputs. */ - GPUMaterialNode(DNode node); - - virtual ~GPUMaterialNode() = default; - - /* Compile the node by adding the appropriate GPU material graph nodes and linking the - * appropriate resources. */ - virtual void compile(GPUMaterial *material) = 0; - - /* Returns a contiguous array containing the GPU node stacks of each input. */ - GPUNodeStack *get_inputs_array(); - - /* Returns a contiguous array containing the GPU node stacks of each output. */ - GPUNodeStack *get_outputs_array(); - - protected: - /* Returns a reference to the node this operations represents. */ - bNode &node() const; - - private: - /* Populate the inputs of the node. The input link is set to nullptr and is expected to be - * initialized by the GPU material compiler before calling the compile method. */ - void populate_inputs(); - /* Populate the outputs of the node. The output link is set to nullptr and is expected to be - * initialized by the compile method. */ - void populate_outputs(); -}; - -/* -------------------------------------------------------------------- * GPU Material Operation. */ diff --git a/source/blender/viewport_compositor/VPC_gpu_material_node.hh b/source/blender/viewport_compositor/VPC_gpu_material_node.hh new file mode 100644 index 00000000000..3358c3f15db --- /dev/null +++ b/source/blender/viewport_compositor/VPC_gpu_material_node.hh @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +#pragma once + +#include "BLI_vector.hh" + +#include "DNA_node_types.h" + +#include "GPU_material.h" + +#include "NOD_derived_node_tree.hh" + +namespace blender::viewport_compositor { + +using namespace nodes::derived_node_tree_types; + +/* A class that represents a node in a GPU material. The GPU node stacks for inputs and outputs are + * stored and populated during construction. Derived class should implement the compile method to + * implement the node and link it to the GPU material. The GPU material compiler is expected to + * initialize the input links of node before invoking the compile method. */ +class GPUMaterialNode { + private: + /* The node that this operation represents. */ + DNode node_; + /* The GPU node stacks of the inputs of the node. Those are populated during construction in the + * populate_inputs method. The links of the inputs are initialized by the GPU material compiler + * prior to calling the compile method. There is an extra stack at the end to mark the end of the + * array, as this is what the GPU module functions expect. */ + Vector<GPUNodeStack> inputs_; + /* The GPU node stacks of the outputs of the node. Those are populated during construction in the + * populate_outputs method. There is an extra stack at the end to mark the end of the array, as + * this is what the GPU module functions expect. */ + Vector<GPUNodeStack> outputs_; + + public: + /* Construct the node by populating both its inputs and outputs. */ + GPUMaterialNode(DNode node); + + virtual ~GPUMaterialNode() = default; + + /* Compile the node by adding the appropriate GPU material graph nodes and linking the + * appropriate resources. */ + virtual void compile(GPUMaterial *material) = 0; + + /* Returns a contiguous array containing the GPU node stacks of each input. */ + GPUNodeStack *get_inputs_array(); + + /* Returns a contiguous array containing the GPU node stacks of each output. */ + GPUNodeStack *get_outputs_array(); + + protected: + /* Returns a reference to the node this operations represents. */ + bNode &node() const; + + private: + /* Populate the inputs of the node. The input link is set to nullptr and is expected to be + * initialized by the GPU material compiler before calling the compile method. */ + void populate_inputs(); + /* Populate the outputs of the node. The output link is set to nullptr and is expected to be + * initialized by the compile method. */ + void populate_outputs(); +}; + +} // namespace blender::viewport_compositor diff --git a/source/blender/viewport_compositor/intern/compositor_execute.cc b/source/blender/viewport_compositor/intern/compositor_execute.cc index 73545bbf8cc..2d966267d8a 100644 --- a/source/blender/viewport_compositor/intern/compositor_execute.cc +++ b/source/blender/viewport_compositor/intern/compositor_execute.cc @@ -40,6 +40,7 @@ #include "VPC_compositor_execute.hh" #include "VPC_context.hh" #include "VPC_domain.hh" +#include "VPC_gpu_material_node.hh" #include "VPC_input_descriptor.hh" #include "VPC_node_operation.hh" #include "VPC_operation.hh" @@ -48,125 +49,10 @@ #include "VPC_texture_pool.hh" #include "VPC_utilities.hh" -/* -------------------------------------------------------------------- - * GPU Material Node. - */ - namespace blender::viewport_compositor { using namespace nodes::derived_node_tree_types; -GPUMaterialNode::GPUMaterialNode(DNode node) : node_(node) -{ - populate_inputs(); - populate_outputs(); -} - -GPUNodeStack *GPUMaterialNode::get_inputs_array() -{ - return inputs_.data(); -} - -GPUNodeStack *GPUMaterialNode::get_outputs_array() -{ - return outputs_.data(); -} - -bNode &GPUMaterialNode::node() const -{ - return *node_->bnode(); -} - -static eGPUType gpu_type_from_socket_type(eNodeSocketDatatype type) -{ - switch (type) { - case SOCK_FLOAT: - return GPU_FLOAT; - case SOCK_VECTOR: - return GPU_VEC3; - case SOCK_RGBA: - return GPU_VEC4; - default: - BLI_assert_unreachable(); - return GPU_NONE; - } -} - -static void gpu_stack_vector_from_socket(float *vector, const SocketRef *socket) -{ - switch (socket->bsocket()->type) { - case SOCK_FLOAT: - vector[0] = socket->default_value<bNodeSocketValueFloat>()->value; - return; - case SOCK_VECTOR: - copy_v3_v3(vector, socket->default_value<bNodeSocketValueVector>()->value); - return; - case SOCK_RGBA: - copy_v4_v4(vector, socket->default_value<bNodeSocketValueRGBA>()->value); - return; - default: - BLI_assert_unreachable(); - } -} - -static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack) -{ - /* Make sure this stack is not marked as the end of the stack array. */ - stack.end = false; - /* This will be initialized later by the GPU material compiler or the compile method. */ - stack.link = nullptr; - /* Socket type and its corresponding GPU type. */ - stack.sockettype = socket->bsocket()->type; - stack.type = gpu_type_from_socket_type((eNodeSocketDatatype)socket->bsocket()->type); - - if (socket->is_input()) { - /* Get the origin socket connected to the input if any. */ - const DInputSocket input{socket.context(), &socket->as_input()}; - DSocket origin = get_node_input_origin_socket(input); - /* The input is linked if the origin socket is not null and is an output socket. Had it been an - * input socket, then it is an unlinked input of a group input node. */ - stack.hasinput = origin->is_output(); - /* Get the socket value from the origin if it is an input, because then it would be an unlinked - * input of a group input node, otherwise, get the value from the socket itself. */ - if (origin->is_input()) { - gpu_stack_vector_from_socket(stack.vec, origin.socket_ref()); - } - else { - gpu_stack_vector_from_socket(stack.vec, socket.socket_ref()); - } - } - else { - stack.hasoutput = socket->is_logically_linked(); - /* Populate the stack vector even for outputs because some nodes store their properties in the - * default values of their outputs. */ - gpu_stack_vector_from_socket(stack.vec, socket.socket_ref()); - } -} - -void GPUMaterialNode::populate_inputs() -{ - /* Reserve a stack for each input in addition to an extra stack at the end to mark the end of the - * array, as this is what the GPU module functions expect. */ - inputs_.resize(node_->inputs().size() + 1); - inputs_.last().end = true; - - for (int i = 0; i < node_->inputs().size(); i++) { - populate_gpu_node_stack(node_.input(i), inputs_[i]); - } -} - -void GPUMaterialNode::populate_outputs() -{ - /* Reserve a stack for each output in addition to an extra stack at the end to mark the end of - * the array, as this is what the GPU module functions expect. */ - outputs_.resize(node_->outputs().size() + 1); - outputs_.last().end = true; - - for (int i = 0; i < node_->outputs().size(); i++) { - populate_gpu_node_stack(node_.output(i), outputs_[i]); - } -} - /* -------------------------------------------------------------------- * GPU Material Operation. */ diff --git a/source/blender/viewport_compositor/intern/gpu_material_node.cc b/source/blender/viewport_compositor/intern/gpu_material_node.cc new file mode 100644 index 00000000000..935b891ae79 --- /dev/null +++ b/source/blender/viewport_compositor/intern/gpu_material_node.cc @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +#include "BLI_assert.h" +#include "BLI_math_vector.h" + +#include "DNA_node_types.h" + +#include "NOD_derived_node_tree.hh" + +#include "GPU_material.h" + +#include "VPC_gpu_material_node.hh" +#include "VPC_utilities.hh" + +namespace blender::viewport_compositor { + +using namespace nodes::derived_node_tree_types; + +GPUMaterialNode::GPUMaterialNode(DNode node) : node_(node) +{ + populate_inputs(); + populate_outputs(); +} + +GPUNodeStack *GPUMaterialNode::get_inputs_array() +{ + return inputs_.data(); +} + +GPUNodeStack *GPUMaterialNode::get_outputs_array() +{ + return outputs_.data(); +} + +bNode &GPUMaterialNode::node() const +{ + return *node_->bnode(); +} + +static eGPUType gpu_type_from_socket_type(eNodeSocketDatatype type) +{ + switch (type) { + case SOCK_FLOAT: + return GPU_FLOAT; + case SOCK_VECTOR: + return GPU_VEC3; + case SOCK_RGBA: + return GPU_VEC4; + default: + BLI_assert_unreachable(); + return GPU_NONE; + } +} + +static void gpu_stack_vector_from_socket(float *vector, const SocketRef *socket) +{ + switch (socket->bsocket()->type) { + case SOCK_FLOAT: + vector[0] = socket->default_value<bNodeSocketValueFloat>()->value; + return; + case SOCK_VECTOR: + copy_v3_v3(vector, socket->default_value<bNodeSocketValueVector>()->value); + return; + case SOCK_RGBA: + copy_v4_v4(vector, socket->default_value<bNodeSocketValueRGBA>()->value); + return; + default: + BLI_assert_unreachable(); + } +} + +static void populate_gpu_node_stack(DSocket socket, GPUNodeStack &stack) +{ + /* Make sure this stack is not marked as the end of the stack array. */ + stack.end = false; + /* This will be initialized later by the GPU material compiler or the compile method. */ + stack.link = nullptr; + /* Socket type and its corresponding GPU type. */ + stack.sockettype = socket->bsocket()->type; + stack.type = gpu_type_from_socket_type((eNodeSocketDatatype)socket->bsocket()->type); + + if (socket->is_input()) { + /* Get the origin socket connected to the input if any. */ + const DInputSocket input{socket.context(), &socket->as_input()}; + DSocket origin = get_node_input_origin_socket(input); + /* The input is linked if the origin socket is not null and is an output socket. Had it been an + * input socket, then it is an unlinked input of a group input node. */ + stack.hasinput = origin->is_output(); + /* Get the socket value from the origin if it is an input, because then it would be an unlinked + * input of a group input node, otherwise, get the value from the socket itself. */ + if (origin->is_input()) { + gpu_stack_vector_from_socket(stack.vec, origin.socket_ref()); + } + else { + gpu_stack_vector_from_socket(stack.vec, socket.socket_ref()); + } + } + else { + stack.hasoutput = socket->is_logically_linked(); + /* Populate the stack vector even for outputs because some nodes store their properties in the + * default values of their outputs. */ + gpu_stack_vector_from_socket(stack.vec, socket.socket_ref()); + } +} + +void GPUMaterialNode::populate_inputs() +{ + /* Reserve a stack for each input in addition to an extra stack at the end to mark the end of the + * array, as this is what the GPU module functions expect. */ + inputs_.resize(node_->inputs().size() + 1); + inputs_.last().end = true; + + for (int i = 0; i < node_->inputs().size(); i++) { + populate_gpu_node_stack(node_.input(i), inputs_[i]); + } +} + +void GPUMaterialNode::populate_outputs() +{ + /* Reserve a stack for each output in addition to an extra stack at the end to mark the end of + * the array, as this is what the GPU module functions expect. */ + outputs_.resize(node_->outputs().size() + 1); + outputs_.last().end = true; + + for (int i = 0; i < node_->outputs().size(); i++) { + populate_gpu_node_stack(node_.output(i), outputs_[i]); + } +} + +} // namespace blender::viewport_compositor |