svm.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. #ifndef __SVM_H__
  17. #define __SVM_H__
  18. #include "render/attribute.h"
  19. #include "render/graph.h"
  20. #include "render/shader.h"
  21. #include "util/util_array.h"
  22. #include "util/util_set.h"
  23. #include "util/util_string.h"
  24. #include "util/util_thread.h"
  25. CCL_NAMESPACE_BEGIN
  26. class Device;
  27. class DeviceScene;
  28. class ImageManager;
  29. class Scene;
  30. class ShaderGraph;
  31. class ShaderInput;
  32. class ShaderNode;
  33. class ShaderOutput;
  34. /* Shader Manager */
  35. class SVMShaderManager : public ShaderManager {
  36. public:
  37. SVMShaderManager();
  38. ~SVMShaderManager();
  39. void reset(Scene *scene);
  40. void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
  41. void device_free(Device *device, DeviceScene *dscene, Scene *scene);
  42. protected:
  43. /* Lock used to synchronize threaded nodes compilation. */
  44. thread_spin_lock nodes_lock_;
  45. void device_update_shader(Scene *scene,
  46. Shader *shader,
  47. Progress *progress,
  48. array<int4> *global_svm_nodes);
  49. };
  50. /* Graph Compiler */
  51. class SVMCompiler {
  52. public:
  53. struct Summary {
  54. Summary();
  55. /* Number of SVM nodes shader was compiled into. */
  56. int num_svm_nodes;
  57. /* Peak stack usage during shader evaluation. */
  58. int peak_stack_usage;
  59. /* Time spent on surface graph finalization. */
  60. double time_finalize;
  61. /* Time spent on generating SVM nodes for surface shader. */
  62. double time_generate_surface;
  63. /* Time spent on generating SVM nodes for bump shader. */
  64. double time_generate_bump;
  65. /* Time spent on generating SVM nodes for volume shader. */
  66. double time_generate_volume;
  67. /* Time spent on generating SVM nodes for displacement shader. */
  68. double time_generate_displacement;
  69. /* Total time spent on all routines. */
  70. double time_total;
  71. /* A full multiline description of the state of the compiler after
  72. * compilation.
  73. */
  74. string full_report() const;
  75. };
  76. SVMCompiler(ShaderManager *shader_manager,
  77. ImageManager *image_manager,
  78. LightManager *light_manager);
  79. void compile(
  80. Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary = NULL);
  81. int stack_assign(ShaderOutput *output);
  82. int stack_assign(ShaderInput *input);
  83. int stack_assign_if_linked(ShaderInput *input);
  84. int stack_assign_if_linked(ShaderOutput *output);
  85. int stack_find_offset(int size);
  86. int stack_find_offset(SocketType::Type type);
  87. void stack_clear_offset(SocketType::Type type, int offset);
  88. void stack_link(ShaderInput *input, ShaderOutput *output);
  89. void add_node(ShaderNodeType type, int a = 0, int b = 0, int c = 0);
  90. void add_node(int a = 0, int b = 0, int c = 0, int d = 0);
  91. void add_node(ShaderNodeType type, const float3 &f);
  92. void add_node(const float4 &f);
  93. uint attribute(ustring name);
  94. uint attribute(AttributeStandard std);
  95. uint attribute_standard(ustring name);
  96. uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
  97. uint closure_mix_weight_offset()
  98. {
  99. return mix_weight_offset;
  100. }
  101. ShaderType output_type()
  102. {
  103. return current_type;
  104. }
  105. ImageManager *image_manager;
  106. ShaderManager *shader_manager;
  107. LightManager *light_manager;
  108. bool background;
  109. protected:
  110. /* stack */
  111. struct Stack {
  112. Stack()
  113. {
  114. memset(users, 0, sizeof(users));
  115. }
  116. Stack(const Stack &other)
  117. {
  118. memcpy(users, other.users, sizeof(users));
  119. }
  120. Stack &operator=(const Stack &other)
  121. {
  122. memcpy(users, other.users, sizeof(users));
  123. return *this;
  124. }
  125. bool empty()
  126. {
  127. for (int i = 0; i < SVM_STACK_SIZE; i++)
  128. if (users[i])
  129. return false;
  130. return true;
  131. }
  132. void print()
  133. {
  134. printf("stack <");
  135. for (int i = 0; i < SVM_STACK_SIZE; i++)
  136. printf((users[i]) ? "*" : " ");
  137. printf(">\n");
  138. }
  139. int users[SVM_STACK_SIZE];
  140. };
  141. /* Global state of the compiler accessible from the compilation routines. */
  142. struct CompilerState {
  143. explicit CompilerState(ShaderGraph *graph);
  144. /* ** Global state, used by various compilation steps. ** */
  145. /* Set of nodes which were already compiled. */
  146. ShaderNodeSet nodes_done;
  147. /* Set of closures which were already compiled. */
  148. ShaderNodeSet closure_done;
  149. /* ** SVM nodes generation state ** */
  150. /* Flag whether the node with corresponding ID was already compiled or
  151. * not. Array element with index i corresponds to a node with such if.
  152. *
  153. * TODO(sergey): This is actually a copy of nodes_done just in another
  154. * notation. We can de-duplicate this storage actually after switching
  155. * all areas to use this flags array.
  156. */
  157. vector<bool> nodes_done_flag;
  158. };
  159. void stack_clear_temporary(ShaderNode *node);
  160. int stack_size(SocketType::Type type);
  161. void stack_clear_users(ShaderNode *node, ShaderNodeSet &done);
  162. /* single closure */
  163. void find_dependencies(ShaderNodeSet &dependencies,
  164. const ShaderNodeSet &done,
  165. ShaderInput *input,
  166. ShaderNode *skip_node = NULL);
  167. void generate_node(ShaderNode *node, ShaderNodeSet &done);
  168. void generate_closure_node(ShaderNode *node, CompilerState *state);
  169. void generated_shared_closure_nodes(ShaderNode *root_node,
  170. ShaderNode *node,
  171. CompilerState *state,
  172. const ShaderNodeSet &shared);
  173. void generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state);
  174. /* multi closure */
  175. void generate_multi_closure(ShaderNode *root_node, ShaderNode *node, CompilerState *state);
  176. /* compile */
  177. void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
  178. array<int4> current_svm_nodes;
  179. ShaderType current_type;
  180. Shader *current_shader;
  181. ShaderGraph *current_graph;
  182. Stack active_stack;
  183. int max_stack_use;
  184. uint mix_weight_offset;
  185. bool compile_failed;
  186. };
  187. CCL_NAMESPACE_END
  188. #endif /* __SVM_H__ */