Blender V4.5
node_composite_group_input.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_string_ref.hh"
6
7#include "GPU_shader.hh"
8
9#include "NOD_composite.hh" /* Own include. */
10
11#include "COM_node_operation.hh"
12#include "COM_utilities.hh"
13
15
16using namespace blender::compositor;
17
19 public:
21
22 void execute() override
23 {
24 const Scene &scene = this->context().get_scene();
25 for (const bNodeSocket *output : this->node()->output_sockets()) {
27 continue;
28 }
29
30 Result &result = this->get_result(output->identifier);
31 if (!result.should_compute()) {
32 continue;
33 }
34
35 const char *pass_name = StringRef(output->name) == "Image" ? "Combined" : output->name;
36 this->context().populate_meta_data_for_pass(&scene, 0, pass_name, result.meta_data);
37
38 const Result pass = this->context().get_pass(&scene, 0, pass_name);
39 this->execute_pass(pass, result);
40 }
41 }
42
43 void execute_pass(const Result &pass, Result &result)
44 {
45 if (!pass.is_allocated()) {
46 /* Pass not rendered yet, or not supported by viewport. */
47 result.allocate_invalid();
48 this->context().set_info_message("Viewport compositor setup not fully supported");
49 return;
50 }
51
52 if (!this->context().is_valid_compositing_region()) {
53 result.allocate_invalid();
54 return;
55 }
56
57 result.set_type(pass.type());
58 result.set_precision(pass.precision());
59
60 if (this->context().use_gpu()) {
61 this->execute_pass_gpu(pass, result);
62 }
63 else {
64 this->execute_pass_cpu(pass, result);
65 }
66 }
67
69 {
70 GPUShader *shader = this->context().get_shader(this->get_shader_name(pass),
71 result.precision());
72 GPU_shader_bind(shader);
73
74 /* The compositing space might be limited to a subset of the pass texture, so only read that
75 * compositing region into an appropriately sized result. */
76 const rcti compositing_region = this->context().get_compositing_region();
77 const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin);
78 GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound);
79
80 pass.bind_as_texture(shader, "input_tx");
81
82 result.allocate_texture(Domain(this->context().get_compositing_region_size()));
83 result.bind_as_image(shader, "output_img");
84
85 compute_dispatch_threads_at_least(shader, result.domain().size);
86
88 pass.unbind_as_texture();
89 result.unbind_as_image();
90 }
91
92 const char *get_shader_name(const Result &pass)
93 {
94 switch (pass.type()) {
96 return "compositor_read_input_float";
100 return "compositor_read_input_float4";
101 case ResultType::Int:
102 case ResultType::Int2:
104 case ResultType::Bool:
105 /* Not supported. */
106 break;
107 }
108
110 return nullptr;
111 }
112
114 {
115 /* The compositing space might be limited to a subset of the pass texture, so only read that
116 * compositing region into an appropriately sized result. */
117 const rcti compositing_region = this->context().get_compositing_region();
118 const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin);
119
120 result.allocate_texture(Domain(this->context().get_compositing_region_size()));
121
122 parallel_for(result.domain().size, [&](const int2 texel) {
123 result.store_pixel_generic_type(texel, pass.load_pixel_generic_type(texel + lower_bound));
124 });
125 }
126};
127
128} // namespace blender::nodes::node_composite_group_input_cc
129
130namespace blender::nodes {
131
137
138} // namespace blender::nodes
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_unbind()
virtual const Scene & get_scene() const =0
virtual void populate_meta_data_for_pass(const Scene *scene, int view_layer_id, const char *pass_name, MetaData &meta_data) const
GPUShader * get_shader(const char *info_name, ResultPrecision precision)
virtual Result get_pass(const Scene *scene, int view_layer, const char *pass_name)=0
virtual rcti get_compositing_region() const =0
virtual void set_info_message(StringRef message) const =0
NodeOperation(Context &context, DNode node)
Result & get_result(StringRef identifier)
Definition operation.cc:39
static ResultPrecision precision(eGPUTextureFormat format)
Definition result.cc:166
void unbind_as_texture() const
Definition result.cc:389
static ResultType type(eGPUTextureFormat format)
Definition result.cc:194
void bind_as_texture(GPUShader *shader, const char *texture_name) const
Definition result.cc:365
bool is_allocated() const
Definition result.cc:627
#define output
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:170
void parallel_for(const int2 range, const Function &function)
bool is_socket_available(const bNodeSocket *socket)
Definition utilities.cc:25
compositor::NodeOperation * get_group_input_compositor_operation(compositor::Context &context, DNode node)
VecBase< int32_t, 2 > int2
int ymin
int xmin