Blender
V5.0
source
blender
compositor
COM_shader_operation.hh
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
#pragma once
6
7
#include <memory>
8
9
#include "
BLI_map.hh
"
10
11
#include "
GPU_material.hh
"
12
#include "
GPU_shader.hh
"
13
14
#include "
gpu_shader_create_info.hh
"
15
16
#include "
NOD_derived_node_tree.hh
"
17
18
#include "
COM_context.hh
"
19
#include "
COM_input_descriptor.hh
"
20
#include "
COM_pixel_operation.hh
"
21
#include "
COM_scheduler.hh
"
22
#include "
COM_shader_node.hh
"
23
24
namespace
blender::compositor
{
25
26
using namespace
nodes::derived_node_tree_types;
27
28
/* ------------------------------------------------------------------------------------------------
29
* Shader Operation
30
*
31
* A pixel operation that evaluates a shader compiled from the pixel compile unit using the GPU
32
* material compiler, see GPU_material.hh for more information. Also see the PixelOperation class
33
* for more information on pixel operations.
34
*
35
* An input to the pixel operation is declared for a distinct output socket as follows:
36
*
37
* - A texture is added to the shader, which will be bound to the result of the output socket
38
* during evaluation.
39
* - A GPU attribute is added to the GPU material for that output socket and is linked to the GPU
40
* input stack of the inputs linked to the output socket.
41
* - Code is emitted to initialize the values of the attributes by sampling the textures
42
* corresponding to each of the inputs.
43
* - The newly added attribute is mapped to the output socket in output_to_material_attribute_map_
44
* to share that same attributes for all inputs linked to the same output socket.
45
*
46
* An output to the pixel operation is declared for an output socket as follows:
47
*
48
* - An image is added in the shader where the output value will be written.
49
* - A storer GPU material node that stores the value of the output is added and linked to the GPU
50
* output stack of the output. The storer will store the value in the image identified by the
51
* index of the output given to the storer.
52
* - The storer functions are generated dynamically to map each index with its appropriate image.
53
*
54
* The GPU material code generator source is used to construct a compute shader that is then
55
* dispatched during operation evaluation after binding the inputs, outputs, and any necessary
56
* resources. */
57
class
ShaderOperation
:
public
PixelOperation
{
58
private
:
59
/* The GPU material backing the operation. This is created and compiled during construction and
60
* freed during destruction. */
61
GPUMaterial
*material_;
62
/* A map that associates each node in the compile unit with an instance of its shader node. */
63
Map<DNode, std::unique_ptr<ShaderNode>
> shader_nodes_;
64
/* A map that associates the output socket of a node that is not part of the shader operation to
65
* the attribute that was created for it. This is used to share the same attribute with all
66
* inputs that are linked to the same output socket. */
67
Map<DOutputSocket, GPUNodeLink *>
output_to_material_attribute_map_;
68
/* A map that associates implicit inputs to the attributes that were created for them. */
69
Map<ImplicitInput, GPUNodeLink *>
implicit_input_to_material_attribute_map_;
70
71
public
:
72
/* Construct and compile a GPU material from the given shader compile unit and execution schedule
73
* by calling GPU_material_from_callbacks with the appropriate callbacks. */
74
ShaderOperation
(
Context
&
context
,
PixelCompileUnit
&compile_unit,
const
Schedule
&schedule);
75
76
/* Free the GPU material. */
77
~ShaderOperation
()
override
;
78
79
/* Allocate the output results, bind the shader and all its needed resources, then dispatch the
80
* shader. */
81
void
execute
()
override
;
82
83
private
:
84
/* Bind the uniform buffer of the GPU material as well as any color band textures needed by the
85
* GPU material. The compiled shader of the material is given as an argument and assumed to be
86
* bound. */
87
void
bind_material_resources(
gpu::Shader
*shader);
88
89
/* Bind the input results of the operation to the appropriate textures in the GPU material. The
90
* attributes stored in output_to_material_attribute_map_ have names that match the texture
91
* samplers in the shader as well as the identifiers of the operation inputs that they correspond
92
* to. The compiled shader of the material is given as an argument and assumed to be bound. */
93
void
bind_inputs(
gpu::Shader
*shader);
94
95
/* Bind the output results of the operation to the appropriate images in the GPU material. The
96
* name of the images in the shader match the identifier of their corresponding outputs. The
97
* compiled shader of the material is given as an argument and assumed to be bound. */
98
void
bind_outputs(
gpu::Shader
*shader);
99
100
/* A static callback method of interface ConstructGPUMaterialFn that is passed to
101
* GPU_material_from_callbacks to construct the GPU material graph. The thunk parameter will be a
102
* pointer to the instance of ShaderOperation that is being compiled. The method goes over the
103
* compile unit and does the following for each node:
104
*
105
* - Instantiate a ShaderNode from the node and add it to shader_nodes_.
106
* - Link the inputs of the node if needed. The inputs are either linked to other nodes in the
107
* GPU material graph or are exposed as inputs to the shader operation itself if they are
108
* linked to nodes that are not part of the shader operation.
109
* - Call the compile method of the shader node to actually add and link the GPU material graph
110
* nodes.
111
* - If any of the outputs of the node are linked to nodes that are not part of the shader
112
* operation, they are exposed as outputs to the shader operation itself. */
113
static
void
construct_material(
void
*thunk,
GPUMaterial
*material);
114
115
/* Link the inputs of the node if needed. Unlinked inputs will be linked to constant values. If
116
* the input is linked to a node that is not part of the shader operation, the input will be
117
* exposed as an input to the shader operation and linked to it. While if the input is linked to
118
* a node that is part of the shader operation, then it is linked to that node in the GPU
119
* material node graph. */
120
void
link_node_inputs(
DNode
node);
121
122
/* Link the GPU stack of the given unavailable input to a constant zero value setter GPU node.
123
* The value is ignored since the socket is unavailable, but the GPU Material compiler expects
124
* all inputs to be linked, even unavailable ones. */
125
void
link_node_input_unavailable(
const
DInputSocket
input
);
126
127
/* Link the GPU stack of the given unlinked input to a constant value setter GPU node that
128
* supplies the value of the unlinked input. The value is taken from the given origin input,
129
* which will be equal to the input in most cases, but can also be an unlinked input of a group
130
* node. */
131
void
link_node_input_constant(
const
DInputSocket
input
,
const
DInputSocket
origin);
132
133
/* Given an unlinked input with an implicit input. Declare a new input to the operation for that
134
* implicit input if not done already and link it to the input link of the GPU node stack of the
135
* input socket. The implicit input and type are taken from the given origin input, which will
136
* be equal to the input in most cases, but can also be an unlinked input of a group node */
137
void
link_node_input_implicit(
const
DInputSocket
input
,
const
DInputSocket
origin);
138
139
/* Given the input socket of a node that is part of the shader operation which is linked to the
140
* given output socket of a node that is also part of the shader operation, just link the output
141
* link of the GPU node stack of the output socket to the input link of the GPU node stack of the
142
* input socket. This essentially establishes the needed links in the GPU material node graph. */
143
void
link_node_input_internal(
DInputSocket
input_socket,
DOutputSocket
output_socket);
144
145
/* Given the input socket of a node that is part of the shader operation which is linked to the
146
* given output socket of a node that is not part of the shader operation, declare a new
147
* operation input and link it to the input link of the GPU node stack of the input socket. An
148
* operation input is only declared if no input was already declared for that same output socket
149
* before. */
150
void
link_node_input_external(
DInputSocket
input_socket,
DOutputSocket
output_socket);
151
152
/* Given the input socket of a node that is part of the shader operation which is linked to the
153
* given output socket of a node that is not part of the shader operation, declare a new input to
154
* the operation that is represented in the GPU material by a newly created GPU attribute. It is
155
* assumed that no operation input was declared for this same output socket before. In the
156
* generate_code_for_inputs method, a texture will be added in the shader for each of the
157
* declared inputs, having the same name as the attribute. Additionally, code will be emitted to
158
* initialize the attributes by sampling their corresponding textures. */
159
void
declare_operation_input(
DInputSocket
input_socket,
DOutputSocket
output_socket);
160
161
/* Populate the output results of the shader operation for output sockets of the given node that
162
* are linked to nodes outside of the shader operation or are used to compute a preview for the
163
* node. */
164
void
populate_results_for_node(
DNode
node);
165
166
/* Given the output socket of a node that is part of the shader operation which is linked to an
167
* input socket of a node that is not part of the shader operation, declare a new output to the
168
* operation and link it to an output storer passing in the index of the output. In the
169
* generate_code_for_outputs method, an image will be added in the shader for each of the
170
* declared outputs. Additionally, code will be emitted to define the storer functions that store
171
* the value in the appropriate image identified by the given index. */
172
void
populate_operation_result(
DOutputSocket
output_socket);
173
174
/* A static callback method of interface GPUCodegenCallbackFn that is passed to
175
* GPU_material_from_callbacks to create the shader create info of the GPU material. The thunk
176
* parameter will be a pointer to the instance of ShaderOperation that is being compiled.
177
*
178
* This method first generates the necessary code to load the inputs and store the outputs. Then,
179
* it creates a compute shader from the generated sources. Finally, it adds the necessary GPU
180
* resources to the shader. */
181
static
void
generate_code(
void
*thunk,
GPUMaterial
*material,
GPUCodegenOutput
*code_generator);
182
183
/* Add an image in the shader for each of the declared outputs. Additionally, emit code to define
184
* the storer functions that store the given value in the appropriate image identified by the
185
* given index. */
186
std::string generate_code_for_outputs(
gpu::shader::ShaderCreateInfo
&shader_create_info);
187
188
/* Add a texture will in the shader for each of the declared inputs/attributes in the operation,
189
* having the same name as the attribute. Additionally, emit code to initialize the attributes by
190
* sampling their corresponding textures. */
191
std::string generate_code_for_inputs(
GPUMaterial
*material,
192
gpu::shader::ShaderCreateInfo
&shader_create_info);
193
};
194
195
}
// namespace blender::compositor
BLI_map.hh
COM_context.hh
COM_input_descriptor.hh
COM_pixel_operation.hh
COM_scheduler.hh
COM_shader_node.hh
GPU_material.hh
GPU_shader.hh
NOD_derived_node_tree.hh
blender::Map
Definition
BLI_map.hh:129
blender::compositor::Context
Definition
COM_context.hh:44
blender::compositor::Operation::context
Context & context() const
Definition
operation.cc:163
blender::compositor::PixelOperation::PixelOperation
PixelOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
Definition
pixel_operation.cc:27
blender::compositor::ShaderOperation::ShaderOperation
ShaderOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
Definition
shader_operation.cc:40
blender::compositor::ShaderOperation::execute
void execute() override
Definition
shader_operation.cc:54
blender::compositor::ShaderOperation::~ShaderOperation
~ShaderOperation() override
Definition
shader_operation.cc:49
blender::gpu::Shader
Definition
gpu_shader_private.hh:43
blender::nodes::DInputSocket
Definition
NOD_derived_node_tree.hh:132
blender::nodes::DNode
Definition
NOD_derived_node_tree.hh:71
blender::nodes::DOutputSocket
Definition
NOD_derived_node_tree.hh:150
input
#define input
Definition
gpu_shader_compat_cxx.hh:170
gpu_shader_create_info.hh
blender::compositor
Definition
BKE_node.hh:77
blender::compositor::Schedule
VectorSet< DNode > Schedule
Definition
COM_scheduler.hh:18
blender::compositor::PixelCompileUnit
VectorSet< DNode > PixelCompileUnit
Definition
COM_pixel_operation.hh:23
GPUCodegenOutput
Definition
GPU_material.hh:342
GPUMaterial
Definition
gpu/intern/gpu_material.cc:63
blender::gpu::shader::ShaderCreateInfo
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Definition
gpu_shader_create_info.hh:686
Generated on
for Blender by
doxygen
1.16.1