40using namespace nodes::derived_node_tree_types;
63 result.allocate_texture(domain);
69 bind_material_resources(shader);
81void ShaderOperation::bind_material_resources(
GPUShader *shader)
93 if (texture->colorband) {
100void ShaderOperation::bind_inputs(
GPUShader *shader)
110void ShaderOperation::bind_outputs(
GPUShader *shader)
117void ShaderOperation::construct_material(
void *thunk,
GPUMaterial *material)
122 ShaderNode *shader_node = node->typeinfo->get_compositor_shader_node(node);
123 operation->shader_nodes_.add_new(node, std::unique_ptr<ShaderNode>(shader_node));
125 operation->link_node_inputs(node);
127 shader_node->
compile(material);
129 operation->populate_results_for_node(node);
133void ShaderOperation::link_node_inputs(DNode node)
135 for (
const bNodeSocket *input : node->input_sockets()) {
136 const DInputSocket dinput{node.context(), input};
148 link_node_input_internal(dinput, doutput);
155 link_node_input_external(dinput, doutput);
159void ShaderOperation::link_node_input_internal(DInputSocket input_socket,
160 DOutputSocket output_socket)
162 ShaderNode &output_node = *shader_nodes_.lookup(output_socket.node());
163 GPUNodeStack &output_stack = output_node.get_output(output_socket->identifier);
165 ShaderNode &input_node = *shader_nodes_.lookup(input_socket.node());
166 GPUNodeStack &input_stack = input_node.get_input(input_socket->identifier);
168 input_stack.
link = output_stack.
link;
171void ShaderOperation::link_node_input_external(DInputSocket input_socket,
172 DOutputSocket output_socket)
175 ShaderNode &node = *shader_nodes_.lookup(input_socket.node());
176 GPUNodeStack &stack = node.get_input(input_socket->identifier);
178 if (!output_to_material_attribute_map_.
contains(output_socket)) {
180 declare_operation_input(input_socket, output_socket);
188 const std::string input_identifier = outputs_to_declared_inputs_map_.
lookup(output_socket);
190 input_descriptor.domain_priority =
math::min(
191 input_descriptor.domain_priority,
197 stack.
link = output_to_material_attribute_map_.
lookup(output_socket);
218void ShaderOperation::declare_operation_input(DInputSocket input_socket,
219 DOutputSocket output_socket)
221 const int input_index = output_to_material_attribute_map_.
size();
222 std::string input_identifier =
"input" + std::to_string(input_index);
241 output_to_material_attribute_map_.
add(output_socket, attribute_link);
247 outputs_to_declared_inputs_map_.
add_new(output_socket, input_identifier);
250void ShaderOperation::populate_results_for_node(DNode node)
254 for (
const bNodeSocket *output : node->output_sockets()) {
255 const DOutputSocket doutput{node.context(), output};
265 const bool is_preview_output = doutput == preview_output;
266 if (is_preview_output) {
270 if (is_operation_output || is_preview_output) {
271 populate_operation_result(doutput);
280 return "node_compositor_store_output_float";
282 return "node_compositor_store_output_vector";
284 return "node_compositor_store_output_color";
294void ShaderOperation::populate_operation_result(DOutputSocket output_socket)
297 std::string output_identifier =
"output" + std::to_string(output_id);
306 ShaderNode &node = *shader_nodes_.lookup(output_socket.node());
307 GPUNodeLink *output_link = node.get_output(output_socket->identifier).link;
318 GPU_link(material_, store_function_name, id_link, output_link, &storer_output_link);
325using namespace gpu::shader;
327void ShaderOperation::generate_code(
void *thunk,
332 ShaderCreateInfo &shader_create_info = *
reinterpret_cast<ShaderCreateInfo *
>(
335 shader_create_info.local_group_size(16, 16);
339 shader_create_info.auto_resource_location(
true);
343 shader_create_info.typedef_source(
"gpu_shader_compositor_type_conversion.glsl");
349 shader_create_info.compute_source(
"gpu_shader_compositor_main.glsl");
355 shader_create_info.typedef_source_generated +=
"void evaluate();\n";
358 operation->generate_code_for_outputs(shader_create_info);
360 shader_create_info.compute_source_generated +=
"void evaluate()\n{\n";
362 operation->generate_code_for_inputs(material, shader_create_info);
364 shader_create_info.compute_source_generated += code_generator_output->
composite;
366 shader_create_info.compute_source_generated +=
"}\n";
375 return "vec4(value)";
377 return "vec4(vector, 0.0)";
389void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_info)
391 const std::string store_float_function_header =
"void store_float(const uint id, float value)";
392 const std::string store_vector_function_header =
"void store_vector(const uint id, vec3 vector)";
393 const std::string store_color_function_header =
"void store_color(const uint id, vec4 color)";
400 shader_create_info.typedef_source_generated += store_float_function_header +
";\n";
401 shader_create_info.typedef_source_generated += store_vector_function_header +
";\n";
402 shader_create_info.typedef_source_generated += store_color_function_header +
";\n";
408 std::stringstream store_float_function;
409 std::stringstream store_vector_function;
410 std::stringstream store_color_function;
411 const std::string store_function_start =
"\n{\n switch (id) {\n";
412 store_float_function << store_float_function_header << store_function_start;
413 store_vector_function << store_vector_function_header << store_function_start;
414 store_color_function << store_color_function_header << store_function_start;
417 const Result &result =
get_result(output_identifier);
420 shader_create_info.image(0,
421 result.get_gpu_texture_format(),
428 std::stringstream case_code;
430 const std::string texel =
", ivec2(gl_GlobalInvocationID.xy), ";
431 case_code <<
" case " << StringRef(output_identifier).drop_known_prefix(
"output") <<
":\n"
432 <<
" imageStore(" << output_identifier << texel << store_expression <<
");\n"
436 switch (result.type()) {
438 store_float_function << case_code.str();
441 store_vector_function << case_code.str();
444 store_color_function << case_code.str();
454 const std::string store_function_end =
" }\n}\n\n";
455 store_float_function << store_function_end;
456 store_vector_function << store_function_end;
457 store_color_function << store_function_end;
459 shader_create_info.compute_source_generated += store_float_function.str() +
460 store_vector_function.str() +
461 store_color_function.str();
502void ShaderOperation::generate_code_for_inputs(
GPUMaterial *material,
503 ShaderCreateInfo &shader_create_info)
514 shader_create_info.sampler(0, ImageType::FLOAT_2D, attribute->name, Frequency::PASS);
520 std::stringstream declare_attributes;
521 declare_attributes <<
"struct {\n";
525 declare_attributes <<
" " << type <<
" v" << attribute->id <<
";\n";
527 declare_attributes <<
"} var_attrs;\n\n";
529 shader_create_info.compute_source_generated += declare_attributes.str();
533 shader_create_info.typedef_source(
"gpu_shader_compositor_texture_utilities.glsl");
537 std::stringstream initialize_attributes;
541 initialize_attributes <<
"var_attrs.v" << attribute->id <<
" = "
542 <<
"texture_load(" << attribute->name
543 <<
", ivec2(gl_GlobalInvocationID.xy))." << swizzle <<
";\n";
545 initialize_attributes <<
"\n";
547 shader_create_info.compute_source_generated += initialize_attributes.str();
#define BLI_assert_unreachable()
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
eGPUBackendType GPU_backend_get_type()
GPUNodeLink * GPU_constant(const float *num)
void GPU_material_compile(GPUMaterial *mat)
ListBase GPU_material_attributes(const GPUMaterial *material)
void GPU_material_status_set(GPUMaterial *mat, eGPUMaterialStatus status)
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)
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)
void GPU_texture_bind(GPUTexture *texture, int unit)
void GPU_texture_image_unbind_all()
void GPU_texture_unbind_all()
struct GPUShader GPUShader
virtual void compile(SVMCompiler &compiler)=0
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
ValueIterator values() const
void add_new(const Key &key, const Value &value)
bool contains(const Key &key) const
bool contains(const Key &key) const
Result create_result(ResultType type, ResultPrecision precision)
Result & get_input(StringRef identifier) const
Result & get_result(StringRef identifier)
InputDescriptor & get_input_descriptor(StringRef identifier)
void populate_result(StringRef identifier, Result result)
Context & context() const
void declare_input_descriptor(StringRef identifier, InputDescriptor descriptor)
virtual Domain compute_domain()
const Schedule & schedule_
PixelCompileUnit compile_unit_
VectorSet< DOutputSocket > preview_outputs_
Map< DOutputSocket, std::string > output_sockets_to_output_identifiers_map_
Map< std::string, DOutputSocket > inputs_to_linked_outputs_map_
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
void bind_as_texture(GPUShader *shader, const char *texture_name) const
ShaderOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
T min(const T &a, const T &b)
bool is_output_linked_to_node_conditioned(DOutputSocket output, FunctionRef< bool(DNode)> condition)
static const char * glsl_swizzle_from_result_type(ResultType type)
static const char * get_set_function_name(ResultType type)
DOutputSocket get_output_linked_to_input(DInputSocket input)
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)
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_type_from_result_type(ResultType type)
GPUShaderCreateInfo * create_info