Files
test/source/blender/compositor/algorithms/intern/pad.cc
Omar Emara 0e304c813c Refactor: Use Float2 images internally if possible
Previously, Float2 images were internally stored as either Float3 or
Float4 images due to limitations in the implementation, which no longer
exists. So this patch refactors the compositor code to store Float2
images in actual Float2 containers, which gives better performance and
memory savings.

Some algorithms were adjusted to operate on Float2 instead of Float3 as
was previously the case.

Pull Request: https://projects.blender.org/blender/blender/pulls/140855
2025-06-23 14:34:37 +02:00

127 lines
3.3 KiB
C++

/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "GPU_shader.hh"
#include "COM_context.hh"
#include "COM_result.hh"
#include "COM_utilities.hh"
#include "COM_algorithm_pad.hh"
namespace blender::compositor {
static const char *get_shader_name(const ResultType type, const PaddingMethod padding_method)
{
switch (padding_method) {
case PaddingMethod::Zero:
switch (type) {
case ResultType::Color:
return "compositor_pad_zero_float4";
default:
break;
}
break;
case PaddingMethod::Extend:
switch (type) {
case ResultType::Float2:
return "compositor_pad_extend_float2";
case ResultType::Float:
return "compositor_pad_extend_float";
default:
break;
}
break;
}
BLI_assert_unreachable();
return "";
}
static void zero_pad_gpu(Context &context,
const Result &input,
Result &output,
const int2 size,
const PaddingMethod padding_method)
{
GPUShader *shader = context.get_shader(get_shader_name(input.type(), padding_method));
GPU_shader_bind(shader);
GPU_shader_uniform_2iv(shader, "size", size);
input.bind_as_texture(shader, "input_tx");
Domain extended_domain = input.domain();
extended_domain.size += size * 2;
output.allocate_texture(extended_domain);
output.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, extended_domain.size);
GPU_shader_unbind();
input.unbind_as_texture();
output.unbind_as_image();
}
static void zero_pad_cpu(const Result &input,
Result &output,
const int2 size,
const PaddingMethod padding_method)
{
Domain extended_domain = input.domain();
extended_domain.size += size * 2;
output.allocate_texture(extended_domain);
switch (padding_method) {
case PaddingMethod::Zero:
switch (input.type()) {
case ResultType::Color:
parallel_for(extended_domain.size, [&](const int2 texel) {
output.store_pixel(texel, input.load_pixel_zero<float4>(texel - size));
});
break;
default:
BLI_assert_unreachable();
}
break;
case PaddingMethod::Extend:
switch (input.type()) {
case ResultType::Float:
parallel_for(extended_domain.size, [&](const int2 texel) {
output.store_pixel(texel, input.load_pixel_extended<float>(texel - size));
});
break;
case ResultType::Float2:
parallel_for(extended_domain.size, [&](const int2 texel) {
output.store_pixel(texel, input.load_pixel_extended<float2>(texel - size));
});
break;
default:
BLI_assert_unreachable();
}
break;
}
}
void pad(Context &context,
const Result &input,
Result &output,
const int2 size,
const PaddingMethod padding_method)
{
if (input.is_single_value()) {
output.share_data(input);
return;
}
if (context.use_gpu()) {
zero_pad_gpu(context, input, output, size, padding_method);
}
else {
zero_pad_cpu(input, output, size, padding_method);
}
}
} // namespace blender::compositor