42# define SRC_NAME(io, link, list, type) \
43 link->node->name << "_" << io << BLI_findindex(&link->node->list, (const void *)link) << "_" \
46# define SRC_NAME(io, list, link, type) type
51 switch (
input->source) {
58 return stream <<
"node_tree.u" <<
input->id;
60 return stream <<
"var_attrs.v" <<
input->attr->id;
62 return stream <<
"UNI_ATTR(unf_attrs[resource_id].attr" <<
input->uniform_attr->id <<
")";
64 return stream <<
"attr_load_layer(" <<
input->layer_attr->hash_code <<
")";
66 return stream <<
"strct" <<
input->id;
68 return stream <<
input->texture->sampler_name;
70 return stream <<
input->texture->tiled_mapping_name;
89 for (
const uint32_t &
element : uint_span) {
90 char formatted_float[32];
92 stream << formatted_float;
106 stream << Span<float>(
input->vec,
input->type);
136 create_info = MEM_new<GPUCodegenCreateInfo>(__func__, debug_name);
137 output.create_info =
reinterpret_cast<GPUShaderCreateInfo *
>(
152 bool do_optimize = (nodes_total_ >= 60 || textures_total_ >= 4 || uniforms_total_ >= 64) &&
153 (textures_total_ >= 1 && uniforms_total_ >= 8 && nodes_total_ >= 4);
166 info.
interface_generated = MEM_new<StageInterfaceInfo>(__func__,
"codegen_iface",
"var_attrs");
171 std::stringstream load_ss;
187 load_ss <<
"var_attrs." << var_name;
188 if (attr->is_hair_length) {
190 load_ss <<
" = attr_load_" << input_type <<
"(" << attr_name <<
");\n";
193 switch (attr->type) {
198 load_ss <<
" = attr_load_orco(" << attr_name <<
");\n";
202 load_ss <<
" = attr_load_tangent(" << attr_name <<
");\n";
206 load_ss <<
" = attr_load_" << input_type <<
"(" << attr_name <<
");\n";
215 output.attr_load = load_ss.str();
222 std::stringstream ss;
227 if (tex->colorband) {
235 else if (tex->tiled_mapping_name[0] !=
'\0') {
249 textures_total_ = slot;
253 ss <<
"struct NodeTree {\n";
257 ss <<
input->type <<
" crypto_hash;\n";
260 ss <<
input->type <<
" u" <<
input->id <<
";\n";
269 ss <<
"struct UniformAttrs {\n";
271 ss <<
"vec4 attr" << attr->id <<
";\n";
302 source_files.
append((
const char *)value);
307 std::sort(source_files.
begin(), source_files.
end());
308 for (
auto &key : source_files) {
314void GPUCodegen::node_serialize(std::stringstream &eval_ss,
const GPUNode *node)
318 switch (
input->source) {
323 eval_ss <<
input->type <<
" " <<
input <<
" = CLOSURE_DEFAULT;\n";
338 eval_ss << node->
name <<
"(";
341 switch (
input->source) {
350 eval_ss << to <<
"_from_" << from <<
"(";
357 eval_ss <<
input->link->output;
363 float coefficients[3];
365 eval_ss <<
", " << Span<float>(coefficients, 3);
391std::string GPUCodegen::graph_serialize(
eGPUNodeTag tree_tag,
392 GPUNodeLink *output_link,
393 const char *output_default)
395 if (output_link ==
nullptr && output_default ==
nullptr) {
399 std::stringstream eval_ss;
400 bool has_nodes =
false;
404 if ((node->
tag & tree_tag) == 0) {
407 node_serialize(eval_ss, node);
416 eval_ss <<
"return " << output_link->
output <<
";\n";
420 eval_ss <<
"return " << output_default <<
";\n";
423 std::string
str = eval_ss.str();
428std::string GPUCodegen::graph_serialize(
eGPUNodeTag tree_tag)
430 std::stringstream eval_ss;
432 if (node->
tag & tree_tag) {
433 node_serialize(eval_ss, node);
436 std::string
str = eval_ss.str();
447 float material_hash = 0.0f;
452 material_hash =
hash.float_encoded();
454 cryptomatte_input_->vec[0] = material_hash;
478void GPUCodegen::set_unique_ids()
495 output.surface = graph_serialize(
498 output.displacement = graph_serialize(
506 std::stringstream eval_ss;
507 eval_ss <<
"\n/* Generated Functions */\n\n";
516 eval_ss <<
"float " << func_link->name <<
"() {\n" <<
fn <<
"}\n\n";
518 output.material_functions = eval_ss.str();
#define BLI_assert_msg(a, msg)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
void BLI_ghashIterator_step(GHashIterator *ghi)
void BLI_ghashIterator_free(GHashIterator *ghi)
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
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)
bool GPU_shader_draw_parameters_support()
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
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()
#define SRC_NAME(io, list, link, type)
void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag)
@ GPU_NODE_TAG_DISPLACEMENT
@ GPU_NODE_TAG_COMPOSITOR
@ GPU_SOURCE_FUNCTION_CALL
@ GPU_SOURCE_TEX_TILED_MAPPING
@ GPU_SOURCE_UNIFORM_ATTR
void * MEM_callocN(size_t len, const char *str)
static Type to_type(const eGPUType type)
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(const StringRefNull shader_source_name)
std::ostream & operator<<(std::ostream &stream, const eAlpha &space)
static blender::bke::bNodeSocketTemplate outputs[]
static blender::bke::bNodeSocketTemplate inputs[]
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)
Vector< StringRefNull, 0 > dependencies_generated
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)