Realtime Compositor: Allow more result types

Previously, the Result class was reserved for inputs and outputs of
operations, so its allowed types were naturally those exposed to the
user. However, we now use the Result class internally for intermediate
results, so it now makes sense to expend the allowed types.

The types are now divided into two categories, those that are user
facing and need to be handled in implicit operations and those that
are internal and can be exempt from such handling. Internal types are
reserved for texture results, as the single value mechanism is only
useful for user facing results.

The patch merely adjusts the switch cases across the code base, adding
one new internal type as an example.

Pull Request: https://projects.blender.org/blender/blender/pulls/112414
This commit is contained in:
Omar Emara 2023-09-25 15:12:52 +02:00 committed by Omar Emara
parent b7fe84d9bc
commit 6b53fd5cf6
8 changed files with 110 additions and 26 deletions

@ -15,14 +15,22 @@
namespace blender::realtime_compositor {
/* Possible data types that operations can operate on. They either represent the base type of the
* result texture or a single value result. The color type represents an RGBA color. And the vector
* type represents a generic 4-component vector, which can encode two 2D vectors, one 3D vector
* with the last component ignored, or other dimensional data. */
enum class ResultType : uint8_t {
/* The following types are user facing and can be used as inputs and outputs of operations. They
* either represent the base type of the result texture or a single value result. The color type
* represents an RGBA color. And the vector type represents a generic 4-component vector, which
* can encode two 2D vectors, one 3D vector with the last component ignored, or other dimensional
* data. */
Float,
Vector,
Color,
/* The following types are for internal use only, not user facing, and can't be used as inputs
* and outputs of operations. Furthermore, they can't be single values and thus always need to be
* allocated as textures. It follows that they needn't be handled in implicit operations like
* type conversion, shader, or single value reduction operations. To add a new type, just add a
* new case in the get_texture_format() function. */
Int2,
};
enum class ResultPrecision : uint8_t {

@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "IMB_colormanagement.h"
#include "GPU_shader.h"
@ -17,6 +19,34 @@
namespace blender::realtime_compositor {
static void set_shader_luminance_coefficients(GPUShader *shader, ResultType type)
{
switch (type) {
case ResultType::Color: {
float luminance_coefficients[3];
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
return;
}
case ResultType::Vector: {
float luminance_coefficients[3] = {1.0f, 1.0f, 1.0f};
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
return;
}
case ResultType::Float: {
float luminance_coefficients[3] = {1.0f, 0.0f, 0.0f};
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
return;
}
case ResultType::Int2: {
/* SMAA does not support integer types. */
break;
}
}
BLI_assert_unreachable();
}
static Result detect_edges(Context &context,
Result &input,
float threshold,
@ -25,25 +55,7 @@ static Result detect_edges(Context &context,
GPUShader *shader = context.shader_manager().get("compositor_smaa_edge_detection");
GPU_shader_bind(shader);
switch (input.type()) {
case ResultType::Color: {
float luminance_coefficients[3];
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
break;
}
case ResultType::Vector: {
float luminance_coefficients[3] = {1.0f, 1.0f, 1.0f};
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
break;
}
case ResultType::Float: {
float luminance_coefficients[3] = {1.0f, 0.0f, 0.0f};
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
break;
}
}
set_shader_luminance_coefficients(shader, input.type());
GPU_shader_uniform_1f(shader, "smaa_threshold", threshold);
GPU_shader_uniform_1f(
shader, "smaa_local_contrast_adaptation_factor", local_contrast_adaptation_factor);

@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "BLI_math_base.hh"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
@ -21,11 +22,19 @@ namespace blender::realtime_compositor {
static const char *get_blur_shader(ResultType type)
{
if (type == ResultType::Float) {
return "compositor_symmetric_separable_blur_float";
switch (type) {
case ResultType::Float:
return "compositor_symmetric_separable_blur_float";
case ResultType::Vector:
case ResultType::Color:
return "compositor_symmetric_separable_blur_color";
case ResultType::Int2:
/* Blur does not support integer types. */
break;
}
return "compositor_symmetric_separable_blur_color";
BLI_assert_unreachable();
return nullptr;
}
static Result horizontal_pass(Context &context,

@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "BLI_math_vector_types.hh"
#include "COM_input_single_value_operation.hh"
@ -45,6 +46,10 @@ void InputSingleValueOperation::execute()
case ResultType::Color:
result.set_color_value(float4(bsocket->default_value_typed<bNodeSocketValueRGBA>()->value));
break;
default:
/* Other types are internal and needn't be handled by operations. */
BLI_assert_unreachable();
break;
}
}

@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "BLI_math_angle_types.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_matrix_types.hh"
@ -98,6 +99,10 @@ GPUShader *RealizeOnDomainOperation::get_realization_shader()
return shader_manager().get("compositor_realize_on_domain_bicubic_vector");
case ResultType::Float:
return shader_manager().get("compositor_realize_on_domain_bicubic_float");
default:
/* Other types are internal and needn't be handled by operations. */
BLI_assert_unreachable();
return nullptr;
}
}
else {
@ -108,6 +113,10 @@ GPUShader *RealizeOnDomainOperation::get_realization_shader()
return shader_manager().get("compositor_realize_on_domain_vector");
case ResultType::Float:
return shader_manager().get("compositor_realize_on_domain_float");
default:
/* Other types are internal and needn't be handled by operations. */
BLI_assert_unreachable();
return nullptr;
}
}

@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "GPU_state.h"
#include "GPU_texture.h"
@ -43,6 +45,10 @@ void ReduceToSingleValueOperation::execute()
case ResultType::Float:
result.set_float_value(*pixel);
break;
default:
/* Other types are internal and needn't be handled by operations. */
BLI_assert_unreachable();
break;
}
MEM_freeN(pixel);

@ -39,6 +39,8 @@ eGPUTextureFormat Result::get_texture_format() const
case ResultType::Vector:
case ResultType::Color:
return GPU_RGBA16F;
case ResultType::Int2:
return GPU_RG16I;
}
break;
case ResultPrecision::Full:
@ -48,6 +50,8 @@ eGPUTextureFormat Result::get_texture_format() const
case ResultType::Vector:
case ResultType::Color:
return GPU_RGBA32F;
case ResultType::Int2:
return GPU_RG32I;
}
break;
}
@ -93,6 +97,10 @@ void Result::allocate_invalid()
case ResultType::Color:
set_color_value(float4(0.0f));
break;
default:
/* Other types are internal and do not support single values. */
BLI_assert_unreachable();
break;
}
}
@ -162,6 +170,10 @@ void Result::steal_data(Result &source)
case ResultType::Color:
color_value_ = source.color_value_;
break;
default:
/* Other types are internal and do not support single values. */
BLI_assert_unreachable();
break;
}
source.texture_ = nullptr;

