svm.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "device/device.h"
  17. #include "render/graph.h"
  18. #include "render/light.h"
  19. #include "render/mesh.h"
  20. #include "render/nodes.h"
  21. #include "render/scene.h"
  22. #include "render/shader.h"
  23. #include "render/svm.h"
  24. #include "util/util_logging.h"
  25. #include "util/util_foreach.h"
  26. #include "util/util_progress.h"
  27. #include "util/util_task.h"
  28. CCL_NAMESPACE_BEGIN
  29. /* Shader Manager */
  30. SVMShaderManager::SVMShaderManager()
  31. {
  32. }
  33. SVMShaderManager::~SVMShaderManager()
  34. {
  35. }
  36. void SVMShaderManager::reset(Scene * /*scene*/)
  37. {
  38. }
  39. void SVMShaderManager::device_update_shader(Scene *scene,
  40. Shader *shader,
  41. Progress *progress,
  42. array<int4> *global_svm_nodes)
  43. {
  44. if (progress->get_cancel()) {
  45. return;
  46. }
  47. assert(shader->graph);
  48. array<int4> svm_nodes;
  49. svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
  50. SVMCompiler::Summary summary;
  51. SVMCompiler compiler(scene->shader_manager, scene->image_manager, scene->light_manager);
  52. compiler.background = (shader == scene->default_background);
  53. compiler.compile(scene, shader, svm_nodes, 0, &summary);
  54. VLOG(2) << "Compilation summary:\n"
  55. << "Shader name: " << shader->name << "\n"
  56. << summary.full_report();
  57. nodes_lock_.lock();
  58. if (shader->use_mis && shader->has_surface_emission) {
  59. scene->light_manager->need_update = true;
  60. }
  61. /* The copy needs to be done inside the lock, if another thread resizes the array
  62. * while memcpy is running, it'll be copying into possibly invalid/freed ram.
  63. */
  64. size_t global_nodes_size = global_svm_nodes->size();
  65. global_svm_nodes->resize(global_nodes_size + svm_nodes.size());
  66. /* Offset local SVM nodes to a global address space. */
  67. int4 &jump_node = (*global_svm_nodes)[shader->id];
  68. jump_node.y = svm_nodes[0].y + global_nodes_size - 1;
  69. jump_node.z = svm_nodes[0].z + global_nodes_size - 1;
  70. jump_node.w = svm_nodes[0].w + global_nodes_size - 1;
  71. /* Copy new nodes to global storage. */
  72. memcpy(&(*global_svm_nodes)[global_nodes_size],
  73. &svm_nodes[1],
  74. sizeof(int4) * (svm_nodes.size() - 1));
  75. nodes_lock_.unlock();
  76. }
  77. void SVMShaderManager::device_update(Device *device,
  78. DeviceScene *dscene,
  79. Scene *scene,
  80. Progress &progress)
  81. {
  82. if (!need_update)
  83. return;
  84. VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
  85. double start_time = time_dt();
  86. /* test if we need to update */
  87. device_free(device, dscene, scene);
  88. /* determine which shaders are in use */
  89. device_update_shaders_used(scene);
  90. /* svm_nodes */
  91. array<int4> svm_nodes;
  92. size_t i;
  93. for (i = 0; i < scene->shaders.size(); i++) {
  94. svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
  95. }
  96. TaskPool task_pool;
  97. foreach (Shader *shader, scene->shaders) {
  98. task_pool.push(
  99. function_bind(
  100. &SVMShaderManager::device_update_shader, this, scene, shader, &progress, &svm_nodes),
  101. false);
  102. }
  103. task_pool.wait_work();
  104. if (progress.get_cancel()) {
  105. return;
  106. }
  107. dscene->svm_nodes.steal_data(svm_nodes);
  108. dscene->svm_nodes.copy_to_device();
  109. for (i = 0; i < scene->shaders.size(); i++) {
  110. Shader *shader = scene->shaders[i];
  111. shader->need_update = false;
  112. }
  113. device_update_common(device, dscene, scene, progress);
  114. need_update = false;
  115. VLOG(1) << "Shader manager updated " << scene->shaders.size() << " shaders in "
  116. << time_dt() - start_time << " seconds.";
  117. }
  118. void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
  119. {
  120. device_free_common(device, dscene, scene);
  121. dscene->svm_nodes.free();
  122. }
  123. /* Graph Compiler */
  124. SVMCompiler::SVMCompiler(ShaderManager *shader_manager_,
  125. ImageManager *image_manager_,
  126. LightManager *light_manager_)
  127. {
  128. shader_manager = shader_manager_;
  129. image_manager = image_manager_;
  130. light_manager = light_manager_;
  131. max_stack_use = 0;
  132. current_type = SHADER_TYPE_SURFACE;
  133. current_shader = NULL;
  134. current_graph = NULL;
  135. background = false;
  136. mix_weight_offset = SVM_STACK_INVALID;
  137. compile_failed = false;
  138. }
  139. int SVMCompiler::stack_size(SocketType::Type type)
  140. {
  141. int size = 0;
  142. switch (type) {
  143. case SocketType::FLOAT:
  144. case SocketType::INT:
  145. size = 1;
  146. break;
  147. case SocketType::COLOR:
  148. case SocketType::VECTOR:
  149. case SocketType::NORMAL:
  150. case SocketType::POINT:
  151. size = 3;
  152. break;
  153. case SocketType::CLOSURE:
  154. size = 0;
  155. break;
  156. default:
  157. assert(0);
  158. break;
  159. }
  160. return size;
  161. }
  162. int SVMCompiler::stack_find_offset(int size)
  163. {
  164. int offset = -1;
  165. /* find free space in stack & mark as used */
  166. for (int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
  167. if (active_stack.users[i])
  168. num_unused = 0;
  169. else
  170. num_unused++;
  171. if (num_unused == size) {
  172. offset = i + 1 - size;
  173. max_stack_use = max(i + 1, max_stack_use);
  174. while (i >= offset)
  175. active_stack.users[i--] = 1;
  176. return offset;
  177. }
  178. }
  179. if (!compile_failed) {
  180. compile_failed = true;
  181. fprintf(stderr,
  182. "Cycles: out of SVM stack space, shader \"%s\" too big.\n",
  183. current_shader->name.c_str());
  184. }
  185. return 0;
  186. }
  187. int SVMCompiler::stack_find_offset(SocketType::Type type)
  188. {
  189. return stack_find_offset(stack_size(type));
  190. }
  191. void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset)
  192. {
  193. int size = stack_size(type);
  194. for (int i = 0; i < size; i++)
  195. active_stack.users[offset + i]--;
  196. }
  197. int SVMCompiler::stack_assign(ShaderInput *input)
  198. {
  199. /* stack offset assign? */
  200. if (input->stack_offset == SVM_STACK_INVALID) {
  201. if (input->link) {
  202. /* linked to output -> use output offset */
  203. assert(input->link->stack_offset != SVM_STACK_INVALID);
  204. input->stack_offset = input->link->stack_offset;
  205. }
  206. else {
  207. Node *node = input->parent;
  208. /* not linked to output -> add nodes to load default value */
  209. input->stack_offset = stack_find_offset(input->type());
  210. if (input->type() == SocketType::FLOAT) {
  211. add_node(NODE_VALUE_F,
  212. __float_as_int(node->get_float(input->socket_type)),
  213. input->stack_offset);
  214. }
  215. else if (input->type() == SocketType::INT) {
  216. add_node(NODE_VALUE_F, node->get_int(input->socket_type), input->stack_offset);
  217. }
  218. else if (input->type() == SocketType::VECTOR || input->type() == SocketType::NORMAL ||
  219. input->type() == SocketType::POINT || input->type() == SocketType::COLOR) {
  220. add_node(NODE_VALUE_V, input->stack_offset);
  221. add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
  222. }
  223. else /* should not get called for closure */
  224. assert(0);
  225. }
  226. }
  227. return input->stack_offset;
  228. }
  229. int SVMCompiler::stack_assign(ShaderOutput *output)
  230. {
  231. /* if no stack offset assigned yet, find one */
  232. if (output->stack_offset == SVM_STACK_INVALID)
  233. output->stack_offset = stack_find_offset(output->type());
  234. return output->stack_offset;
  235. }
  236. int SVMCompiler::stack_assign_if_linked(ShaderInput *input)
  237. {
  238. if (input->link)
  239. return stack_assign(input);
  240. return SVM_STACK_INVALID;
  241. }
  242. int SVMCompiler::stack_assign_if_linked(ShaderOutput *output)
  243. {
  244. if (!output->links.empty())
  245. return stack_assign(output);
  246. return SVM_STACK_INVALID;
  247. }
  248. void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output)
  249. {
  250. if (output->stack_offset == SVM_STACK_INVALID) {
  251. assert(input->link);
  252. assert(stack_size(output->type()) == stack_size(input->link->type()));
  253. output->stack_offset = input->link->stack_offset;
  254. int size = stack_size(output->type());
  255. for (int i = 0; i < size; i++)
  256. active_stack.users[output->stack_offset + i]++;
  257. }
  258. }
  259. void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
  260. {
  261. /* optimization we should add:
  262. * find and lower user counts for outputs for which all inputs are done.
  263. * this is done before the node is compiled, under the assumption that the
  264. * node will first load all inputs from the stack and then writes its
  265. * outputs. this used to work, but was disabled because it gave trouble
  266. * with inputs getting stack positions assigned */
  267. foreach (ShaderInput *input, node->inputs) {
  268. ShaderOutput *output = input->link;
  269. if (output && output->stack_offset != SVM_STACK_INVALID) {
  270. bool all_done = true;
  271. /* optimization we should add: verify if in->parent is actually used */
  272. foreach (ShaderInput *in, output->links)
  273. if (in->parent != node && done.find(in->parent) == done.end())
  274. all_done = false;
  275. if (all_done) {
  276. stack_clear_offset(output->type(), output->stack_offset);
  277. output->stack_offset = SVM_STACK_INVALID;
  278. foreach (ShaderInput *in, output->links)
  279. in->stack_offset = SVM_STACK_INVALID;
  280. }
  281. }
  282. }
  283. }
  284. void SVMCompiler::stack_clear_temporary(ShaderNode *node)
  285. {
  286. foreach (ShaderInput *input, node->inputs) {
  287. if (!input->link && input->stack_offset != SVM_STACK_INVALID) {
  288. stack_clear_offset(input->type(), input->stack_offset);
  289. input->stack_offset = SVM_STACK_INVALID;
  290. }
  291. }
  292. }
  293. uint SVMCompiler::encode_uchar4(uint x, uint y, uint z, uint w)
  294. {
  295. assert(x <= 255);
  296. assert(y <= 255);
  297. assert(z <= 255);
  298. assert(w <= 255);
  299. return (x) | (y << 8) | (z << 16) | (w << 24);
  300. }
  301. void SVMCompiler::add_node(int a, int b, int c, int d)
  302. {
  303. current_svm_nodes.push_back_slow(make_int4(a, b, c, d));
  304. }
  305. void SVMCompiler::add_node(ShaderNodeType type, int a, int b, int c)
  306. {
  307. current_svm_nodes.push_back_slow(make_int4(type, a, b, c));
  308. }
  309. void SVMCompiler::add_node(ShaderNodeType type, const float3 &f)
  310. {
  311. current_svm_nodes.push_back_slow(
  312. make_int4(type, __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z)));
  313. }
  314. void SVMCompiler::add_node(const float4 &f)
  315. {
  316. current_svm_nodes.push_back_slow(make_int4(
  317. __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z), __float_as_int(f.w)));
  318. }
  319. uint SVMCompiler::attribute(ustring name)
  320. {
  321. return shader_manager->get_attribute_id(name);
  322. }
  323. uint SVMCompiler::attribute(AttributeStandard std)
  324. {
  325. return shader_manager->get_attribute_id(std);
  326. }
  327. uint SVMCompiler::attribute_standard(ustring name)
  328. {
  329. AttributeStandard std = Attribute::name_standard(name.c_str());
  330. return (std) ? attribute(std) : attribute(name);
  331. }
  332. void SVMCompiler::find_dependencies(ShaderNodeSet &dependencies,
  333. const ShaderNodeSet &done,
  334. ShaderInput *input,
  335. ShaderNode *skip_node)
  336. {
  337. ShaderNode *node = (input->link) ? input->link->parent : NULL;
  338. if (node != NULL && done.find(node) == done.end() && node != skip_node &&
  339. dependencies.find(node) == dependencies.end()) {
  340. foreach (ShaderInput *in, node->inputs) {
  341. find_dependencies(dependencies, done, in, skip_node);
  342. }
  343. dependencies.insert(node);
  344. }
  345. }
  346. void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet &done)
  347. {
  348. node->compile(*this);
  349. stack_clear_users(node, done);
  350. stack_clear_temporary(node);
  351. if (current_type == SHADER_TYPE_SURFACE) {
  352. if (node->has_spatial_varying())
  353. current_shader->has_surface_spatial_varying = true;
  354. }
  355. else if (current_type == SHADER_TYPE_VOLUME) {
  356. if (node->has_spatial_varying())
  357. current_shader->has_volume_spatial_varying = true;
  358. }
  359. if (node->has_object_dependency()) {
  360. current_shader->has_object_dependency = true;
  361. }
  362. if (node->has_attribute_dependency()) {
  363. current_shader->has_attribute_dependency = true;
  364. }
  365. if (node->has_integrator_dependency()) {
  366. current_shader->has_integrator_dependency = true;
  367. }
  368. }
  369. void SVMCompiler::generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state)
  370. {
  371. ShaderNodeSet &done = state->nodes_done;
  372. vector<bool> &done_flag = state->nodes_done_flag;
  373. bool nodes_done;
  374. do {
  375. nodes_done = true;
  376. foreach (ShaderNode *node, nodes) {
  377. if (!done_flag[node->id]) {
  378. bool inputs_done = true;
  379. foreach (ShaderInput *input, node->inputs) {
  380. if (input->link && !done_flag[input->link->parent->id]) {
  381. inputs_done = false;
  382. }
  383. }
  384. if (inputs_done) {
  385. generate_node(node, done);
  386. done.insert(node);
  387. done_flag[node->id] = true;
  388. }
  389. else {
  390. nodes_done = false;
  391. }
  392. }
  393. }
  394. } while (!nodes_done);
  395. }
  396. void SVMCompiler::generate_closure_node(ShaderNode *node, CompilerState *state)
  397. {
  398. /* execute dependencies for closure */
  399. foreach (ShaderInput *in, node->inputs) {
  400. if (in->link != NULL) {
  401. ShaderNodeSet dependencies;
  402. find_dependencies(dependencies, state->nodes_done, in);
  403. generate_svm_nodes(dependencies, state);
  404. }
  405. }
  406. /* closure mix weight */
  407. const char *weight_name = (current_type == SHADER_TYPE_VOLUME) ? "VolumeMixWeight" :
  408. "SurfaceMixWeight";
  409. ShaderInput *weight_in = node->input(weight_name);
  410. if (weight_in && (weight_in->link || node->get_float(weight_in->socket_type) != 1.0f))
  411. mix_weight_offset = stack_assign(weight_in);
  412. else
  413. mix_weight_offset = SVM_STACK_INVALID;
  414. /* compile closure itself */
  415. generate_node(node, state->nodes_done);
  416. mix_weight_offset = SVM_STACK_INVALID;
  417. if (current_type == SHADER_TYPE_SURFACE) {
  418. if (node->has_surface_emission())
  419. current_shader->has_surface_emission = true;
  420. if (node->has_surface_transparent())
  421. current_shader->has_surface_transparent = true;
  422. if (node->has_surface_bssrdf()) {
  423. current_shader->has_surface_bssrdf = true;
  424. if (node->has_bssrdf_bump())
  425. current_shader->has_bssrdf_bump = true;
  426. }
  427. if (node->has_bump()) {
  428. current_shader->has_bump = true;
  429. }
  430. }
  431. }
  432. void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
  433. ShaderNode *node,
  434. CompilerState *state,
  435. const ShaderNodeSet &shared)
  436. {
  437. if (shared.find(node) != shared.end()) {
  438. generate_multi_closure(root_node, node, state);
  439. }
  440. else {
  441. foreach (ShaderInput *in, node->inputs) {
  442. if (in->type() == SocketType::CLOSURE && in->link)
  443. generated_shared_closure_nodes(root_node, in->link->parent, state, shared);
  444. }
  445. }
  446. }
  447. void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
  448. ShaderNode *node,
  449. CompilerState *state)
  450. {
  451. /* only generate once */
  452. if (state->closure_done.find(node) != state->closure_done.end())
  453. return;
  454. state->closure_done.insert(node);
  455. if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
  456. /* weighting is already taken care of in ShaderGraph::transform_multi_closure */
  457. ShaderInput *cl1in = node->input("Closure1");
  458. ShaderInput *cl2in = node->input("Closure2");
  459. ShaderInput *facin = node->input("Fac");
  460. /* skip empty mix/add closure nodes */
  461. if (!cl1in->link && !cl2in->link)
  462. return;
  463. if (facin && facin->link) {
  464. /* mix closure: generate instructions to compute mix weight */
  465. ShaderNodeSet dependencies;
  466. find_dependencies(dependencies, state->nodes_done, facin);
  467. generate_svm_nodes(dependencies, state);
  468. /* execute shared dependencies. this is needed to allow skipping
  469. * of zero weight closures and their dependencies later, so we
  470. * ensure that they only skip dependencies that are unique to them */
  471. ShaderNodeSet cl1deps, cl2deps, shareddeps;
  472. find_dependencies(cl1deps, state->nodes_done, cl1in);
  473. find_dependencies(cl2deps, state->nodes_done, cl2in);
  474. ShaderNodeIDComparator node_id_comp;
  475. set_intersection(cl1deps.begin(),
  476. cl1deps.end(),
  477. cl2deps.begin(),
  478. cl2deps.end(),
  479. std::inserter(shareddeps, shareddeps.begin()),
  480. node_id_comp);
  481. /* it's possible some nodes are not shared between this mix node
  482. * inputs, but still needed to be always executed, this mainly
  483. * happens when a node of current subbranch is used by a parent
  484. * node or so */
  485. if (root_node != node) {
  486. foreach (ShaderInput *in, root_node->inputs) {
  487. ShaderNodeSet rootdeps;
  488. find_dependencies(rootdeps, state->nodes_done, in, node);
  489. set_intersection(rootdeps.begin(),
  490. rootdeps.end(),
  491. cl1deps.begin(),
  492. cl1deps.end(),
  493. std::inserter(shareddeps, shareddeps.begin()),
  494. node_id_comp);
  495. set_intersection(rootdeps.begin(),
  496. rootdeps.end(),
  497. cl2deps.begin(),
  498. cl2deps.end(),
  499. std::inserter(shareddeps, shareddeps.begin()),
  500. node_id_comp);
  501. }
  502. }
  503. if (!shareddeps.empty()) {
  504. if (cl1in->link) {
  505. generated_shared_closure_nodes(root_node, cl1in->link->parent, state, shareddeps);
  506. }
  507. if (cl2in->link) {
  508. generated_shared_closure_nodes(root_node, cl2in->link->parent, state, shareddeps);
  509. }
  510. generate_svm_nodes(shareddeps, state);
  511. }
  512. /* generate instructions for input closure 1 */
  513. if (cl1in->link) {
  514. /* Add instruction to skip closure and its dependencies if mix
  515. * weight is zero.
  516. */
  517. current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ONE, 0, stack_assign(facin), 0));
  518. int node_jump_skip_index = current_svm_nodes.size() - 1;
  519. generate_multi_closure(root_node, cl1in->link->parent, state);
  520. /* Fill in jump instruction location to be after closure. */
  521. current_svm_nodes[node_jump_skip_index].y = current_svm_nodes.size() -
  522. node_jump_skip_index - 1;
  523. }
  524. /* generate instructions for input closure 2 */
  525. if (cl2in->link) {
  526. /* Add instruction to skip closure and its dependencies if mix
  527. * weight is zero.
  528. */
  529. current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ZERO, 0, stack_assign(facin), 0));
  530. int node_jump_skip_index = current_svm_nodes.size() - 1;
  531. generate_multi_closure(root_node, cl2in->link->parent, state);
  532. /* Fill in jump instruction location to be after closure. */
  533. current_svm_nodes[node_jump_skip_index].y = current_svm_nodes.size() -
  534. node_jump_skip_index - 1;
  535. }
  536. /* unassign */
  537. facin->stack_offset = SVM_STACK_INVALID;
  538. }
  539. else {
  540. /* execute closures and their dependencies, no runtime checks
  541. * to skip closures here because was already optimized due to
  542. * fixed weight or add closure that always needs both */
  543. if (cl1in->link)
  544. generate_multi_closure(root_node, cl1in->link->parent, state);
  545. if (cl2in->link)
  546. generate_multi_closure(root_node, cl2in->link->parent, state);
  547. }
  548. }
  549. else {
  550. generate_closure_node(node, state);
  551. }
  552. state->nodes_done.insert(node);
  553. state->nodes_done_flag[node->id] = true;
  554. }
  555. void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
  556. {
  557. /* Converting a shader graph into svm_nodes that can be executed
  558. * sequentially on the virtual machine is fairly simple. We can keep
  559. * looping over nodes and each time all the inputs of a node are
  560. * ready, we add svm_nodes for it that read the inputs from the
  561. * stack and write outputs back to the stack.
  562. *
  563. * With the SVM, we always sample only a single closure. We can think
  564. * of all closures nodes as a binary tree with mix closures as inner
  565. * nodes and other closures as leafs. The SVM will traverse that tree,
  566. * each time deciding to go left or right depending on the mix weights,
  567. * until a closure is found.
  568. *
  569. * We only execute nodes that are needed for the mix weights and chosen
  570. * closure.
  571. */
  572. current_type = type;
  573. current_graph = graph;
  574. /* get input in output node */
  575. ShaderNode *node = graph->output();
  576. ShaderInput *clin = NULL;
  577. switch (type) {
  578. case SHADER_TYPE_SURFACE:
  579. clin = node->input("Surface");
  580. break;
  581. case SHADER_TYPE_VOLUME:
  582. clin = node->input("Volume");
  583. break;
  584. case SHADER_TYPE_DISPLACEMENT:
  585. clin = node->input("Displacement");
  586. break;
  587. case SHADER_TYPE_BUMP:
  588. clin = node->input("Normal");
  589. break;
  590. default:
  591. assert(0);
  592. break;
  593. }
  594. /* clear all compiler state */
  595. memset((void *)&active_stack, 0, sizeof(active_stack));
  596. current_svm_nodes.clear();
  597. foreach (ShaderNode *node_iter, graph->nodes) {
  598. foreach (ShaderInput *input, node_iter->inputs)
  599. input->stack_offset = SVM_STACK_INVALID;
  600. foreach (ShaderOutput *output, node_iter->outputs)
  601. output->stack_offset = SVM_STACK_INVALID;
  602. }
  603. /* for the bump shader we need add a node to store the shader state */
  604. bool need_bump_state = (type == SHADER_TYPE_BUMP) &&
  605. (shader->displacement_method == DISPLACE_BOTH);
  606. int bump_state_offset = SVM_STACK_INVALID;
  607. if (need_bump_state) {
  608. bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE);
  609. add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset);
  610. }
  611. if (shader->used) {
  612. if (clin->link) {
  613. bool generate = false;
  614. switch (type) {
  615. case SHADER_TYPE_SURFACE: /* generate surface shader */
  616. generate = true;
  617. shader->has_surface = true;
  618. break;
  619. case SHADER_TYPE_VOLUME: /* generate volume shader */
  620. generate = true;
  621. shader->has_volume = true;
  622. break;
  623. case SHADER_TYPE_DISPLACEMENT: /* generate displacement shader */
  624. generate = true;
  625. shader->has_displacement = true;
  626. break;
  627. case SHADER_TYPE_BUMP: /* generate bump shader */
  628. generate = true;
  629. break;
  630. default:
  631. break;
  632. }
  633. if (generate) {
  634. CompilerState state(graph);
  635. generate_multi_closure(clin->link->parent, clin->link->parent, &state);
  636. }
  637. }
  638. /* compile output node */
  639. node->compile(*this);
  640. }
  641. /* add node to restore state after bump shader has finished */
  642. if (need_bump_state) {
  643. add_node(NODE_LEAVE_BUMP_EVAL, bump_state_offset);
  644. }
  645. /* if compile failed, generate empty shader */
  646. if (compile_failed) {
  647. current_svm_nodes.clear();
  648. compile_failed = false;
  649. }
  650. /* for bump shaders we fall thru to the surface shader, but if this is any other kind of shader
  651. * it ends here */
  652. if (type != SHADER_TYPE_BUMP) {
  653. add_node(NODE_END, 0, 0, 0);
  654. }
  655. }
  656. void SVMCompiler::compile(
  657. Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary)
  658. {
  659. /* copy graph for shader with bump mapping */
  660. ShaderNode *output = shader->graph->output();
  661. int start_num_svm_nodes = svm_nodes.size();
  662. const double time_start = time_dt();
  663. bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
  664. output->input("Surface")->link && output->input("Displacement")->link;
  665. /* finalize */
  666. {
  667. scoped_timer timer((summary != NULL) ? &summary->time_finalize : NULL);
  668. shader->graph->finalize(scene,
  669. has_bump,
  670. shader->has_integrator_dependency,
  671. shader->displacement_method == DISPLACE_BOTH);
  672. }
  673. current_shader = shader;
  674. shader->has_surface = false;
  675. shader->has_surface_emission = false;
  676. shader->has_surface_transparent = false;
  677. shader->has_surface_bssrdf = false;
  678. shader->has_bump = has_bump;
  679. shader->has_bssrdf_bump = has_bump;
  680. shader->has_volume = false;
  681. shader->has_displacement = false;
  682. shader->has_surface_spatial_varying = false;
  683. shader->has_volume_spatial_varying = false;
  684. shader->has_object_dependency = false;
  685. shader->has_attribute_dependency = false;
  686. shader->has_integrator_dependency = false;
  687. /* generate bump shader */
  688. if (has_bump) {
  689. scoped_timer timer((summary != NULL) ? &summary->time_generate_bump : NULL);
  690. compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
  691. svm_nodes[index].y = svm_nodes.size();
  692. svm_nodes.append(current_svm_nodes);
  693. }
  694. /* generate surface shader */
  695. {
  696. scoped_timer timer((summary != NULL) ? &summary->time_generate_surface : NULL);
  697. compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
  698. /* only set jump offset if there's no bump shader, as the bump shader will fall thru to this
  699. * one if it exists */
  700. if (!has_bump) {
  701. svm_nodes[index].y = svm_nodes.size();
  702. }
  703. svm_nodes.append(current_svm_nodes);
  704. }
  705. /* generate volume shader */
  706. {
  707. scoped_timer timer((summary != NULL) ? &summary->time_generate_volume : NULL);
  708. compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
  709. svm_nodes[index].z = svm_nodes.size();
  710. svm_nodes.append(current_svm_nodes);
  711. }
  712. /* generate displacement shader */
  713. {
  714. scoped_timer timer((summary != NULL) ? &summary->time_generate_displacement : NULL);
  715. compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
  716. svm_nodes[index].w = svm_nodes.size();
  717. svm_nodes.append(current_svm_nodes);
  718. }
  719. /* Fill in summary information. */
  720. if (summary != NULL) {
  721. summary->time_total = time_dt() - time_start;
  722. summary->peak_stack_usage = max_stack_use;
  723. summary->num_svm_nodes = svm_nodes.size() - start_num_svm_nodes;
  724. }
  725. }
  726. /* Compiler summary implementation. */
  727. SVMCompiler::Summary::Summary()
  728. : num_svm_nodes(0),
  729. peak_stack_usage(0),
  730. time_finalize(0.0),
  731. time_generate_surface(0.0),
  732. time_generate_bump(0.0),
  733. time_generate_volume(0.0),
  734. time_generate_displacement(0.0),
  735. time_total(0.0)
  736. {
  737. }
  738. string SVMCompiler::Summary::full_report() const
  739. {
  740. string report = "";
  741. report += string_printf("Number of SVM nodes: %d\n", num_svm_nodes);
  742. report += string_printf("Peak stack usage: %d\n", peak_stack_usage);
  743. report += string_printf("Time (in seconds):\n");
  744. report += string_printf("Finalize: %f\n", time_finalize);
  745. report += string_printf(" Surface: %f\n", time_generate_surface);
  746. report += string_printf(" Bump: %f\n", time_generate_bump);
  747. report += string_printf(" Volume: %f\n", time_generate_volume);
  748. report += string_printf(" Displacement: %f\n", time_generate_displacement);
  749. report += string_printf("Generate: %f\n",
  750. time_generate_surface + time_generate_bump + time_generate_volume +
  751. time_generate_displacement);
  752. report += string_printf("Total: %f\n", time_total);
  753. return report;
  754. }
  755. /* Global state of the compiler. */
  756. SVMCompiler::CompilerState::CompilerState(ShaderGraph *graph)
  757. {
  758. int max_id = 0;
  759. foreach (ShaderNode *node, graph->nodes) {
  760. max_id = max(node->id, max_id);
  761. }
  762. nodes_done_flag.resize(max_id + 1, false);
  763. }
  764. CCL_NAMESPACE_END