44 compiler.
compile(shader, *svm_nodes, 0, &summary);
47 <<
"Shader name: " << shader->
name <<
"\n"
62 scene->update_stats->svm.times.add_entry({
"device_update", time});
68 VLOG_INFO <<
"Total " << num_shaders <<
" shaders.";
70 const double start_time =
time_dt();
73 device_free(device, dscene,
scene);
78 for (
int i = 0; i < num_shaders; i++) {
85 if (progress.get_cancel()) {
91 int svm_nodes_size = num_shaders;
92 for (
int i = 0; i < num_shaders; i++) {
94 svm_nodes_size += shader_svm_nodes[i].size() - 1;
97 int4 *svm_nodes = dscene->svm_nodes.alloc(svm_nodes_size);
99 int node_offset = num_shaders;
100 for (
int i = 0; i < num_shaders; i++) {
111 int4 &global_jump_node = svm_nodes[shader->
id];
112 const int4 &local_jump_node = shader_svm_nodes[i][0];
114 global_jump_node.
x = NODE_SHADER_JUMP;
115 global_jump_node.
y = local_jump_node.
y - 1 + node_offset;
116 global_jump_node.
z = local_jump_node.
z - 1 + node_offset;
117 global_jump_node.
w = local_jump_node.
w - 1 + node_offset;
119 node_offset += shader_svm_nodes[i].size() - 1;
123 svm_nodes += num_shaders;
124 for (
int i = 0; i < num_shaders; i++) {
125 const int shader_size = shader_svm_nodes[i].size() - 1;
127 std::copy_n(&shader_svm_nodes[i][1], shader_size, svm_nodes);
128 svm_nodes += shader_size;
131 if (progress.get_cancel()) {
135 device_update_common(device, dscene,
scene, progress);
137 update_flags = UPDATE_NONE;
139 VLOG_INFO <<
"Shader manager updated " << num_shaders <<
" shaders in " <<
time_dt() - start_time
206 if (num_unused ==
size) {
207 offset = i + 1 -
size;
210 while (i >= offset) {
221 "Cycles: out of SVM stack space, shader \"%s\" too big.\n",
237 for (
int i = 0; i <
size; i++) {
249 input->stack_offset =
input->link->stack_offset;
260 input->stack_offset);
278 return input->stack_offset;
288 return output->stack_offset;
293 return (
input->link ||
input->constant_folded_in);
307 if (!
output->links.empty()) {
324 for (
int i = 0; i <
size; i++) {
343 bool all_done =
true;
347 if (
in->parent !=
node && done.find(
in->parent) == done.end()) {
381 return (
x) | (
y << 8) | (
z << 16) | (
w << 24);
430 if (
node !=
nullptr && done.find(
node) == done.end() &&
node != skip_node &&
431 dependencies.find(
node) == dependencies.end())
436 dependencies.insert(
node);
442 node->compile(*
this);
447 if (
node->has_spatial_varying()) {
455 if (
node->has_spatial_varying()) {
458 if (
node->has_attribute_dependency()) {
474 if (!done_flag[
node->id]) {
475 bool inputs_done =
true;
478 if (
input->link && !done_flag[
input->link->parent->id]) {
485 done_flag[
node->id] =
true;
492 }
while (!nodes_done);
499 const int node_feature =
node->get_feature();
500 if ((
state->node_feature_mask & node_feature) != node_feature) {
506 if (
in->link !=
nullptr) {
531 if (
node->has_surface_transparent()) {
534 if (
node->has_surface_bssrdf()) {
536 if (
node->has_bssrdf_bump()) {
540 if (
node->has_bump()) {
570 if (aov_node->
offset >= 0) {
571 aov_nodes.insert(aov_node);
573 if (
in->link !=
nullptr) {
587 if (
state->closure_done.find(
node) !=
state->closure_done.end()) {
604 if (facin && facin->
link) {
621 set_intersection(cl1deps.begin(),
625 std::inserter(shareddeps, shareddeps.begin()),
632 if (root_node !=
node) {
636 set_intersection(rootdeps.begin(),
640 std::inserter(shareddeps, shareddeps.begin()),
642 set_intersection(rootdeps.begin(),
646 std::inserter(shareddeps, shareddeps.begin()),
655 if (!
state->aov_nodes.empty()) {
656 set_intersection(
state->aov_nodes.begin(),
657 state->aov_nodes.end(),
660 std::inserter(shareddeps, shareddeps.begin()),
662 set_intersection(
state->aov_nodes.begin(),
663 state->aov_nodes.end(),
666 std::inserter(shareddeps, shareddeps.begin()),
670 if (!shareddeps.empty()) {
694 node_jump_skip_index - 1;
710 node_jump_skip_index - 1;
763 clin =
output->input(
"Surface");
766 clin =
output->input(
"Volume");
769 clin =
output->input(
"Displacement");
772 clin =
output->input(
"Normal");
795 if (need_bump_state) {
839 if (!
state.aov_nodes.empty()) {
852 if (need_bump_state) {
879 const int start_num_svm_nodes = svm_nodes.
size();
881 const double time_start =
time_dt();
899 if (has_bump_from_displacement) {
902 svm_nodes[index].y = svm_nodes.
size();
912 if (!has_bump_from_displacement) {
913 svm_nodes[index].y = svm_nodes.
size();
922 svm_nodes[index].z = svm_nodes.
size();
931 svm_nodes[index].w = svm_nodes.
size();
936 if (summary !=
nullptr) {
951 time_generate_surface(0.0),
952 time_generate_bump(0.0),
953 time_generate_volume(0.0),
954 time_generate_displacement(0.0),
962 report +=
string_printf(
"Number of SVM nodes: %d\n", num_svm_nodes);
963 report +=
string_printf(
"Peak stack usage: %d\n", peak_stack_usage);
967 time_generate_surface + time_generate_bump + time_generate_volume +
968 time_generate_displacement);
969 report +=
string_printf(
" Surface: %f\n", time_generate_surface);
971 report +=
string_printf(
" Volume: %f\n", time_generate_volume);
972 report +=
string_printf(
" Displacement: %f\n", time_generate_displacement);
983 max_id =
max(
node->id, max_id);
985 nodes_done_flag.resize(max_id + 1,
false);
986 node_feature_mask = 0;
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.
Shader * get_shader(const Scene *scene)
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)
SVMCompiler(Scene *scene)
array< int4 > current_svm_nodes
int stack_find_offset(const int size)
void generate_closure_node(ShaderNode *node, CompilerState *state)
void compile(Shader *shader, array< int4 > &svm_nodes, const int index, Summary *summary=nullptr)
void generate_node(ShaderNode *node, ShaderNodeSet &done)
uint encode_uchar4(const uint x, const uint y=0, const uint z=0, const uint w=0)
int stack_assign_if_linked(ShaderInput *input)
void stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
int stack_size(SocketType::Type type)
void find_dependencies(ShaderNodeSet &dependencies, const ShaderNodeSet &done, ShaderInput *input, ShaderNode *skip_node=nullptr)
void stack_clear_temporary(ShaderNode *node)
uint attribute_standard(ustring name)
void add_node(ShaderNodeType type, const int a=0, const int b=0, const int c=0)
void stack_link(ShaderInput *input, ShaderOutput *output)
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)
void stack_clear_offset(SocketType::Type type, const int offset)
std::atomic_int * svm_node_types_used
void generated_shared_closure_nodes(ShaderNode *root_node, ShaderNode *node, CompilerState *state, const ShaderNodeSet &shared)
int stack_assign(ShaderOutput *output)
void device_update_shader(Scene *scene, Shader *shader, Progress &progress, array< int4 > *svm_nodes)
void device_free(Device *device, DeviceScene *dscene, Scene *scene) override
void device_update_specific(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress) override
~SVMShaderManager() override
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
unique_ptr_vector< ShaderInput > inputs
ShaderOutput * output(const char *name)
bool has_surface_spatial_varying
bool has_bump_from_surface
bool has_volume_attribute_dependency
bool has_bump_from_displacement
EmissionSampling emission_sampling
bool has_surface_raytrace
bool has_surface_transparent
NODE_DECLARE unique_ptr< ShaderGraph > graph
bool has_volume_spatial_varying
void append(const array< T > &from)
void push_back_slow(const T &t)
#define CCL_NAMESPACE_END
#define assert(assertion)
@ 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,...)
static AttributeStandard name_standard(const char *name)
int reference_count() const
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
unique_ptr< LightManager > light_manager
unique_ptr< SceneUpdateStats > update_stats
unique_ptr_vector< Shader > shaders
unique_ptr< ShaderManager > shader_manager
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=nullptr)
CCL_NAMESPACE_BEGIN double time_dt()