@ -5,6 +5,7 @@
#include <memory>
#include <string>
#include "BLI_assert.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_string_ref.hh"
@ -227,6 +228,9 @@ static const char *get_set_function_name(ResultType type)
return "set_rgb";
case ResultType::Color:
return "set_rgba";
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();
@ -312,6 +316,9 @@ static const char *get_store_function_name(ResultType type)
return "node_compositor_store_output_vector";
case ResultType::Color:
return "node_compositor_store_output_color";
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();
@ -402,6 +409,9 @@ static eGPUTextureFormat texture_format_from_result_type(ResultType type)
return GPU_RGBA16F;
case ResultType::Color:
return GPU_RGBA16F;
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();
@ -419,6 +429,9 @@ static const char *glsl_store_expression_from_result_type(ResultType type)
return "vec4(vector, 0.0)";
case ResultType::Color:
return "color";
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();
@ -482,6 +495,10 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
case ResultType::Color:
store_color_function << case_code.str();
break;
default:
/* Other types are internal and needn't be handled by operations. */
BLI_assert_unreachable();
break;
}
}
@ -505,6 +522,9 @@ static const char *glsl_type_from_result_type(ResultType type)
return "vec3";
case ResultType::Color:
return "vec4";
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();
@ -522,6 +542,9 @@ static const char *glsl_swizzle_from_result_type(ResultType type)
return "xyz";
case ResultType::Color:
return "rgba";
default:
/* Other types are internal and needn't be handled by operations. */
break;
}
BLI_assert_unreachable();