Compositor: Implement type conversion in new CPU compositor
This patch implements implicit conversion operations for the new CPU compositor.
This commit is contained in:
@@ -13,19 +13,18 @@
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Conversion Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Conversion Operation
|
||||
*
|
||||
* A simple operation that converts a result from a certain type to another. See the derived
|
||||
* classes for more details.
|
||||
* \{ */
|
||||
|
||||
* classes for more details. */
|
||||
class ConversionOperation : public SimpleOperation {
|
||||
public:
|
||||
using SimpleOperation::SimpleOperation;
|
||||
|
||||
/* If the input result is a single value, execute_single is called. Otherwise, the shader
|
||||
* provided by get_conversion_shader is dispatched. */
|
||||
* provided by get_conversion_shader is dispatched for GPU contexts or execute_cpu is called for
|
||||
* CPU contexts. */
|
||||
void execute() override;
|
||||
|
||||
/* Determine if a conversion operation is needed for the input with the given result and
|
||||
@@ -39,119 +38,107 @@ class ConversionOperation : public SimpleOperation {
|
||||
/* Convert the input single value result to the output single value result. */
|
||||
virtual void execute_single(const Result &input, Result &output) = 0;
|
||||
|
||||
/* Convert the input to the appropriate type and write the result to the output on the CPU. */
|
||||
virtual void execute_cpu(const Result &input, Result &output) = 0;
|
||||
|
||||
/* Get the shader the will be used for conversion. */
|
||||
virtual GPUShader *get_conversion_shader() const = 0;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
}; // namespace blender::realtime_compositorclassConversionOperation:publicSimpleOperation
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Float to Vector Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Float to Vector Operation
|
||||
*
|
||||
* Takes a float result and outputs a vector result. The first three components of the output are
|
||||
* filled with the input float, while the fourth component is set to 1.
|
||||
* \{ */
|
||||
|
||||
* filled with the input float, while the fourth component is set to 1. */
|
||||
class ConvertFloatToVectorOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertFloatToVectorOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Float to Color Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Float to Color Operation
|
||||
*
|
||||
* Takes a float result and outputs a color result. All three color channels of the output are
|
||||
* filled with the input float and the alpha channel is set to 1.
|
||||
* \{ */
|
||||
|
||||
* filled with the input float and the alpha channel is set to 1. */
|
||||
class ConvertFloatToColorOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertFloatToColorOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Color to Float Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Color to Float Operation
|
||||
*
|
||||
* Takes a color result and outputs a float result. The output is the average of the three color
|
||||
* channels, the alpha channel is ignored.
|
||||
* \{ */
|
||||
|
||||
* channels, the alpha channel is ignored. */
|
||||
class ConvertColorToFloatOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertColorToFloatOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Color to Vector Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Color to Vector Operation
|
||||
*
|
||||
* Takes a color result and outputs a vector result. The output is an exact copy of the input since
|
||||
* vectors are 4D.
|
||||
* \{ */
|
||||
|
||||
* vectors are 4D. */
|
||||
class ConvertColorToVectorOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertColorToVectorOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Vector to Float Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Vector to Float Operation
|
||||
*
|
||||
* Takes a vector result and outputs a float result. The output is the average of the three
|
||||
* components.
|
||||
* \{ */
|
||||
|
||||
*components. */
|
||||
class ConvertVectorToFloatOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertVectorToFloatOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Vector to Color Operation
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Vector to Color Operation
|
||||
*
|
||||
* Takes a vector result and outputs a color result. The output is a copy of the three vector
|
||||
* components to the three color channels with the alpha channel set to 1.
|
||||
* \{ */
|
||||
|
||||
* components to the three color channels with the alpha channel set to 1. */
|
||||
class ConvertVectorToColorOperation : public ConversionOperation {
|
||||
public:
|
||||
ConvertVectorToColorOperation(Context &context);
|
||||
|
||||
void execute_single(const Result &input, Result &output) override;
|
||||
|
||||
void execute_cpu(const Result &input, Result &output) override;
|
||||
|
||||
GPUShader *get_conversion_shader() const override;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Conversion Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Conversion Operation
|
||||
*/
|
||||
|
||||
void ConversionOperation::execute()
|
||||
{
|
||||
@@ -25,23 +25,27 @@ void ConversionOperation::execute()
|
||||
|
||||
if (input.is_single_value()) {
|
||||
result.allocate_single_value();
|
||||
execute_single(input, result);
|
||||
this->execute_single(input, result);
|
||||
return;
|
||||
}
|
||||
|
||||
result.allocate_texture(input.domain());
|
||||
if (context().use_gpu()) {
|
||||
GPUShader *shader = get_conversion_shader();
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
GPUShader *shader = get_conversion_shader();
|
||||
GPU_shader_bind(shader);
|
||||
input.bind_as_texture(shader, "input_tx");
|
||||
result.bind_as_image(shader, "output_img");
|
||||
|
||||
input.bind_as_texture(shader, "input_tx");
|
||||
result.bind_as_image(shader, "output_img");
|
||||
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||
|
||||
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||
|
||||
input.unbind_as_texture();
|
||||
result.unbind_as_image();
|
||||
GPU_shader_unbind();
|
||||
input.unbind_as_texture();
|
||||
result.unbind_as_image();
|
||||
GPU_shader_unbind();
|
||||
}
|
||||
else {
|
||||
this->execute_cpu(input, result);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleOperation *ConversionOperation::construct_if_needed(Context &context,
|
||||
@@ -81,11 +85,9 @@ SimpleOperation *ConversionOperation::construct_if_needed(Context &context,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Float to Vector Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Float to Vector Operation
|
||||
*/
|
||||
|
||||
ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -101,16 +103,21 @@ void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &
|
||||
output.set_vector_value(float4(float3(input.get_float_value()), 1.0f));
|
||||
}
|
||||
|
||||
void ConvertFloatToVectorOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size, [&](const int2 texel) {
|
||||
output.store_pixel(texel, float4(float3(input.load_pixel(texel).x), 1.0f));
|
||||
});
|
||||
}
|
||||
|
||||
GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
|
||||
{
|
||||
return context().get_shader("compositor_convert_float_to_vector");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Float to Color Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Float to Color Operation
|
||||
*/
|
||||
|
||||
ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -123,9 +130,14 @@ ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context)
|
||||
|
||||
void ConvertFloatToColorOperation::execute_single(const Result &input, Result &output)
|
||||
{
|
||||
float4 color = float4(input.get_float_value());
|
||||
color[3] = 1.0f;
|
||||
output.set_color_value(color);
|
||||
output.set_color_value(float4(float3(input.get_float_value()), 1.0f));
|
||||
}
|
||||
|
||||
void ConvertFloatToColorOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size, [&](const int2 texel) {
|
||||
output.store_pixel(texel, float4(float3(input.load_pixel(texel).x), 1.0f));
|
||||
});
|
||||
}
|
||||
|
||||
GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const
|
||||
@@ -133,11 +145,9 @@ GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const
|
||||
return context().get_shader("compositor_convert_float_to_color");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Color to Float Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Color to Float Operation
|
||||
*/
|
||||
|
||||
ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -151,7 +161,15 @@ ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context)
|
||||
void ConvertColorToFloatOperation::execute_single(const Result &input, Result &output)
|
||||
{
|
||||
float4 color = input.get_color_value();
|
||||
output.set_float_value((color[0] + color[1] + color[2]) / 3.0f);
|
||||
output.set_float_value((color.x + color.y + color.z) / 3.0f);
|
||||
}
|
||||
|
||||
void ConvertColorToFloatOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size, [&](const int2 texel) {
|
||||
const float4 color = input.load_pixel(texel);
|
||||
output.store_pixel(texel, float4((color.x + color.y + color.z) / 3.0f));
|
||||
});
|
||||
}
|
||||
|
||||
GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const
|
||||
@@ -159,11 +177,9 @@ GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const
|
||||
return context().get_shader("compositor_convert_color_to_float");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Color to Vector Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Color to Vector Operation
|
||||
*/
|
||||
|
||||
ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -180,16 +196,20 @@ void ConvertColorToVectorOperation::execute_single(const Result &input, Result &
|
||||
output.set_vector_value(color);
|
||||
}
|
||||
|
||||
void ConvertColorToVectorOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size,
|
||||
[&](const int2 texel) { output.store_pixel(texel, input.load_pixel(texel)); });
|
||||
}
|
||||
|
||||
GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
|
||||
{
|
||||
return context().get_shader("compositor_convert_color_to_vector");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Vector to Float Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Vector to Float Operation
|
||||
*/
|
||||
|
||||
ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -206,16 +226,22 @@ void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &
|
||||
output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f);
|
||||
}
|
||||
|
||||
void ConvertVectorToFloatOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size, [&](const int2 texel) {
|
||||
const float4 vector = input.load_pixel(texel);
|
||||
output.store_pixel(texel, float4((vector.x + vector.y + vector.z) / 3.0f));
|
||||
});
|
||||
}
|
||||
|
||||
GPUShader *ConvertVectorToFloatOperation::get_conversion_shader() const
|
||||
{
|
||||
return context().get_shader("compositor_convert_vector_to_float");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert Vector to Color Operation
|
||||
* \{ */
|
||||
/* --------------------------------------------------------------------
|
||||
* Convert Vector to Color Operation
|
||||
*/
|
||||
|
||||
ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
|
||||
: ConversionOperation(context)
|
||||
@@ -231,11 +257,16 @@ void ConvertVectorToColorOperation::execute_single(const Result &input, Result &
|
||||
output.set_color_value(float4(float3(input.get_vector_value()), 1.0f));
|
||||
}
|
||||
|
||||
void ConvertVectorToColorOperation::execute_cpu(const Result &input, Result &output)
|
||||
{
|
||||
parallel_for(input.domain().size, [&](const int2 texel) {
|
||||
output.store_pixel(texel, float4(input.load_pixel(texel).xyz(), 1.0f));
|
||||
});
|
||||
}
|
||||
|
||||
GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const
|
||||
{
|
||||
return context().get_shader("compositor_convert_vector_to_color");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
Reference in New Issue
Block a user