38using namespace nodes::derived_node_tree_types;
60 result.allocate_texture(domain);
66 bind_material_resources(shader);
79void ShaderOperation::bind_material_resources(
gpu::Shader *shader)
98void ShaderOperation::bind_inputs(gpu::Shader *shader)
108void ShaderOperation::bind_outputs(gpu::Shader *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);
223 stack.
vec[0] = int(value);
274void ShaderOperation::link_node_input_constant(
const DInputSocket
input,
const DInputSocket origin)
291void ShaderOperation::link_node_input_implicit(
const DInputSocket
input,
const DInputSocket origin)
297 const ImplicitInput implicit_input = origin_descriptor.implicit_input;
302 input_descriptor.type = origin_descriptor.type;
303 input_descriptor.implicit_input = implicit_input;
307 if (implicit_input_to_material_attribute_map_.
contains(implicit_input)) {
314 existing_input_descriptor.domain_priority =
math::min(
315 existing_input_descriptor.domain_priority, input_descriptor.domain_priority);
319 stack.
link = implicit_input_to_material_attribute_map_.
lookup(implicit_input);
324 const std::string input_identifier =
"implicit_input" + std::to_string(implicit_input_index);
334 GPUNodeLink *attribute_link;
341 implicit_input_to_material_attribute_map_.add(implicit_input, attribute_link);
345 stack.
link = attribute_link;
348void ShaderOperation::link_node_input_internal(
DInputSocket input_socket,
351 ShaderNode &output_node = *shader_nodes_.lookup(output_socket.node());
352 GPUNodeStack &output_stack = output_node.get_output(output_socket->identifier);
354 ShaderNode &input_node = *shader_nodes_.lookup(input_socket.node());
355 GPUNodeStack &input_stack = input_node.get_input(input_socket->identifier);
357 input_stack.
link = output_stack.
link;
360void ShaderOperation::link_node_input_external(
DInputSocket input_socket,
364 ShaderNode &node = *shader_nodes_.lookup(input_socket.node());
365 GPUNodeStack &stack = node.get_input(input_socket->identifier);
367 if (!output_to_material_attribute_map_.contains(output_socket)) {
369 declare_operation_input(input_socket, output_socket);
379 input_descriptor.domain_priority =
math::min(
380 input_descriptor.domain_priority,
389 stack.
link = output_to_material_attribute_map_.lookup(output_socket);
392void ShaderOperation::declare_operation_input(
DInputSocket input_socket,
395 const int input_index = output_to_material_attribute_map_.size();
396 std::string input_identifier =
"input" + std::to_string(input_index);
408 GPUNodeLink *attribute_link;
415 output_to_material_attribute_map_.add(output_socket, attribute_link);
428void ShaderOperation::populate_results_for_node(
DNode node)
433 const DOutputSocket doutput{node.context(),
output};
447 const bool is_preview_output = doutput == preview_output;
448 if (is_preview_output) {
452 if (is_operation_output || is_preview_output) {
453 populate_operation_result(doutput);
462 return "node_compositor_store_output_float";
464 return "node_compositor_store_output_int";
466 return "node_compositor_store_output_bool";
468 return "node_compositor_store_output_float3";
470 return "node_compositor_store_output_color";
472 return "node_compositor_store_output_float4";
474 return "node_compositor_store_output_float2";
476 return "node_compositor_store_output_int2";
478 return "node_compositor_store_output_menu";
490void ShaderOperation::populate_operation_result(DOutputSocket output_socket)
493 std::string output_identifier =
"output" + std::to_string(output_id);
502 ShaderNode &node = *shader_nodes_.lookup(output_socket.node());
503 GPUNodeLink *output_link = node.get_output(output_socket->identifier).link;
514 GPU_link(material_, store_function_name, id_link, output_link, &storer_output_link);
521using namespace gpu::shader;
523void ShaderOperation::generate_code(
void *thunk,
535 shader_create_info.
typedef_source(
"gpu_shader_compositor_type_conversion.glsl");
541 shader_create_info.
compute_source(
"gpu_shader_compositor_main.glsl");
543 std::string store_code = operation->generate_code_for_outputs(shader_create_info);
545 {
"gpu_shader_compositor_store.glsl", {}, store_code});
547 std::string eval_code;
548 eval_code +=
"void evaluate()\n{\n";
550 eval_code += operation->generate_code_for_inputs(material, shader_create_info);
567 return "vec4(value)";
571 return "ivec4(int(value))";
575 return "ivec4(bool(value))";
577 return "vec4(value, 0.0)";
585 return "vec4(value.xy, 0.0, 0.0)";
589 return "ivec4(ivec2(value.xy), 0, 0)";
593 return "ivec4(int(value))";
613 return ImageType::Float2D;
618 return ImageType::Int2D;
627 return ImageType::Float2D;
630std::string ShaderOperation::generate_code_for_outputs(
ShaderCreateInfo &shader_create_info)
632 const std::string store_float_function_header =
"void store_float(const uint id, float value)";
634 const std::string store_int_function_header =
"void store_int(const uint id, float value)";
636 const std::string store_bool_function_header =
"void store_bool(const uint id, float value)";
637 const std::string store_float3_function_header =
"void store_float3(const uint id, vec3 value)";
638 const std::string store_color_function_header =
"void store_color(const uint id, vec4 value)";
639 const std::string store_float4_function_header =
"void store_float4(const uint id, vec4 value)";
641 const std::string store_float2_function_header =
"void store_float2(const uint id, vec3 value)";
643 const std::string store_int2_function_header =
"void store_int2(const uint id, vec3 value)";
645 const std::string store_menu_function_header =
"void store_menu(const uint id, float value)";
650 std::stringstream store_float_function;
651 std::stringstream store_int_function;
652 std::stringstream store_bool_function;
653 std::stringstream store_float3_function;
654 std::stringstream store_color_function;
655 std::stringstream store_float4_function;
656 std::stringstream store_float2_function;
657 std::stringstream store_int2_function;
658 std::stringstream store_menu_function;
659 const std::string store_function_start =
"\n{\n switch (id) {\n";
660 store_float_function << store_float_function_header << store_function_start;
661 store_int_function << store_int_function_header << store_function_start;
662 store_bool_function << store_bool_function_header << store_function_start;
663 store_float3_function << store_float3_function_header << store_function_start;
664 store_color_function << store_color_function_header << store_function_start;
665 store_float4_function << store_float4_function_header << store_function_start;
666 store_float2_function << store_float2_function_header << store_function_start;
667 store_int2_function << store_int2_function_header << store_function_start;
668 store_menu_function << store_menu_function_header << store_function_start;
670 int output_index = 0;
675 shader_create_info.
image(output_index,
676 result.get_gpu_texture_format(),
684 std::stringstream case_code;
686 const std::string texel =
", ivec2(gl_GlobalInvocationID.xy), ";
688 <<
" imageStore(" << output_identifier << texel << store_expression <<
");\n"
694 store_float_function << case_code.str();
697 store_int_function << case_code.str();
700 store_bool_function << case_code.str();
703 store_float3_function << case_code.str();
706 store_color_function << case_code.str();
709 store_float4_function << case_code.str();
712 store_float2_function << case_code.str();
715 store_int2_function << case_code.str();
718 store_menu_function << case_code.str();
729 const std::string store_function_end =
" }\n}\n\n";
730 store_float_function << store_function_end;
731 store_int_function << store_function_end;
732 store_bool_function << store_function_end;
733 store_float3_function << store_function_end;
734 store_color_function << store_function_end;
735 store_float4_function << store_function_end;
736 store_float2_function << store_function_end;
737 store_int2_function << store_function_end;
738 store_menu_function << store_function_end;
740 return store_float_function.str() + store_int_function.str() + store_bool_function.str() +
741 store_float3_function.str() + store_color_function.str() + store_float4_function.str() +
742 store_float2_function.str() + store_int2_function.str() + store_menu_function.str();
814std::string ShaderOperation::generate_code_for_inputs(
GPUMaterial *material,
833 shader_create_info.
sampler(input_slot_location,
837 input_slot_location++;
843 std::stringstream declare_attributes;
844 declare_attributes <<
"struct {\n";
848 declare_attributes <<
" " << type <<
" v" << attribute->id <<
";\n";
850 declare_attributes <<
"} var_attrs;\n\n";
852 code += declare_attributes.str();
856 shader_create_info.
typedef_source(
"gpu_shader_compositor_texture_utilities.glsl");
860 std::stringstream initialize_attributes;
865 initialize_attributes <<
"var_attrs.v" << attribute->id <<
" = " << type <<
"("
866 <<
"texture_load(" << attribute->name
867 <<
", ivec2(gl_GlobalInvocationID.xy))." << swizzle <<
")"
870 initialize_attributes <<
"\n";
872 code += initialize_attributes.str();
#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 zero_v4(float r[4])
struct bNodeSocket bNodeSocket
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)
blender::gpu::Shader * GPU_material_get_shader(GPUMaterial *material)
void GPU_material_free_single(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)
blender::gpu::UniformBuf * GPU_material_uniform_buffer_get(GPUMaterial *material)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUNodeLink * GPU_uniform(const float *num)
int GPU_shader_get_ubo_binding(blender::gpu::Shader *shader, const char *name)
int GPU_shader_get_sampler_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_texture_image_unbind_all()
void GPU_texture_unbind_all()
void GPU_texture_bind(blender::gpu::Texture *texture, int unit)
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_
static bool is_single_value_only_type(ResultType type)
void bind_as_texture(gpu::Shader *shader, const char *texture_name) const
void bind_as_image(gpu::Shader *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)
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
DSocket get_input_origin_socket(DInputSocket input)
VectorSet< DNode > Schedule
static const char * glsl_store_expression_from_result_type(ResultType type)
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
GPUShaderCreateInfo * create_info
blender::Vector< blender::StringRefNull > dependencies
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Self & compute_source(StringRefNull filename)
GeneratedSourceList generated_sources
Self & typedef_source(StringRefNull filename)
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, GPUSamplerState sampler=GPUSamplerState::internal_sampler())
Self & image(int slot, TextureFormat format, Qualifier qualifiers, ImageReadWriteType type, StringRefNull name, Frequency freq=Frequency::PASS)
Self & local_group_size(int local_size_x, int local_size_y=1, int local_size_z=1)