44 switch (
input->source) {
47 return stream << (
input->is_zone_io ?
"zone" :
"tmp") <<
input->id;
49 return stream << (
input->is_zone_io ?
"zone" :
"cons") <<
input->id;
51 return stream <<
"node_tree.u" <<
input->id << (
input->is_duplicate ?
"b" :
"");
53 return stream <<
"var_attrs.v" <<
input->attr->id;
55 return stream <<
"UNI_ATTR(unf_attrs[resource_id].attr" <<
input->uniform_attr->id <<
")";
57 return stream <<
"attr_load_layer(" <<
input->layer_attr->hash_code <<
")";
59 return stream <<
"strct" <<
input->id;
61 return stream <<
input->texture->sampler_name;
63 return stream <<
input->texture->tiled_mapping_name;
72 return stream << (
output->is_zone_io ?
"zone" :
"tmp") <<
output->id;
82 for (
const uint32_t &
element : uint_span) {
83 char formatted_float[32];
85 stream << formatted_float;
99 stream << Span<float>(
input->vec,
input->type);
129 create_info = MEM_new<GPUCodegenCreateInfo>(__func__, debug_name);
130 output.create_info =
reinterpret_cast<GPUShaderCreateInfo *
>(
145 bool do_optimize = (nodes_total_ >= 60 || textures_total_ >= 4 || uniforms_total_ >= 64) &&
146 (textures_total_ >= 1 && uniforms_total_ >= 8 && nodes_total_ >= 4);
159 info.
interface_generated = MEM_new<StageInterfaceInfo>(__func__,
"codegen_iface",
"var_attrs");
164 std::stringstream load_ss;
180 GPUType input_type, iface_type;
182 load_ss <<
"var_attrs." << var_name;
183 if (attr->is_hair_length || attr->is_hair_intercept) {
185 load_ss <<
" = attr_load_" << input_type <<
"(domain, " << attr_name <<
", " << attr_n
189 switch (attr->type) {
194 load_ss <<
" = attr_load_orco(domain, " << attr_name <<
", " << attr_n <<
");\n";
198 load_ss <<
" = attr_load_tangent(domain, " << attr_name <<
", " << attr_n <<
");\n";
202 load_ss <<
" = attr_load_" << input_type <<
"(domain, " << attr_name <<
", " << attr_n
213 output.attr_load = load_ss.str();
220 std::stringstream ss;
225 if (tex->colorband) {
233 else if (tex->tiled_mapping_name[0] !=
'\0') {
247 textures_total_ = slot;
251 ss <<
"struct NodeTree {\n";
255 ss <<
input->type <<
" crypto_hash;\n";
258 ss <<
input->type <<
" u" <<
input->id << (
input->is_duplicate ?
"b" :
"") <<
";\n";
267 ss <<
"struct UniformAttrs {\n";
269 ss <<
"vec4 attr" << attr->id <<
";\n";
286 std::stringstream &eval_ss,
299 eval_ss << to <<
"_from_" << from <<
"(";
306 eval_ss <<
input->link->output;
312 float coefficients[3];
324 std::stringstream ss;
325 if (!
input->is_duplicate) {
330 switch (
input->source) {
332 eval_ss << type() <<
" " <<
input <<
"; " <<
input->function_call <<
input <<
");\n";
335 eval_ss <<
input->type <<
" " <<
input <<
" = CLOSURE_DEFAULT;\n";
338 if (!
input->is_duplicate) {
339 eval_ss << type() <<
" " <<
input <<
" = " << (GPUConstant *)
input <<
";\n";
344 if (
input->is_zone_io) {
345 eval_ss << type() <<
" " <<
input <<
" = ";
346 source_reference(
input);
352 eval_ss << type() <<
" zone" <<
input->id <<
" = " <<
input <<
";\n";
366 eval_ss << node->
name <<
"(";
369 if (
input->is_zone_io) {
372 switch (
input->source) {
375 source_reference(
input);
410 std::sort(source_files.
begin(), source_files.
end());
414GPUGraphOutput GPUCodegen::graph_serialize(
GPUNodeTag tree_tag,
415 GPUNodeLink *output_link,
416 const char *output_default)
418 if (output_link ==
nullptr && output_default ==
nullptr) {
422 Set<StringRefNull> used_libraries;
423 std::stringstream eval_ss;
424 bool has_nodes =
false;
428 if ((node->
tag & tree_tag) == 0) {
431 node_serialize(used_libraries, eval_ss, node);
440 eval_ss <<
"return " << output_link->
output <<
";\n";
444 eval_ss <<
"return " << output_default <<
";\n";
447 std::string
str = eval_ss.str();
452GPUGraphOutput GPUCodegen::graph_serialize(
GPUNodeTag tree_tag)
454 std::stringstream eval_ss;
455 Set<StringRefNull> used_libraries;
457 if (node->
tag & tree_tag) {
458 node_serialize(used_libraries, eval_ss, node);
461 std::string
str = eval_ss.str();
472 float material_hash = 0.0f;
477 material_hash =
hash.float_encoded();
479 cryptomatte_input_->vec[0] = material_hash;
503void GPUCodegen::set_unique_ids()
517 auto &map = node->
is_zone_end ? zone_ends : zone_starts;
522 auto find_zone_io = [](
auto first) {
523 while (first && !first->is_zone_io && first->next) {
530 for (GPUNode *end : zone_ends.
values()) {
532 GPUInput *end_input = find_zone_io((GPUInput *)end->inputs.first);
533 GPUOutput *end_output = find_zone_io((GPUOutput *)end->outputs.first);
535 GPUNode *start = zone_starts.
lookup(end->zone_index);
537 GPUInput *start_input = find_zone_io((GPUInput *)start->
inputs.
first);
538 GPUOutput *start_output = find_zone_io((GPUOutput *)start->
outputs.
first);
540 for (; start_input; start_input = start_input->
next,
541 start_output = start_output->
next,
542 end_input = end_input->
next,
543 end_output = end_output->
next)
545 start_output->
id = start_input->
id;
546 end_input->
id = start_input->
id;
547 end_output->
id = start_input->
id;
556 output.surface = graph_serialize(
559 output.displacement = graph_serialize(
568 std::stringstream eval_ss;
576 eval_ss <<
"float " << func_link->name <<
"() {\n" <<
graph.serialized <<
"}\n\n";
577 output.material_functions.append({eval_ss.str(),
graph.dependencies});
#define BLI_assert_msg(a, msg)
void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed)
void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len)
void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data)
uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
LinkData * BLI_genericNodeN(void *data)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define SNPRINTF(dst, format,...)
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
uint64_t GPU_material_uuid_get(GPUMaterial *mat)
Material * GPU_material_get_material(GPUMaterial *material)
eGPUMaterialFlag GPU_material_flag(const GPUMaterial *mat)
void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs)
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const void * element
ValueIterator values() const &
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Span< NewT > constexpr cast() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
void append(const T &value)
bool should_optimize_heuristic() const
GPUCodegenCreateInfo * create_info
void generate_cryptomatte()
GPUCodegen(GPUMaterial *mat_, GPUNodeGraph *graph_, const char *debug_name)
void generate_resources()
void generate_uniform_buffer()
static Vector< StringRefNull > set_to_vector_stable(Set< StringRefNull > &set)
void gpu_material_library_use_function(blender::Set< blender::StringRefNull > &used_libraries, const char *name)
void gpu_nodes_tag(GPUNodeGraph *graph, GPUNodeLink *link_start, GPUNodeTag tag)
@ GPU_SOURCE_FUNCTION_CALL
@ GPU_SOURCE_TEX_TILED_MAPPING
@ GPU_SOURCE_UNIFORM_ATTR
@ GPU_NODE_TAG_DISPLACEMENT
@ GPU_NODE_TAG_COMPOSITOR
void * MEM_callocN(size_t len, const char *str)
static Type to_type(const GPUType type)
std::ostream & operator<<(std::ostream &stream, const eAlpha &space)
char attr_names[16][GPU_MAX_SAFE_ATTR_NAME+1]
const char * append_sampler_name(const char name[32])
Vector< std::unique_ptr< NameEntry >, 16 > sampler_names
StageInterfaceInfo * interface_generated
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Self & vertex_in(int slot, Type type, StringRefNull name)
Self & additional_info(StringRefNull info_name)
Self & vertex_out(StageInterfaceInfo &interface)
std::string typedef_source_generated
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, GPUSamplerState sampler=GPUSamplerState::internal_sampler())
Self & uniform_buf(int slot, StringRefNull type_name, StringRefNull name, Frequency freq=Frequency::PASS)
Self & smooth(Type type, StringRefNull _name)