40 assert(shader->graph);
44 compiler.
background = (shader == scene->background->get_shader(scene));
45 compiler.
compile(shader, *svm_nodes, 0, &summary);
48 <<
"Shader name: " << shader->name <<
"\n"
62 if (scene->update_stats) {
63 scene->update_stats->svm.times.add_entry({
"device_update", time});
67 const int num_shaders = scene->shaders.size();
69 VLOG_INFO <<
"Total " << num_shaders <<
" shaders.";
74 device_free(device, dscene, scene);
79 for (
int i = 0; i < num_shaders; i++) {
85 &shader_svm_nodes[i]));
89 if (progress.get_cancel()) {
95 int svm_nodes_size = num_shaders;
96 for (
int i = 0; i < num_shaders; i++) {
98 svm_nodes_size += shader_svm_nodes[i].size() - 1;
101 int4 *svm_nodes = dscene->svm_nodes.alloc(svm_nodes_size);
103 int node_offset = num_shaders;
104 for (
int i = 0; i < num_shaders; i++) {
105 Shader *shader = scene->shaders[i];
115 int4 &global_jump_node = svm_nodes[shader->id];
116 int4 &local_jump_node = shader_svm_nodes[i][0];
118 global_jump_node.
x = NODE_SHADER_JUMP;
119 global_jump_node.
y = local_jump_node.
y - 1 + node_offset;
120 global_jump_node.
z = local_jump_node.
z - 1 + node_offset;
121 global_jump_node.
w = local_jump_node.
w - 1 + node_offset;
123 node_offset += shader_svm_nodes[i].size() - 1;
127 svm_nodes += num_shaders;
128 for (
int i = 0; i < num_shaders; i++) {
129 int shader_size = shader_svm_nodes[i].size() - 1;
131 memcpy(svm_nodes, &shader_svm_nodes[i][1],
sizeof(
int4) * shader_size);
132 svm_nodes += shader_size;
135 if (progress.get_cancel()) {
139 dscene->svm_nodes.copy_to_device();
141 device_update_common(device, dscene, scene, progress);
143 update_flags = UPDATE_NONE;
145 VLOG_INFO <<
"Shader manager updated " << num_shaders <<
" shaders in " <<
time_dt() - start_time
212 if (num_unused == size) {
213 offset = i + 1 -
size;
216 while (i >= offset) {
227 "Cycles: out of SVM stack space, shader \"%s\" too big.\n",
243 for (
int i = 0; i <
size; i++) {
255 input->stack_offset = input->link->stack_offset;
258 Node *node = input->parent;
266 input->stack_offset);
269 add_node(NODE_VALUE_F, node->get_int(input->socket_type), input->stack_offset);
275 add_node(NODE_VALUE_V, input->stack_offset);
276 add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
284 return input->stack_offset;
294 return output->stack_offset;
299 return (input->link || input->constant_folded_in);
313 if (!output->links.empty()) {
326 output->stack_offset = input->link->stack_offset;
330 for (
int i = 0; i <
size; i++) {
349 bool all_done =
true;
353 if (in->parent != node && done.find(in->parent) == done.end()) {
385 return (x) | (y << 8) | (
z << 16) | (
w << 24);
414 return scene->shader_manager->get_attribute_id(name);
419 return scene->shader_manager->get_attribute_id(std);
434 if (node !=
NULL && done.find(node) == done.end() && node != skip_node &&
435 dependencies.find(node) == dependencies.end())
440 dependencies.insert(node);
446 node->compile(*
this);
451 if (node->has_spatial_varying()) {
459 if (node->has_spatial_varying()) {
462 if (node->has_attribute_dependency()) {
478 if (!done_flag[node->id]) {
479 bool inputs_done =
true;
482 if (input->link && !done_flag[input->link->parent->id]) {
489 done_flag[node->id] =
true;
496 }
while (!nodes_done);
503 const int node_feature = node->get_feature();
504 if ((
state->node_feature_mask & node_feature) != node_feature) {
510 if (in->link !=
NULL) {
522 if (weight_in && (weight_in->
link || node->get_float(weight_in->
socket_type) != 1.0f)) {
535 if (node->has_surface_transparent()) {
538 if (node->has_surface_bssrdf()) {
540 if (node->has_bssrdf_bump()) {
544 if (node->has_bump()) {
555 if (shared.find(node) != shared.end()) {
574 if (aov_node->
offset >= 0) {
575 aov_nodes.insert(aov_node);
577 if (in->link !=
NULL) {
591 if (
state->closure_done.find(node) !=
state->closure_done.end()) {
595 state->closure_done.insert(node);
608 if (facin && facin->
link) {
623 set_intersection(cl1deps.begin(),
627 std::inserter(shareddeps, shareddeps.begin()),
634 if (root_node != node) {
638 set_intersection(rootdeps.begin(),
642 std::inserter(shareddeps, shareddeps.begin()),
644 set_intersection(rootdeps.begin(),
648 std::inserter(shareddeps, shareddeps.begin()),
657 if (
state->aov_nodes.size()) {
658 set_intersection(
state->aov_nodes.begin(),
659 state->aov_nodes.end(),
662 std::inserter(shareddeps, shareddeps.begin()),
664 set_intersection(
state->aov_nodes.begin(),
665 state->aov_nodes.end(),
668 std::inserter(shareddeps, shareddeps.begin()),
672 if (!shareddeps.empty()) {
696 node_jump_skip_index - 1;
712 node_jump_skip_index - 1;
734 state->nodes_done.insert(node);
735 state->nodes_done_flag[node->id] =
true;
765 clin = output->input(
"Surface");
768 clin = output->input(
"Volume");
771 clin = output->input(
"Displacement");
774 clin = output->input(
"Normal");
795 if (need_bump_state) {
800 if (shader->reference_count()) {
807 shader->has_surface =
true;
813 shader->has_volume =
true;
819 shader->has_displacement =
true;
837 output->compile(*
this);
839 if (!
state.aov_nodes.empty()) {
852 if (need_bump_state) {
877 int start_num_svm_nodes = svm_nodes.
size();
879 const double time_start =
time_dt();
881 bool has_bump = (shader->get_displacement_method() !=
DISPLACE_TRUE) &&
882 output->input(
"Surface")->link && output->input(
"Displacement")->link;
887 shader->graph->finalize(scene, has_bump, shader->get_displacement_method() ==
DISPLACE_BOTH);
893 shader->has_surface_transparent =
false;
894 shader->has_surface_raytrace =
false;
895 shader->has_surface_bssrdf =
false;
896 shader->has_bump = has_bump;
897 shader->has_bssrdf_bump = has_bump;
898 shader->has_volume =
false;
899 shader->has_displacement =
false;
900 shader->has_surface_spatial_varying =
false;
901 shader->has_volume_spatial_varying =
false;
902 shader->has_volume_attribute_dependency =
false;
908 svm_nodes[index].y = svm_nodes.
size();
919 svm_nodes[index].y = svm_nodes.
size();
928 svm_nodes[index].z = svm_nodes.
size();
936 svm_nodes[index].w = svm_nodes.
size();
941 if (summary !=
NULL) {
948 shader->estimate_emission();
957 time_generate_surface(0.0),
958 time_generate_bump(0.0),
959 time_generate_volume(0.0),
960 time_generate_displacement(0.0),
968 report +=
string_printf(
"Number of SVM nodes: %d\n", num_svm_nodes);
969 report +=
string_printf(
"Peak stack usage: %d\n", peak_stack_usage);
973 report +=
string_printf(
" Surface: %f\n", time_generate_surface);
975 report +=
string_printf(
" Volume: %f\n", time_generate_volume);
976 report +=
string_printf(
" Displacement: %f\n", time_generate_displacement);
978 time_generate_surface + time_generate_bump + time_generate_volume +
979 time_generate_displacement);
991 max_id =
max(node->id, max_id);
993 nodes_done_flag.resize(max_id + 1,
false);
994 node_feature_mask = 0;
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static AttributeStandard name_standard(const char *name)
device_vector< int4 > svm_nodes
ShaderGraph * current_graph
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
void find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes, ShaderGraph *graph, CompilerState *state)
void add_node(ShaderNodeType type, int a=0, int b=0, int c=0)
SVMCompiler(Scene *scene)
array< int4 > current_svm_nodes
void generate_closure_node(ShaderNode *node, CompilerState *state)
void stack_clear_offset(SocketType::Type type, int offset)
void generate_node(ShaderNode *node, ShaderNodeSet &done)
int stack_assign_if_linked(ShaderInput *input)
void stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
int stack_size(SocketType::Type type)
void stack_clear_temporary(ShaderNode *node)
uint encode_uchar4(uint x, uint y=0, uint z=0, uint w=0)
uint attribute_standard(ustring name)
void stack_link(ShaderInput *input, ShaderOutput *output)
void find_dependencies(ShaderNodeSet &dependencies, const ShaderNodeSet &done, ShaderInput *input, ShaderNode *skip_node=NULL)
void generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state)
bool is_linked(ShaderInput *input)
void generate_multi_closure(ShaderNode *root_node, ShaderNode *node, CompilerState *state)
uint attribute(ustring name)
std::atomic_int * svm_node_types_used
int stack_find_offset(int size)
void compile(Shader *shader, array< int4 > &svm_nodes, int index, Summary *summary=NULL)
void generated_shared_closure_nodes(ShaderNode *root_node, ShaderNode *node, CompilerState *state, const ShaderNodeSet &shared)
int stack_assign(ShaderOutput *output)
void reset(Scene *scene) override
void device_free(Device *device, DeviceScene *dscene, Scene *scene) override
void device_update_specific(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress) override
void device_update_shader(Scene *scene, Shader *shader, Progress *progress, array< int4 > *svm_nodes)
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
vector< ShaderInput * > inputs
ShaderOutput * output(const char *name)
bool has_surface_spatial_varying
bool has_volume_attribute_dependency
bool has_surface_raytrace
bool has_surface_transparent
bool has_volume_spatial_varying
void append(const array< T > &from)
void push_back_slow(const T &t)
local_group_size(16, 16) .push_constant(Type b
#define CCL_NAMESPACE_END
@ SHADER_TYPE_DISPLACEMENT
#define SVM_BUMP_EVAL_STATE_SIZE
#define SVM_STACK_INVALID
#define KERNEL_FEATURE_NODE_MASK_DISPLACEMENT
#define KERNEL_FEATURE_NODE_MASK_BUMP
#define KERNEL_FEATURE_NODE_MASK_VOLUME
#define KERNEL_FEATURE_NODE_MASK_SURFACE
#define KERNEL_FEATURE_NODE_RAYTRACE
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
@ SHADER_SPECIAL_TYPE_COMBINE_CLOSURE
set< ShaderNode *, ShaderNodeIDComparator > ShaderNodeSet
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
CompilerState(ShaderGraph *graph)
int users[SVM_STACK_SIZE]
double time_generate_volume
double time_generate_surface
double time_generate_bump
string full_report() const
double time_generate_displacement
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=NULL)
CCL_NAMESPACE_BEGIN double time_dt()