38using namespace nodes::derived_node_tree_types;
60 result.allocate_texture(domain);
66 bind_material_resources(shader);
79void ShaderOperation::bind_material_resources(GPUShader *shader)
98void ShaderOperation::bind_inputs(GPUShader *shader)
108void ShaderOperation::bind_outputs(GPUShader *shader)
115void ShaderOperation::construct_material(
void *thunk, GPUMaterial *material)
118 operation->material_ = material;
119 for (DNode node : operation->compile_unit_) {
120 operation->shader_nodes_.add_new(node, std::make_unique<ShaderNode>(node));
122 operation->link_node_inputs(node);
124 operation->shader_nodes_.lookup(node)->compile(material);
126 operation->populate_results_for_node(node);
130void ShaderOperation::link_node_inputs(
DNode node)
132 for (
int i = 0;
i < node->input_sockets().
size();
i++) {
133 const DInputSocket
input{node.context(), node->input_sockets()[
i]};
138 this->link_node_input_unavailable(
input);
144 if (origin->is_input()) {
150 this->link_node_input_constant(
input, DInputSocket(origin));
153 this->link_node_input_implicit(
input, DInputSocket(origin));
159 const DOutputSocket
output = DOutputSocket(origin);
177 ShaderNode &node = *shader_nodes_.lookup(
input.node());
178 GPUNodeStack &stack = node.get_input(
input->identifier);
192 switch (
input->type) {
195 stack.
vec[0] = value;
201 stack.
vec[0] = int(value);
207 stack.
vec[0] = float(value);
255void ShaderOperation::link_node_input_constant(
const DInputSocket
input,
const DInputSocket origin)
269void ShaderOperation::link_node_input_implicit(
const DInputSocket
input,
const DInputSocket origin)
275 const ImplicitInput implicit_input = origin_descriptor.implicit_input;
280 input_descriptor.type = origin_descriptor.type;
281 input_descriptor.implicit_input = implicit_input;
285 if (implicit_input_to_material_attribute_map_.
contains(implicit_input)) {
292 existing_input_descriptor.domain_priority =
math::min(
293 existing_input_descriptor.domain_priority, input_descriptor.domain_priority);
297 stack.
link = implicit_input_to_material_attribute_map_.
lookup(implicit_input);
302 const std::string input_identifier =
"implicit_input" + std::to_string(implicit_input_index);
312 GPUNodeLink *attribute_link;
319 implicit_input_to_material_attribute_map_.add(implicit_input, attribute_link);
323 stack.
link = attribute_link;
326void ShaderOperation::link_node_input_internal(
DInputSocket input_socket,
329 ShaderNode &output_node = *shader_nodes_.lookup(output_socket.node());
330 GPUNodeStack &output_stack = output_node.get_output(output_socket->identifier);
332 ShaderNode &input_node = *shader_nodes_.lookup(input_socket.node());
333 GPUNodeStack &input_stack = input_node.get_input(input_socket->identifier);
335 input_stack.
link = output_stack.
link;
338void ShaderOperation::link_node_input_external(
DInputSocket input_socket,
342 ShaderNode &node = *shader_nodes_.lookup(input_socket.node());
343 GPUNodeStack &stack = node.get_input(input_socket->identifier);
345 if (!output_to_material_attribute_map_.contains(output_socket)) {
347 declare_operation_input(input_socket, output_socket);
357 input_descriptor.domain_priority =
math::min(
358 input_descriptor.domain_priority,
367 stack.
link = output_to_material_attribute_map_.lookup(output_socket);
370void ShaderOperation::declare_operation_input(
DInputSocket input_socket,
373 const int input_index = output_to_material_attribute_map_.size();
374 std::string input_identifier =
"input" + std::to_string(input_index);
386 GPUNodeLink *attribute_link;
393 output_to_material_attribute_map_.add(output_socket, attribute_link);
406void ShaderOperation::populate_results_for_node(
DNode node)
411 const DOutputSocket doutput{node.context(),
output};
425 const bool is_preview_output = doutput == preview_output;
426 if (is_preview_output) {
430 if (is_operation_output || is_preview_output) {
431 populate_operation_result(doutput);
440 return "node_compositor_store_output_float";
442 return "node_compositor_store_output_int";
444 return "node_compositor_store_output_bool";
446 return "node_compositor_store_output_float3";
448 return "node_compositor_store_output_color";
450 return "node_compositor_store_output_float4";
452 return "node_compositor_store_output_float2";
454 return "node_compositor_store_output_int2";
461void ShaderOperation::populate_operation_result(DOutputSocket output_socket)
464 std::string output_identifier =
"output" + std::to_string(output_id);
473 ShaderNode &node = *shader_nodes_.lookup(output_socket.node());
474 GPUNodeLink *output_link = node.get_output(output_socket->identifier).link;
485 GPU_link(material_, store_function_name, id_link, output_link, &storer_output_link);
492using namespace gpu::shader;
494void ShaderOperation::generate_code(
void *thunk,
506 shader_create_info.
typedef_source(
"gpu_shader_compositor_type_conversion.glsl");
512 shader_create_info.
compute_source(
"gpu_shader_compositor_main.glsl");
521 operation->generate_code_for_outputs(shader_create_info);
525 operation->generate_code_for_inputs(material, shader_create_info);
538 return "vec4(value)";
542 return "ivec4(int(value))";
546 return "ivec4(bool(value))";
548 return "vec4(value, 0.0)";
556 return "vec4(value.xy, 0.0, 0.0)";
560 return "ivec4(ivec2(value.xy), 0, 0)";
575 return ImageType::Float2D;
579 return ImageType::Int2D;
583 return ImageType::Float2D;
586void ShaderOperation::generate_code_for_outputs(
ShaderCreateInfo &shader_create_info)
588 const std::string store_float_function_header =
"void store_float(const uint id, float value)";
590 const std::string store_int_function_header =
"void store_int(const uint id, float value)";
592 const std::string store_bool_function_header =
"void store_bool(const uint id, float value)";
593 const std::string store_float3_function_header =
"void store_float3(const uint id, vec3 value)";
594 const std::string store_color_function_header =
"void store_color(const uint id, vec4 value)";
595 const std::string store_float4_function_header =
"void store_float4(const uint id, vec4 value)";
597 const std::string store_float2_function_header =
"void store_float2(const uint id, vec3 value)";
599 const std::string store_int2_function_header =
"void store_int2(const uint id, vec3 value)";
618 std::stringstream store_float_function;
619 std::stringstream store_int_function;
620 std::stringstream store_bool_function;
621 std::stringstream store_float3_function;
622 std::stringstream store_color_function;
623 std::stringstream store_float4_function;
624 std::stringstream store_float2_function;
625 std::stringstream store_int2_function;
626 const std::string store_function_start =
"\n{\n switch (id) {\n";
627 store_float_function << store_float_function_header << store_function_start;
628 store_int_function << store_int_function_header << store_function_start;
629 store_bool_function << store_bool_function_header << store_function_start;
630 store_float3_function << store_float3_function_header << store_function_start;
631 store_color_function << store_color_function_header << store_function_start;
632 store_float4_function << store_float4_function_header << store_function_start;
633 store_float2_function << store_float2_function_header << store_function_start;
634 store_int2_function << store_int2_function_header << store_function_start;
636 int output_index = 0;
641 shader_create_info.
image(output_index,
642 result.get_gpu_texture_format(),
650 std::stringstream case_code;
652 const std::string texel =
", ivec2(gl_GlobalInvocationID.xy), ";
654 <<
" imageStore(" << output_identifier << texel << store_expression <<
");\n"
660 store_float_function << case_code.str();
663 store_int_function << case_code.str();
666 store_bool_function << case_code.str();
669 store_float3_function << case_code.str();
672 store_color_function << case_code.str();
675 store_float4_function << case_code.str();
678 store_float2_function << case_code.str();
681 store_int2_function << case_code.str();
687 const std::string store_function_end =
" }\n}\n\n";
688 store_float_function << store_function_end;
689 store_int_function << store_function_end;
690 store_bool_function << store_function_end;
691 store_float3_function << store_function_end;
692 store_color_function << store_function_end;
693 store_float4_function << store_function_end;
694 store_float2_function << store_function_end;
695 store_int2_function << store_function_end;
698 store_float_function.str() + store_int_function.str() + store_bool_function.str() +
699 store_float3_function.str() + store_color_function.str() + store_float4_function.str() +
700 store_float2_function.str() + store_int2_function.str();
758void ShaderOperation::generate_code_for_inputs(
GPUMaterial *material,
775 shader_create_info.
sampler(input_slot_location,
779 input_slot_location++;
785 std::stringstream declare_attributes;
786 declare_attributes <<
"struct {\n";
790 declare_attributes <<
" " << type <<
" v" << attribute->id <<
";\n";
792 declare_attributes <<
"} var_attrs;\n\n";
798 shader_create_info.
typedef_source(
"gpu_shader_compositor_texture_utilities.glsl");
802 std::stringstream initialize_attributes;
807 initialize_attributes <<
"var_attrs.v" << attribute->id <<
" = " << type <<
"("
808 <<
"texture_load(" << attribute->name
809 <<
", ivec2(gl_GlobalInvocationID.xy))." << swizzle <<
")"
812 initialize_attributes <<
"\n";
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v4(float r[4])
struct bNodeSocket bNodeSocket
eGPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
GPUNodeLink * GPU_constant(const float *num)
ListBase GPU_material_attributes(const GPUMaterial *material)
void GPU_material_free_single(GPUMaterial *material)
GPUShader * GPU_material_get_shader(GPUMaterial *material)
ListBase GPU_material_textures(GPUMaterial *material)
void GPU_material_add_output_link_composite(GPUMaterial *material, GPUNodeLink *link)
GPUMaterial * GPU_material_from_callbacks(eGPUMaterialEngine engine, ConstructGPUMaterialFn construct_function_cb, GPUCodegenCallbackFn generate_code_function_cb, void *thunk)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUUniformBuf * GPU_material_uniform_buffer_get(GPUMaterial *material)
GPUNodeLink * GPU_uniform(const float *num)
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_texture_bind(GPUTexture *texture, int unit)
void GPU_texture_image_unbind_all()
void GPU_texture_unbind_all()
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
ValueIterator values() const &
const Value & lookup(const Key &key) const
void add_new(const Key &key, const Value &value)
bool contains(const Key &key) const
constexpr StringRef drop_known_prefix(StringRef prefix) const
Result create_result(ResultType type, ResultPrecision precision)
Result & get_result(StringRef identifier)
void populate_result(StringRef identifier, Result result)
Context & context() const
Result & get_input(StringRef identifier) const
virtual Domain compute_domain()
InputDescriptor & get_input_descriptor(StringRef identifier)
void declare_input_descriptor(StringRef identifier, InputDescriptor descriptor)
Map< DOutputSocket, std::string > outputs_to_declared_inputs_map_
Map< std::string, DOutputSocket > inputs_to_linked_outputs_map_
Map< std::string, int > inputs_to_reference_counts_map_
const Schedule & schedule_
VectorSet< DOutputSocket > preview_outputs_
Map< DOutputSocket, std::string > output_sockets_to_output_identifiers_map_
PixelOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
PixelCompileUnit compile_unit_
Map< ImplicitInput, std::string > implicit_inputs_to_input_identifiers_map_
void bind_as_texture(GPUShader *shader, const char *texture_name) const
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
ShaderOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
~ShaderOperation() override
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
static void initialize_input_stack_value(const DInputSocket input, GPUNodeStack &stack)
bool is_output_linked_to_node_conditioned(DOutputSocket output, FunctionRef< bool(DNode)> condition)
DSocket get_input_origin_socket(DInputSocket input)
VectorSet< DNode > Schedule
static const char * glsl_store_expression_from_result_type(ResultType type)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
static const char * glsl_swizzle_from_result_type(ResultType type)
static ImageType gpu_image_type_from_result_type(const ResultType type)
VectorSet< DNode > PixelCompileUnit
static const char * glsl_type_from_result_type(ResultType type)
DOutputSocket find_preview_output_socket(const DNode &node)
ResultType get_node_socket_result_type(const bNodeSocket *socket)
InputDescriptor input_descriptor_from_input_socket(const bNodeSocket *socket)
static const char * get_store_function_name(ResultType type)
bool is_socket_available(const bNodeSocket *socket)
static const char * get_set_function_name(const ResultType type)
T min(const T &a, const T &b)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
GPUShaderCreateInfo * create_info
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Self & compute_source(StringRefNull filename)
Self & image(int slot, eGPUTextureFormat format, Qualifier qualifiers, ImageReadWriteType type, StringRefNull name, Frequency freq=Frequency::PASS)
Self & typedef_source(StringRefNull filename)
std::string typedef_source_generated
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, GPUSamplerState sampler=GPUSamplerState::internal_sampler())
std::string compute_source_generated
Self & local_group_size(int local_size_x, int local_size_y=1, int local_size_z=1)