Files
test/source/blender/compositor/intern/node_operation.cc
Jeroen Bakker 542e7bb8e7 Compositor: Add GPU debug groups
This PR adds debug groups to improve using GPU tools like debuggers
and profilers. It will try to use the node type as debug group name when
available.

Pull Request: https://projects.blender.org/blender/blender/pulls/138768
2025-05-12 15:45:45 +02:00

144 lines
3.6 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "BLI_string_ref.hh"
#include "BLI_timeit.hh"
#include "DNA_node_types.h"
#include "NOD_derived_node_tree.hh"
#include "BKE_node.hh"
#include "GPU_debug.hh"
#include "COM_algorithm_compute_preview.hh"
#include "COM_context.hh"
#include "COM_input_descriptor.hh"
#include "COM_node_operation.hh"
#include "COM_operation.hh"
#include "COM_result.hh"
#include "COM_scheduler.hh"
#include "COM_utilities.hh"
namespace blender::compositor {
using namespace nodes::derived_node_tree_types;
NodeOperation::NodeOperation(Context &context, DNode node) : Operation(context), node_(node)
{
for (const bNodeSocket *output : node->output_sockets()) {
if (!output->is_available()) {
continue;
}
const ResultType result_type = get_node_socket_result_type(output);
populate_result(output->identifier, context.create_result(result_type));
}
for (const bNodeSocket *input : node->input_sockets()) {
if (!input->is_available()) {
continue;
}
const InputDescriptor input_descriptor = input_descriptor_from_input_socket(input);
declare_input_descriptor(input->identifier, input_descriptor);
}
}
void NodeOperation::evaluate()
{
if (context().use_gpu()) {
GPU_debug_group_begin(node().bnode()->typeinfo->idname.c_str());
}
const timeit::TimePoint before_time = timeit::Clock::now();
Operation::evaluate();
const timeit::TimePoint after_time = timeit::Clock::now();
if (context().profiler()) {
context().profiler()->set_node_evaluation_time(node_.instance_key(), after_time - before_time);
}
if (context().use_gpu()) {
GPU_debug_group_end();
}
}
void NodeOperation::compute_preview()
{
if (bool(context().needed_outputs() & OutputTypes::Previews) && is_node_preview_needed(node())) {
const Result *result = get_preview_result();
if (result) {
compositor::compute_preview(context(), node(), *result);
}
}
}
Result *NodeOperation::get_preview_result()
{
/* Find the first linked output. */
for (const bNodeSocket *output : node()->output_sockets()) {
if (!output->is_available()) {
continue;
}
Result &output_result = get_result(output->identifier);
if (output_result.should_compute()) {
return &output_result;
}
}
/* No linked outputs, but no inputs either, so nothing to preview. */
if (node()->input_sockets().is_empty()) {
return nullptr;
}
/* Find the first allocated input. */
for (const bNodeSocket *input : node()->input_sockets()) {
if (!input->is_available()) {
continue;
}
Result &input_result = get_input(input->identifier);
if (input_result.is_allocated()) {
return &input_result;
}
}
BLI_assert_unreachable();
return nullptr;
}
void NodeOperation::compute_results_reference_counts(const Schedule &schedule)
{
for (const bNodeSocket *output : this->node()->output_sockets()) {
if (!output->is_available()) {
continue;
}
const DOutputSocket doutput{node().context(), output};
const int reference_count = number_of_inputs_linked_to_output_conditioned(
doutput, [&](DInputSocket input) { return schedule.contains(input.node()); });
get_result(doutput->identifier).set_reference_count(reference_count);
}
}
const DNode &NodeOperation::node() const
{
return node_;
}
const bNode &NodeOperation::bnode() const
{
return *node_;
}
bool NodeOperation::should_compute_output(StringRef identifier)
{
return get_result(identifier).should_compute();
}
} // namespace blender::compositor