render_graph_finalize_test.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. /*
  2. * Copyright 2011-2016 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 "testing/testing.h"
  17. #include "testing/mock_log.h"
  18. #include "render/graph.h"
  19. #include "render/scene.h"
  20. #include "render/nodes.h"
  21. #include "util/util_array.h"
  22. #include "util/util_logging.h"
  23. #include "util/util_string.h"
  24. #include "util/util_vector.h"
  25. using testing::_;
  26. using testing::AnyNumber;
  27. using testing::HasSubstr;
  28. using testing::ScopedMockLog;
  29. CCL_NAMESPACE_BEGIN
  30. namespace {
  31. template<typename T> class ShaderNodeBuilder {
  32. public:
  33. ShaderNodeBuilder(const string &name) : name_(name)
  34. {
  35. node_ = new T();
  36. node_->name = name;
  37. }
  38. const string &name() const
  39. {
  40. return name_;
  41. }
  42. ShaderNode *node() const
  43. {
  44. return node_;
  45. }
  46. template<typename V> ShaderNodeBuilder &set(const string &input_name, V value)
  47. {
  48. ShaderInput *input_socket = node_->input(input_name.c_str());
  49. EXPECT_NE((void *)NULL, input_socket);
  50. input_socket->set(value);
  51. return *this;
  52. }
  53. template<typename T2, typename V> ShaderNodeBuilder &set(V T2::*pfield, V value)
  54. {
  55. static_cast<T *>(node_)->*pfield = value;
  56. return *this;
  57. }
  58. protected:
  59. string name_;
  60. ShaderNode *node_;
  61. };
  62. class ShaderGraphBuilder {
  63. public:
  64. ShaderGraphBuilder(ShaderGraph *graph) : graph_(graph)
  65. {
  66. node_map_["Output"] = graph->output();
  67. }
  68. ShaderNode *find_node(const string &name)
  69. {
  70. map<string, ShaderNode *>::iterator it = node_map_.find(name);
  71. if (it == node_map_.end()) {
  72. return NULL;
  73. }
  74. return it->second;
  75. }
  76. template<typename T> ShaderGraphBuilder &add_node(const T &node)
  77. {
  78. EXPECT_EQ(find_node(node.name()), (void *)NULL);
  79. graph_->add(node.node());
  80. node_map_[node.name()] = node.node();
  81. return *this;
  82. }
  83. ShaderGraphBuilder &add_connection(const string &from, const string &to)
  84. {
  85. vector<string> tokens_from, tokens_to;
  86. string_split(tokens_from, from, "::");
  87. string_split(tokens_to, to, "::");
  88. EXPECT_EQ(tokens_from.size(), 2);
  89. EXPECT_EQ(tokens_to.size(), 2);
  90. ShaderNode *node_from = find_node(tokens_from[0]), *node_to = find_node(tokens_to[0]);
  91. EXPECT_NE((void *)NULL, node_from);
  92. EXPECT_NE((void *)NULL, node_to);
  93. EXPECT_NE(node_from, node_to);
  94. ShaderOutput *socket_from = node_from->output(tokens_from[1].c_str());
  95. ShaderInput *socket_to = node_to->input(tokens_to[1].c_str());
  96. EXPECT_NE((void *)NULL, socket_from);
  97. EXPECT_NE((void *)NULL, socket_to);
  98. graph_->connect(socket_from, socket_to);
  99. return *this;
  100. }
  101. /* Common input/output boilerplate. */
  102. ShaderGraphBuilder &add_attribute(const string &name)
  103. {
  104. return (*this).add_node(
  105. ShaderNodeBuilder<AttributeNode>(name).set(&AttributeNode::attribute, ustring(name)));
  106. }
  107. ShaderGraphBuilder &output_closure(const string &from)
  108. {
  109. return (*this).add_connection(from, "Output::Surface");
  110. }
  111. ShaderGraphBuilder &output_color(const string &from)
  112. {
  113. return (*this)
  114. .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
  115. .add_connection(from, "EmissionNode::Color")
  116. .output_closure("EmissionNode::Emission");
  117. }
  118. ShaderGraphBuilder &output_value(const string &from)
  119. {
  120. return (*this)
  121. .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
  122. .add_connection(from, "EmissionNode::Strength")
  123. .output_closure("EmissionNode::Emission");
  124. }
  125. protected:
  126. ShaderGraph *graph_;
  127. map<string, ShaderNode *> node_map_;
  128. };
  129. } // namespace
  130. class RenderGraph : public testing::Test {
  131. protected:
  132. ScopedMockLog log;
  133. Stats stats;
  134. Profiler profiler;
  135. DeviceInfo device_info;
  136. Device *device_cpu;
  137. SceneParams scene_params;
  138. Scene *scene;
  139. ShaderGraph graph;
  140. ShaderGraphBuilder builder;
  141. RenderGraph() : testing::Test(), builder(&graph)
  142. {
  143. }
  144. virtual void SetUp()
  145. {
  146. util_logging_start();
  147. util_logging_verbosity_set(1);
  148. device_cpu = Device::create(device_info, stats, profiler, true);
  149. scene = new Scene(scene_params, device_cpu);
  150. }
  151. virtual void TearDown()
  152. {
  153. delete scene;
  154. delete device_cpu;
  155. }
  156. };
  157. #define EXPECT_ANY_MESSAGE(log) EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  158. #define CORRECT_INFO_MESSAGE(log, message) \
  159. EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message)));
  160. #define INVALID_INFO_MESSAGE(log, message) \
  161. EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message))).Times(0);
  162. /*
  163. * Test deduplication of nodes that have inputs, some of them folded.
  164. */
  165. TEST_F(RenderGraph, deduplicate_deep)
  166. {
  167. EXPECT_ANY_MESSAGE(log);
  168. CORRECT_INFO_MESSAGE(log, "Folding Value1::Value to constant (0.8).");
  169. CORRECT_INFO_MESSAGE(log, "Folding Value2::Value to constant (0.8).");
  170. CORRECT_INFO_MESSAGE(log, "Deduplicated 2 nodes.");
  171. builder.add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
  172. .add_node(ShaderNodeBuilder<GeometryNode>("Geometry2"))
  173. .add_node(ShaderNodeBuilder<ValueNode>("Value1").set(&ValueNode::value, 0.8f))
  174. .add_node(ShaderNodeBuilder<ValueNode>("Value2").set(&ValueNode::value, 0.8f))
  175. .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise1"))
  176. .add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise2"))
  177. .add_node(
  178. ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_BLEND).set("Fac", 0.5f))
  179. .add_connection("Geometry1::Parametric", "Noise1::Vector")
  180. .add_connection("Value1::Value", "Noise1::Scale")
  181. .add_connection("Noise1::Color", "Mix::Color1")
  182. .add_connection("Geometry2::Parametric", "Noise2::Vector")
  183. .add_connection("Value2::Value", "Noise2::Scale")
  184. .add_connection("Noise2::Color", "Mix::Color2")
  185. .output_color("Mix::Color");
  186. graph.finalize(scene);
  187. EXPECT_EQ(graph.nodes.size(), 5);
  188. }
  189. /*
  190. * Test RGB to BW node.
  191. */
  192. TEST_F(RenderGraph, constant_fold_rgb_to_bw)
  193. {
  194. EXPECT_ANY_MESSAGE(log);
  195. CORRECT_INFO_MESSAGE(log, "Folding RGBToBWNodeNode::Val to constant (0.8).");
  196. CORRECT_INFO_MESSAGE(log,
  197. "Folding convert_float_to_color::value_color to constant (0.8, 0.8, 0.8).");
  198. builder
  199. .add_node(ShaderNodeBuilder<RGBToBWNode>("RGBToBWNodeNode")
  200. .set("Color", make_float3(0.8f, 0.8f, 0.8f)))
  201. .output_color("RGBToBWNodeNode::Val");
  202. graph.finalize(scene);
  203. }
  204. /*
  205. * Tests:
  206. * - folding of Emission nodes that don't emit to nothing.
  207. */
  208. TEST_F(RenderGraph, constant_fold_emission1)
  209. {
  210. EXPECT_ANY_MESSAGE(log);
  211. CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
  212. builder
  213. .add_node(
  214. ShaderNodeBuilder<EmissionNode>("Emission").set("Color", make_float3(0.0f, 0.0f, 0.0f)))
  215. .output_closure("Emission::Emission");
  216. graph.finalize(scene);
  217. }
  218. TEST_F(RenderGraph, constant_fold_emission2)
  219. {
  220. EXPECT_ANY_MESSAGE(log);
  221. CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
  222. builder.add_node(ShaderNodeBuilder<EmissionNode>("Emission").set("Strength", 0.0f))
  223. .output_closure("Emission::Emission");
  224. graph.finalize(scene);
  225. }
  226. /*
  227. * Tests:
  228. * - folding of Background nodes that don't emit to nothing.
  229. */
  230. TEST_F(RenderGraph, constant_fold_background1)
  231. {
  232. EXPECT_ANY_MESSAGE(log);
  233. CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
  234. builder
  235. .add_node(ShaderNodeBuilder<BackgroundNode>("Background")
  236. .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
  237. .output_closure("Background::Background");
  238. graph.finalize(scene);
  239. }
  240. TEST_F(RenderGraph, constant_fold_background2)
  241. {
  242. EXPECT_ANY_MESSAGE(log);
  243. CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
  244. builder.add_node(ShaderNodeBuilder<BackgroundNode>("Background").set("Strength", 0.0f))
  245. .output_closure("Background::Background");
  246. graph.finalize(scene);
  247. }
  248. /*
  249. * Tests:
  250. * - Folding of Add Closure with only one input.
  251. */
  252. TEST_F(RenderGraph, constant_fold_shader_add)
  253. {
  254. EXPECT_ANY_MESSAGE(log);
  255. CORRECT_INFO_MESSAGE(log, "Folding AddClosure1::Closure to socket Diffuse::BSDF.");
  256. CORRECT_INFO_MESSAGE(log, "Folding AddClosure2::Closure to socket Diffuse::BSDF.");
  257. INVALID_INFO_MESSAGE(log, "Folding AddClosure3");
  258. builder.add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
  259. .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure1"))
  260. .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure2"))
  261. .add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure3"))
  262. .add_connection("Diffuse::BSDF", "AddClosure1::Closure1")
  263. .add_connection("Diffuse::BSDF", "AddClosure2::Closure2")
  264. .add_connection("AddClosure1::Closure", "AddClosure3::Closure1")
  265. .add_connection("AddClosure2::Closure", "AddClosure3::Closure2")
  266. .output_closure("AddClosure3::Closure");
  267. graph.finalize(scene);
  268. }
  269. /*
  270. * Tests:
  271. * - Folding of Mix Closure with 0 or 1 fac.
  272. * - Folding of Mix Closure with both inputs folded to the same node.
  273. */
  274. TEST_F(RenderGraph, constant_fold_shader_mix)
  275. {
  276. EXPECT_ANY_MESSAGE(log);
  277. CORRECT_INFO_MESSAGE(log, "Folding MixClosure1::Closure to socket Diffuse::BSDF.");
  278. CORRECT_INFO_MESSAGE(log, "Folding MixClosure2::Closure to socket Diffuse::BSDF.");
  279. CORRECT_INFO_MESSAGE(log, "Folding MixClosure3::Closure to socket Diffuse::BSDF.");
  280. builder.add_attribute("Attribute")
  281. .add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
  282. /* choose left */
  283. .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure1").set("Fac", 0.0f))
  284. .add_connection("Diffuse::BSDF", "MixClosure1::Closure1")
  285. /* choose right */
  286. .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure2").set("Fac", 1.0f))
  287. .add_connection("Diffuse::BSDF", "MixClosure2::Closure2")
  288. /* both inputs folded the same */
  289. .add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure3"))
  290. .add_connection("Attribute::Fac", "MixClosure3::Fac")
  291. .add_connection("MixClosure1::Closure", "MixClosure3::Closure1")
  292. .add_connection("MixClosure2::Closure", "MixClosure3::Closure2")
  293. .output_closure("MixClosure3::Closure");
  294. graph.finalize(scene);
  295. }
  296. /*
  297. * Tests:
  298. * - Folding of Invert with all constant inputs.
  299. */
  300. TEST_F(RenderGraph, constant_fold_invert)
  301. {
  302. EXPECT_ANY_MESSAGE(log);
  303. CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.68, 0.5, 0.32).");
  304. builder
  305. .add_node(ShaderNodeBuilder<InvertNode>("Invert")
  306. .set("Fac", 0.8f)
  307. .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
  308. .output_color("Invert::Color");
  309. graph.finalize(scene);
  310. }
  311. /*
  312. * Tests:
  313. * - Folding of Invert with zero Fac.
  314. */
  315. TEST_F(RenderGraph, constant_fold_invert_fac_0)
  316. {
  317. EXPECT_ANY_MESSAGE(log);
  318. CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to socket Attribute::Color.");
  319. builder.add_attribute("Attribute")
  320. .add_node(ShaderNodeBuilder<InvertNode>("Invert").set("Fac", 0.0f))
  321. .add_connection("Attribute::Color", "Invert::Color")
  322. .output_color("Invert::Color");
  323. graph.finalize(scene);
  324. }
  325. /*
  326. * Tests:
  327. * - Folding of Invert with zero Fac and constant input.
  328. */
  329. TEST_F(RenderGraph, constant_fold_invert_fac_0_const)
  330. {
  331. EXPECT_ANY_MESSAGE(log);
  332. CORRECT_INFO_MESSAGE(log, "Folding Invert::Color to constant (0.2, 0.5, 0.8).");
  333. builder
  334. .add_node(ShaderNodeBuilder<InvertNode>("Invert")
  335. .set("Fac", 0.0f)
  336. .set("Color", make_float3(0.2f, 0.5f, 0.8f)))
  337. .output_color("Invert::Color");
  338. graph.finalize(scene);
  339. }
  340. /*
  341. * Tests:
  342. * - Folding of MixRGB Add with all constant inputs (clamp false).
  343. */
  344. TEST_F(RenderGraph, constant_fold_mix_add)
  345. {
  346. EXPECT_ANY_MESSAGE(log);
  347. CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1.14, 1.42).");
  348. builder
  349. .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
  350. .set(&MixNode::type, NODE_MIX_ADD)
  351. .set(&MixNode::use_clamp, false)
  352. .set("Fac", 0.8f)
  353. .set("Color1", make_float3(0.3, 0.5, 0.7))
  354. .set("Color2", make_float3(0.4, 0.8, 0.9)))
  355. .output_color("MixAdd::Color");
  356. graph.finalize(scene);
  357. }
  358. /*
  359. * Tests:
  360. * - Folding of MixRGB Add with all constant inputs (clamp true).
  361. */
  362. TEST_F(RenderGraph, constant_fold_mix_add_clamp)
  363. {
  364. EXPECT_ANY_MESSAGE(log);
  365. CORRECT_INFO_MESSAGE(log, "Folding MixAdd::Color to constant (0.62, 1, 1).");
  366. builder
  367. .add_node(ShaderNodeBuilder<MixNode>("MixAdd")
  368. .set(&MixNode::type, NODE_MIX_ADD)
  369. .set(&MixNode::use_clamp, true)
  370. .set("Fac", 0.8f)
  371. .set("Color1", make_float3(0.3, 0.5, 0.7))
  372. .set("Color2", make_float3(0.4, 0.8, 0.9)))
  373. .output_color("MixAdd::Color");
  374. graph.finalize(scene);
  375. }
  376. /*
  377. * Tests:
  378. * - No folding on fac 0 for dodge.
  379. */
  380. TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0)
  381. {
  382. EXPECT_ANY_MESSAGE(log);
  383. INVALID_INFO_MESSAGE(log, "Folding ");
  384. builder.add_attribute("Attribute1")
  385. .add_attribute("Attribute2")
  386. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  387. .set(&MixNode::type, NODE_MIX_DODGE)
  388. .set(&MixNode::use_clamp, false)
  389. .set("Fac", 0.0f))
  390. .add_connection("Attribute1::Color", "Mix::Color1")
  391. .add_connection("Attribute2::Color", "Mix::Color2")
  392. .output_color("Mix::Color");
  393. graph.finalize(scene);
  394. }
  395. /*
  396. * Tests:
  397. * - No folding on fac 0 for light.
  398. */
  399. TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0)
  400. {
  401. EXPECT_ANY_MESSAGE(log);
  402. INVALID_INFO_MESSAGE(log, "Folding ");
  403. builder.add_attribute("Attribute1")
  404. .add_attribute("Attribute2")
  405. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  406. .set(&MixNode::type, NODE_MIX_LIGHT)
  407. .set(&MixNode::use_clamp, false)
  408. .set("Fac", 0.0f))
  409. .add_connection("Attribute1::Color", "Mix::Color1")
  410. .add_connection("Attribute2::Color", "Mix::Color2")
  411. .output_color("Mix::Color");
  412. graph.finalize(scene);
  413. }
  414. /*
  415. * Tests:
  416. * - No folding on fac 0 for burn.
  417. */
  418. TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0)
  419. {
  420. EXPECT_ANY_MESSAGE(log);
  421. INVALID_INFO_MESSAGE(log, "Folding ");
  422. builder.add_attribute("Attribute1")
  423. .add_attribute("Attribute2")
  424. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  425. .set(&MixNode::type, NODE_MIX_BURN)
  426. .set(&MixNode::use_clamp, false)
  427. .set("Fac", 0.0f))
  428. .add_connection("Attribute1::Color", "Mix::Color1")
  429. .add_connection("Attribute2::Color", "Mix::Color2")
  430. .output_color("Mix::Color");
  431. graph.finalize(scene);
  432. }
  433. /*
  434. * Tests:
  435. * - No folding on fac 0 for clamped blend.
  436. */
  437. TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0)
  438. {
  439. EXPECT_ANY_MESSAGE(log);
  440. INVALID_INFO_MESSAGE(log, "Folding ");
  441. builder.add_attribute("Attribute1")
  442. .add_attribute("Attribute2")
  443. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  444. .set(&MixNode::type, NODE_MIX_BLEND)
  445. .set(&MixNode::use_clamp, true)
  446. .set("Fac", 0.0f))
  447. .add_connection("Attribute1::Color", "Mix::Color1")
  448. .add_connection("Attribute2::Color", "Mix::Color2")
  449. .output_color("Mix::Color");
  450. graph.finalize(scene);
  451. }
  452. /*
  453. * Tests:
  454. * - Folding of Mix with 0 or 1 Fac.
  455. * - Folding of Mix with both inputs folded to the same node.
  456. */
  457. TEST_F(RenderGraph, constant_fold_part_mix_blend)
  458. {
  459. EXPECT_ANY_MESSAGE(log);
  460. CORRECT_INFO_MESSAGE(log, "Folding MixBlend1::Color to socket Attribute1::Color.");
  461. CORRECT_INFO_MESSAGE(log, "Folding MixBlend2::Color to socket Attribute1::Color.");
  462. CORRECT_INFO_MESSAGE(log, "Folding MixBlend3::Color to socket Attribute1::Color.");
  463. builder.add_attribute("Attribute1")
  464. .add_attribute("Attribute2")
  465. /* choose left */
  466. .add_node(ShaderNodeBuilder<MixNode>("MixBlend1")
  467. .set(&MixNode::type, NODE_MIX_BLEND)
  468. .set(&MixNode::use_clamp, false)
  469. .set("Fac", 0.0f))
  470. .add_connection("Attribute1::Color", "MixBlend1::Color1")
  471. .add_connection("Attribute2::Color", "MixBlend1::Color2")
  472. /* choose right */
  473. .add_node(ShaderNodeBuilder<MixNode>("MixBlend2")
  474. .set(&MixNode::type, NODE_MIX_BLEND)
  475. .set(&MixNode::use_clamp, false)
  476. .set("Fac", 1.0f))
  477. .add_connection("Attribute1::Color", "MixBlend2::Color2")
  478. .add_connection("Attribute2::Color", "MixBlend2::Color1")
  479. /* both inputs folded to Attribute1 */
  480. .add_node(ShaderNodeBuilder<MixNode>("MixBlend3")
  481. .set(&MixNode::type, NODE_MIX_BLEND)
  482. .set(&MixNode::use_clamp, false))
  483. .add_connection("Attribute1::Fac", "MixBlend3::Fac")
  484. .add_connection("MixBlend1::Color", "MixBlend3::Color1")
  485. .add_connection("MixBlend2::Color", "MixBlend3::Color2")
  486. .output_color("MixBlend3::Color");
  487. graph.finalize(scene);
  488. }
  489. /*
  490. * Tests:
  491. * - NOT folding of MixRGB Sub with the same inputs and fac NOT 1.
  492. */
  493. TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad)
  494. {
  495. EXPECT_ANY_MESSAGE(log);
  496. INVALID_INFO_MESSAGE(log, "Folding Mix::");
  497. builder.add_attribute("Attribute")
  498. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  499. .set(&MixNode::type, NODE_MIX_SUB)
  500. .set(&MixNode::use_clamp, true)
  501. .set("Fac", 0.5f))
  502. .add_connection("Attribute::Color", "Mix::Color1")
  503. .add_connection("Attribute::Color", "Mix::Color2")
  504. .output_color("Mix::Color");
  505. graph.finalize(scene);
  506. }
  507. /*
  508. * Tests:
  509. * - Folding of MixRGB Sub with the same inputs and fac 1.
  510. */
  511. TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_1)
  512. {
  513. EXPECT_ANY_MESSAGE(log);
  514. CORRECT_INFO_MESSAGE(log, "Folding Mix::Color to constant (0, 0, 0).");
  515. builder.add_attribute("Attribute")
  516. .add_node(ShaderNodeBuilder<MixNode>("Mix")
  517. .set(&MixNode::type, NODE_MIX_SUB)
  518. .set(&MixNode::use_clamp, true)
  519. .set("Fac", 1.0f))
  520. .add_connection("Attribute::Color", "Mix::Color1")
  521. .add_connection("Attribute::Color", "Mix::Color2")
  522. .output_color("Mix::Color");
  523. graph.finalize(scene);
  524. }
  525. /*
  526. * Graph for testing partial folds of MixRGB with one constant argument.
  527. * Includes 4 tests: constant on each side with fac either unknown or 1.
  528. */
  529. static void build_mix_partial_test_graph(ShaderGraphBuilder &builder,
  530. NodeMix type,
  531. float3 constval)
  532. {
  533. builder
  534. .add_attribute("Attribute")
  535. /* constant on the left */
  536. .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_Fx")
  537. .set(&MixNode::type, type)
  538. .set(&MixNode::use_clamp, false)
  539. .set("Color1", constval))
  540. .add_node(ShaderNodeBuilder<MixNode>("Mix_Cx_F1")
  541. .set(&MixNode::type, type)
  542. .set(&MixNode::use_clamp, false)
  543. .set("Color1", constval)
  544. .set("Fac", 1.0f))
  545. .add_connection("Attribute::Fac", "Mix_Cx_Fx::Fac")
  546. .add_connection("Attribute::Color", "Mix_Cx_Fx::Color2")
  547. .add_connection("Attribute::Color", "Mix_Cx_F1::Color2")
  548. /* constant on the right */
  549. .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_Fx")
  550. .set(&MixNode::type, type)
  551. .set(&MixNode::use_clamp, false)
  552. .set("Color2", constval))
  553. .add_node(ShaderNodeBuilder<MixNode>("Mix_xC_F1")
  554. .set(&MixNode::type, type)
  555. .set(&MixNode::use_clamp, false)
  556. .set("Color2", constval)
  557. .set("Fac", 1.0f))
  558. .add_connection("Attribute::Fac", "Mix_xC_Fx::Fac")
  559. .add_connection("Attribute::Color", "Mix_xC_Fx::Color1")
  560. .add_connection("Attribute::Color", "Mix_xC_F1::Color1")
  561. /* results of actual tests simply added up to connect to output */
  562. .add_node(ShaderNodeBuilder<MixNode>("Out12")
  563. .set(&MixNode::type, NODE_MIX_ADD)
  564. .set(&MixNode::use_clamp, true)
  565. .set("Fac", 1.0f))
  566. .add_node(ShaderNodeBuilder<MixNode>("Out34")
  567. .set(&MixNode::type, NODE_MIX_ADD)
  568. .set(&MixNode::use_clamp, true)
  569. .set("Fac", 1.0f))
  570. .add_node(ShaderNodeBuilder<MixNode>("Out1234")
  571. .set(&MixNode::type, NODE_MIX_ADD)
  572. .set(&MixNode::use_clamp, true)
  573. .set("Fac", 1.0f))
  574. .add_connection("Mix_Cx_Fx::Color", "Out12::Color1")
  575. .add_connection("Mix_Cx_F1::Color", "Out12::Color2")
  576. .add_connection("Mix_xC_Fx::Color", "Out34::Color1")
  577. .add_connection("Mix_xC_F1::Color", "Out34::Color2")
  578. .add_connection("Out12::Color", "Out1234::Color1")
  579. .add_connection("Out34::Color", "Out1234::Color2")
  580. .output_color("Out1234::Color");
  581. }
  582. /*
  583. * Tests: partial folding for RGB Add with known 0.
  584. */
  585. TEST_F(RenderGraph, constant_fold_part_mix_add_0)
  586. {
  587. EXPECT_ANY_MESSAGE(log);
  588. /* 0 + X (fac 1) == X */
  589. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
  590. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
  591. /* X + 0 (fac ?) == X */
  592. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
  593. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
  594. INVALID_INFO_MESSAGE(log, "Folding Out");
  595. build_mix_partial_test_graph(builder, NODE_MIX_ADD, make_float3(0, 0, 0));
  596. graph.finalize(scene);
  597. }
  598. /*
  599. * Tests: partial folding for RGB Sub with known 0.
  600. */
  601. TEST_F(RenderGraph, constant_fold_part_mix_sub_0)
  602. {
  603. EXPECT_ANY_MESSAGE(log);
  604. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
  605. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
  606. /* X - 0 (fac ?) == X */
  607. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
  608. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
  609. INVALID_INFO_MESSAGE(log, "Folding Out");
  610. build_mix_partial_test_graph(builder, NODE_MIX_SUB, make_float3(0, 0, 0));
  611. graph.finalize(scene);
  612. }
  613. /*
  614. * Tests: partial folding for RGB Mul with known 1.
  615. */
  616. TEST_F(RenderGraph, constant_fold_part_mix_mul_1)
  617. {
  618. EXPECT_ANY_MESSAGE(log);
  619. /* 1 * X (fac 1) == X */
  620. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
  621. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to socket Attribute::Color.");
  622. /* X * 1 (fac ?) == X */
  623. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
  624. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
  625. INVALID_INFO_MESSAGE(log, "Folding Out");
  626. build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(1, 1, 1));
  627. graph.finalize(scene);
  628. }
  629. /*
  630. * Tests: partial folding for RGB Div with known 1.
  631. */
  632. TEST_F(RenderGraph, constant_fold_part_mix_div_1)
  633. {
  634. EXPECT_ANY_MESSAGE(log);
  635. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color");
  636. INVALID_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color");
  637. /* X / 1 (fac ?) == X */
  638. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color to socket Attribute::Color.");
  639. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to socket Attribute::Color.");
  640. INVALID_INFO_MESSAGE(log, "Folding Out");
  641. build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(1, 1, 1));
  642. graph.finalize(scene);
  643. }
  644. /*
  645. * Tests: partial folding for RGB Mul with known 0.
  646. */
  647. TEST_F(RenderGraph, constant_fold_part_mix_mul_0)
  648. {
  649. EXPECT_ANY_MESSAGE(log);
  650. /* 0 * ? (fac ?) == 0 */
  651. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
  652. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
  653. /* ? * 0 (fac 1) == 0 */
  654. INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
  655. CORRECT_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color to constant (0, 0, 0).");
  656. CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
  657. INVALID_INFO_MESSAGE(log, "Folding Out1234");
  658. build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(0, 0, 0));
  659. graph.finalize(scene);
  660. }
  661. /*
  662. * Tests: partial folding for RGB Div with known 0.
  663. */
  664. TEST_F(RenderGraph, constant_fold_part_mix_div_0)
  665. {
  666. EXPECT_ANY_MESSAGE(log);
  667. /* 0 / ? (fac ?) == 0 */
  668. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_Fx::Color to constant (0, 0, 0).");
  669. CORRECT_INFO_MESSAGE(log, "Folding Mix_Cx_F1::Color to constant (0, 0, 0).");
  670. INVALID_INFO_MESSAGE(log, "Folding Mix_xC_Fx::Color");
  671. INVALID_INFO_MESSAGE(log, "Folding Mix_xC_F1::Color");
  672. CORRECT_INFO_MESSAGE(log, "Folding Out12::Color to constant (0, 0, 0).");
  673. INVALID_INFO_MESSAGE(log, "Folding Out1234");
  674. build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(0, 0, 0));
  675. graph.finalize(scene);
  676. }
  677. /*
  678. * Tests: Separate/Combine RGB with all constant inputs.
  679. */
  680. TEST_F(RenderGraph, constant_fold_separate_combine_rgb)
  681. {
  682. EXPECT_ANY_MESSAGE(log);
  683. CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::R to constant (0.3).");
  684. CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::G to constant (0.5).");
  685. CORRECT_INFO_MESSAGE(log, "Folding SeparateRGB::B to constant (0.7).");
  686. CORRECT_INFO_MESSAGE(log, "Folding CombineRGB::Image to constant (0.3, 0.5, 0.7).");
  687. builder
  688. .add_node(ShaderNodeBuilder<SeparateRGBNode>("SeparateRGB")
  689. .set("Image", make_float3(0.3f, 0.5f, 0.7f)))
  690. .add_node(ShaderNodeBuilder<CombineRGBNode>("CombineRGB"))
  691. .add_connection("SeparateRGB::R", "CombineRGB::R")
  692. .add_connection("SeparateRGB::G", "CombineRGB::G")
  693. .add_connection("SeparateRGB::B", "CombineRGB::B")
  694. .output_color("CombineRGB::Image");
  695. graph.finalize(scene);
  696. }
  697. /*
  698. * Tests: Separate/Combine XYZ with all constant inputs.
  699. */
  700. TEST_F(RenderGraph, constant_fold_separate_combine_xyz)
  701. {
  702. EXPECT_ANY_MESSAGE(log);
  703. CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::X to constant (0.3).");
  704. CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Y to constant (0.5).");
  705. CORRECT_INFO_MESSAGE(log, "Folding SeparateXYZ::Z to constant (0.7).");
  706. CORRECT_INFO_MESSAGE(log, "Folding CombineXYZ::Vector to constant (0.3, 0.5, 0.7).");
  707. CORRECT_INFO_MESSAGE(
  708. log, "Folding convert_vector_to_color::value_color to constant (0.3, 0.5, 0.7).");
  709. builder
  710. .add_node(ShaderNodeBuilder<SeparateXYZNode>("SeparateXYZ")
  711. .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
  712. .add_node(ShaderNodeBuilder<CombineXYZNode>("CombineXYZ"))
  713. .add_connection("SeparateXYZ::X", "CombineXYZ::X")
  714. .add_connection("SeparateXYZ::Y", "CombineXYZ::Y")
  715. .add_connection("SeparateXYZ::Z", "CombineXYZ::Z")
  716. .output_color("CombineXYZ::Vector");
  717. graph.finalize(scene);
  718. }
  719. /*
  720. * Tests: Separate/Combine HSV with all constant inputs.
  721. */
  722. TEST_F(RenderGraph, constant_fold_separate_combine_hsv)
  723. {
  724. EXPECT_ANY_MESSAGE(log);
  725. CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::H to constant (0.583333).");
  726. CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::S to constant (0.571429).");
  727. CORRECT_INFO_MESSAGE(log, "Folding SeparateHSV::V to constant (0.7).");
  728. CORRECT_INFO_MESSAGE(log, "Folding CombineHSV::Color to constant (0.3, 0.5, 0.7).");
  729. builder
  730. .add_node(ShaderNodeBuilder<SeparateHSVNode>("SeparateHSV")
  731. .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
  732. .add_node(ShaderNodeBuilder<CombineHSVNode>("CombineHSV"))
  733. .add_connection("SeparateHSV::H", "CombineHSV::H")
  734. .add_connection("SeparateHSV::S", "CombineHSV::S")
  735. .add_connection("SeparateHSV::V", "CombineHSV::V")
  736. .output_color("CombineHSV::Color");
  737. graph.finalize(scene);
  738. }
  739. /*
  740. * Tests: Gamma with all constant inputs.
  741. */
  742. TEST_F(RenderGraph, constant_fold_gamma)
  743. {
  744. EXPECT_ANY_MESSAGE(log);
  745. CORRECT_INFO_MESSAGE(log, "Folding Gamma::Color to constant (0.164317, 0.353553, 0.585662).");
  746. builder
  747. .add_node(ShaderNodeBuilder<GammaNode>("Gamma")
  748. .set("Color", make_float3(0.3f, 0.5f, 0.7f))
  749. .set("Gamma", 1.5f))
  750. .output_color("Gamma::Color");
  751. graph.finalize(scene);
  752. }
  753. /*
  754. * Tests: Gamma with one constant 0 input.
  755. */
  756. TEST_F(RenderGraph, constant_fold_gamma_part_0)
  757. {
  758. EXPECT_ANY_MESSAGE(log);
  759. INVALID_INFO_MESSAGE(log, "Folding Gamma_Cx::");
  760. CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to constant (1, 1, 1).");
  761. builder
  762. .add_attribute("Attribute")
  763. /* constant on the left */
  764. .add_node(
  765. ShaderNodeBuilder<GammaNode>("Gamma_Cx").set("Color", make_float3(0.0f, 0.0f, 0.0f)))
  766. .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
  767. /* constant on the right */
  768. .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC").set("Gamma", 0.0f))
  769. .add_connection("Attribute::Color", "Gamma_xC::Color")
  770. /* output sum */
  771. .add_node(ShaderNodeBuilder<MixNode>("Out")
  772. .set(&MixNode::type, NODE_MIX_ADD)
  773. .set(&MixNode::use_clamp, true)
  774. .set("Fac", 1.0f))
  775. .add_connection("Gamma_Cx::Color", "Out::Color1")
  776. .add_connection("Gamma_xC::Color", "Out::Color2")
  777. .output_color("Out::Color");
  778. graph.finalize(scene);
  779. }
  780. /*
  781. * Tests: Gamma with one constant 1 input.
  782. */
  783. TEST_F(RenderGraph, constant_fold_gamma_part_1)
  784. {
  785. EXPECT_ANY_MESSAGE(log);
  786. CORRECT_INFO_MESSAGE(log, "Folding Gamma_Cx::Color to constant (1, 1, 1).");
  787. CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to socket Attribute::Color.");
  788. builder
  789. .add_attribute("Attribute")
  790. /* constant on the left */
  791. .add_node(
  792. ShaderNodeBuilder<GammaNode>("Gamma_Cx").set("Color", make_float3(1.0f, 1.0f, 1.0f)))
  793. .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
  794. /* constant on the right */
  795. .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC").set("Gamma", 1.0f))
  796. .add_connection("Attribute::Color", "Gamma_xC::Color")
  797. /* output sum */
  798. .add_node(ShaderNodeBuilder<MixNode>("Out")
  799. .set(&MixNode::type, NODE_MIX_ADD)
  800. .set(&MixNode::use_clamp, true)
  801. .set("Fac", 1.0f))
  802. .add_connection("Gamma_Cx::Color", "Out::Color1")
  803. .add_connection("Gamma_xC::Color", "Out::Color2")
  804. .output_color("Out::Color");
  805. graph.finalize(scene);
  806. }
  807. /*
  808. * Tests: BrightnessContrast with all constant inputs.
  809. */
  810. TEST_F(RenderGraph, constant_fold_bright_contrast)
  811. {
  812. EXPECT_ANY_MESSAGE(log);
  813. CORRECT_INFO_MESSAGE(log, "Folding BrightContrast::Color to constant (0.16, 0.6, 1.04).");
  814. builder
  815. .add_node(ShaderNodeBuilder<BrightContrastNode>("BrightContrast")
  816. .set("Color", make_float3(0.3f, 0.5f, 0.7f))
  817. .set("Bright", 0.1f)
  818. .set("Contrast", 1.2f))
  819. .output_color("BrightContrast::Color");
  820. graph.finalize(scene);
  821. }
  822. /*
  823. * Tests: blackbody with all constant inputs.
  824. */
  825. TEST_F(RenderGraph, constant_fold_blackbody)
  826. {
  827. EXPECT_ANY_MESSAGE(log);
  828. CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.94163, 0.226523, 0).");
  829. builder.add_node(ShaderNodeBuilder<BlackbodyNode>("Blackbody").set("Temperature", 1200.0f))
  830. .output_color("Blackbody::Color");
  831. graph.finalize(scene);
  832. }
  833. /*
  834. * Tests: Math with all constant inputs (clamp false).
  835. */
  836. TEST_F(RenderGraph, constant_fold_math)
  837. {
  838. EXPECT_ANY_MESSAGE(log);
  839. CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1.6).");
  840. builder
  841. .add_node(ShaderNodeBuilder<MathNode>("Math")
  842. .set(&MathNode::type, NODE_MATH_ADD)
  843. .set(&MathNode::use_clamp, false)
  844. .set("Value1", 0.7f)
  845. .set("Value2", 0.9f))
  846. .output_value("Math::Value");
  847. graph.finalize(scene);
  848. }
  849. /*
  850. * Tests: Math with all constant inputs (clamp true).
  851. */
  852. TEST_F(RenderGraph, constant_fold_math_clamp)
  853. {
  854. EXPECT_ANY_MESSAGE(log);
  855. CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (1).");
  856. builder
  857. .add_node(ShaderNodeBuilder<MathNode>("Math")
  858. .set(&MathNode::type, NODE_MATH_ADD)
  859. .set(&MathNode::use_clamp, true)
  860. .set("Value1", 0.7f)
  861. .set("Value2", 0.9f))
  862. .output_value("Math::Value");
  863. graph.finalize(scene);
  864. }
  865. /*
  866. * Graph for testing partial folds of Math with one constant argument.
  867. * Includes 2 tests: constant on each side.
  868. */
  869. static void build_math_partial_test_graph(ShaderGraphBuilder &builder,
  870. NodeMath type,
  871. float constval)
  872. {
  873. builder
  874. .add_attribute("Attribute")
  875. /* constant on the left */
  876. .add_node(ShaderNodeBuilder<MathNode>("Math_Cx")
  877. .set(&MathNode::type, type)
  878. .set(&MathNode::use_clamp, false)
  879. .set("Value1", constval))
  880. .add_connection("Attribute::Fac", "Math_Cx::Value2")
  881. /* constant on the right */
  882. .add_node(ShaderNodeBuilder<MathNode>("Math_xC")
  883. .set(&MathNode::type, type)
  884. .set(&MathNode::use_clamp, false)
  885. .set("Value2", constval))
  886. .add_connection("Attribute::Fac", "Math_xC::Value1")
  887. /* output sum */
  888. .add_node(ShaderNodeBuilder<MathNode>("Out")
  889. .set(&MathNode::type, NODE_MATH_ADD)
  890. .set(&MathNode::use_clamp, true))
  891. .add_connection("Math_Cx::Value", "Out::Value1")
  892. .add_connection("Math_xC::Value", "Out::Value2")
  893. .output_value("Out::Value");
  894. }
  895. /*
  896. * Tests: partial folding for Math Add with known 0.
  897. */
  898. TEST_F(RenderGraph, constant_fold_part_math_add_0)
  899. {
  900. EXPECT_ANY_MESSAGE(log);
  901. /* X + 0 == 0 + X == X */
  902. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
  903. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
  904. INVALID_INFO_MESSAGE(log, "Folding Out::");
  905. build_math_partial_test_graph(builder, NODE_MATH_ADD, 0.0f);
  906. graph.finalize(scene);
  907. }
  908. /*
  909. * Tests: partial folding for Math Sub with known 0.
  910. */
  911. TEST_F(RenderGraph, constant_fold_part_math_sub_0)
  912. {
  913. EXPECT_ANY_MESSAGE(log);
  914. /* X - 0 == X */
  915. INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
  916. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
  917. INVALID_INFO_MESSAGE(log, "Folding Out::");
  918. build_math_partial_test_graph(builder, NODE_MATH_SUBTRACT, 0.0f);
  919. graph.finalize(scene);
  920. }
  921. /*
  922. * Tests: partial folding for Math Mul with known 1.
  923. */
  924. TEST_F(RenderGraph, constant_fold_part_math_mul_1)
  925. {
  926. EXPECT_ANY_MESSAGE(log);
  927. /* X * 1 == 1 * X == X */
  928. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to socket Attribute::Fac.");
  929. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
  930. INVALID_INFO_MESSAGE(log, "Folding Out::");
  931. build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 1.0f);
  932. graph.finalize(scene);
  933. }
  934. /*
  935. * Tests: partial folding for Math Div with known 1.
  936. */
  937. TEST_F(RenderGraph, constant_fold_part_math_div_1)
  938. {
  939. EXPECT_ANY_MESSAGE(log);
  940. /* X / 1 == X */
  941. INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
  942. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
  943. INVALID_INFO_MESSAGE(log, "Folding Out::");
  944. build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 1.0f);
  945. graph.finalize(scene);
  946. }
  947. /*
  948. * Tests: partial folding for Math Mul with known 0.
  949. */
  950. TEST_F(RenderGraph, constant_fold_part_math_mul_0)
  951. {
  952. EXPECT_ANY_MESSAGE(log);
  953. /* X * 0 == 0 * X == 0 */
  954. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
  955. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (0).");
  956. CORRECT_INFO_MESSAGE(log, "Folding Out::Value to constant (0)");
  957. CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
  958. build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 0.0f);
  959. graph.finalize(scene);
  960. }
  961. /*
  962. * Tests: partial folding for Math Div with known 0.
  963. */
  964. TEST_F(RenderGraph, constant_fold_part_math_div_0)
  965. {
  966. EXPECT_ANY_MESSAGE(log);
  967. /* 0 / X == 0 */
  968. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (0).");
  969. INVALID_INFO_MESSAGE(log, "Folding Math_xC::");
  970. INVALID_INFO_MESSAGE(log, "Folding Out::");
  971. build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 0.0f);
  972. graph.finalize(scene);
  973. }
  974. /*
  975. * Tests: partial folding for Math Power with known 0.
  976. */
  977. TEST_F(RenderGraph, constant_fold_part_math_pow_0)
  978. {
  979. EXPECT_ANY_MESSAGE(log);
  980. /* X ^ 0 == 1 */
  981. INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
  982. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (1).");
  983. INVALID_INFO_MESSAGE(log, "Folding Out::");
  984. build_math_partial_test_graph(builder, NODE_MATH_POWER, 0.0f);
  985. graph.finalize(scene);
  986. }
  987. /*
  988. * Tests: partial folding for Math Power with known 1.
  989. */
  990. TEST_F(RenderGraph, constant_fold_part_math_pow_1)
  991. {
  992. EXPECT_ANY_MESSAGE(log);
  993. /* 1 ^ X == 1; X ^ 1 == X */
  994. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (1)");
  995. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
  996. INVALID_INFO_MESSAGE(log, "Folding Out::");
  997. build_math_partial_test_graph(builder, NODE_MATH_POWER, 1.0f);
  998. graph.finalize(scene);
  999. }
  1000. /*
  1001. * Tests: Vector Math with all constant inputs.
  1002. */
  1003. TEST_F(RenderGraph, constant_fold_vector_math)
  1004. {
  1005. EXPECT_ANY_MESSAGE(log);
  1006. CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Value to constant (1).");
  1007. CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Vector to constant (3, 0, 0).");
  1008. CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_float::value_float to constant (1).");
  1009. CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (2).");
  1010. CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (2, 2, 2).");
  1011. builder
  1012. .add_node(ShaderNodeBuilder<VectorMathNode>("VectorMath")
  1013. .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT)
  1014. .set("Vector1", make_float3(1.3f, 0.5f, 0.7f))
  1015. .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f)))
  1016. .add_node(ShaderNodeBuilder<MathNode>("Math").set(&MathNode::type, NODE_MATH_ADD))
  1017. .add_connection("VectorMath::Vector", "Math::Value1")
  1018. .add_connection("VectorMath::Value", "Math::Value2")
  1019. .output_color("Math::Value");
  1020. graph.finalize(scene);
  1021. }
  1022. /*
  1023. * Graph for testing partial folds of Vector Math with one constant argument.
  1024. * Includes 2 tests: constant on each side.
  1025. */
  1026. static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder,
  1027. NodeVectorMath type,
  1028. float3 constval)
  1029. {
  1030. builder
  1031. .add_attribute("Attribute")
  1032. /* constant on the left */
  1033. .add_node(ShaderNodeBuilder<VectorMathNode>("Math_Cx")
  1034. .set(&VectorMathNode::type, type)
  1035. .set("Vector1", constval))
  1036. .add_connection("Attribute::Vector", "Math_Cx::Vector2")
  1037. /* constant on the right */
  1038. .add_node(ShaderNodeBuilder<VectorMathNode>("Math_xC")
  1039. .set(&VectorMathNode::type, type)
  1040. .set("Vector2", constval))
  1041. .add_connection("Attribute::Vector", "Math_xC::Vector1")
  1042. /* output sum */
  1043. .add_node(ShaderNodeBuilder<VectorMathNode>("Out").set(&VectorMathNode::type,
  1044. NODE_VECTOR_MATH_ADD))
  1045. .add_connection("Math_Cx::Vector", "Out::Vector1")
  1046. .add_connection("Math_xC::Vector", "Out::Vector2")
  1047. .output_color("Out::Vector");
  1048. }
  1049. /*
  1050. * Tests: partial folding for Vector Math Add with known 0.
  1051. */
  1052. TEST_F(RenderGraph, constant_fold_part_vecmath_add_0)
  1053. {
  1054. EXPECT_ANY_MESSAGE(log);
  1055. /* X + 0 == 0 + X == X */
  1056. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to socket Attribute::Vector.");
  1057. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
  1058. INVALID_INFO_MESSAGE(log, "Folding Out::");
  1059. build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_ADD, make_float3(0, 0, 0));
  1060. graph.finalize(scene);
  1061. }
  1062. /*
  1063. * Tests: partial folding for Vector Math Sub with known 0.
  1064. */
  1065. TEST_F(RenderGraph, constant_fold_part_vecmath_sub_0)
  1066. {
  1067. EXPECT_ANY_MESSAGE(log);
  1068. /* X - 0 == X */
  1069. INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
  1070. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to socket Attribute::Vector.");
  1071. INVALID_INFO_MESSAGE(log, "Folding Out::");
  1072. build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_SUBTRACT, make_float3(0, 0, 0));
  1073. graph.finalize(scene);
  1074. }
  1075. /*
  1076. * Tests: partial folding for Vector Math Dot Product with known 0.
  1077. */
  1078. TEST_F(RenderGraph, constant_fold_part_vecmath_dot_0)
  1079. {
  1080. EXPECT_ANY_MESSAGE(log);
  1081. /* X * 0 == 0 * X == X */
  1082. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
  1083. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
  1084. CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
  1085. CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
  1086. build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_DOT_PRODUCT, make_float3(0, 0, 0));
  1087. graph.finalize(scene);
  1088. }
  1089. /*
  1090. * Tests: partial folding for Vector Math Cross Product with known 0.
  1091. */
  1092. TEST_F(RenderGraph, constant_fold_part_vecmath_cross_0)
  1093. {
  1094. EXPECT_ANY_MESSAGE(log);
  1095. /* X * 0 == 0 * X == X */
  1096. CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0).");
  1097. CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0).");
  1098. CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0).");
  1099. CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
  1100. build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_CROSS_PRODUCT, make_float3(0, 0, 0));
  1101. graph.finalize(scene);
  1102. }
  1103. /*
  1104. * Tests: Bump with no height input folded to Normal input.
  1105. */
  1106. TEST_F(RenderGraph, constant_fold_bump)
  1107. {
  1108. EXPECT_ANY_MESSAGE(log);
  1109. CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket Geometry1::Normal.");
  1110. builder.add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
  1111. .add_node(ShaderNodeBuilder<BumpNode>("Bump"))
  1112. .add_connection("Geometry1::Normal", "Bump::Normal")
  1113. .output_color("Bump::Normal");
  1114. graph.finalize(scene);
  1115. }
  1116. /*
  1117. * Tests: Bump with no inputs folded to Geometry::Normal.
  1118. */
  1119. TEST_F(RenderGraph, constant_fold_bump_no_input)
  1120. {
  1121. EXPECT_ANY_MESSAGE(log);
  1122. CORRECT_INFO_MESSAGE(log, "Folding Bump::Normal to socket geometry::Normal.");
  1123. builder.add_node(ShaderNodeBuilder<BumpNode>("Bump")).output_color("Bump::Normal");
  1124. graph.finalize(scene);
  1125. }
  1126. template<class T> void init_test_curve(array<T> &buffer, T start, T end, int steps)
  1127. {
  1128. buffer.resize(steps);
  1129. for (int i = 0; i < steps; i++) {
  1130. buffer[i] = lerp(start, end, float(i) / (steps - 1));
  1131. }
  1132. }
  1133. /*
  1134. * Tests:
  1135. * - Folding of RGB Curves with all constant inputs.
  1136. */
  1137. TEST_F(RenderGraph, constant_fold_rgb_curves)
  1138. {
  1139. EXPECT_ANY_MESSAGE(log);
  1140. CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.275, 0.5, 0.475).");
  1141. array<float3> curve;
  1142. init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
  1143. builder
  1144. .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
  1145. .set(&CurvesNode::curves, curve)
  1146. .set(&CurvesNode::min_x, 0.1f)
  1147. .set(&CurvesNode::max_x, 0.9f)
  1148. .set("Fac", 0.5f)
  1149. .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
  1150. .output_color("Curves::Color");
  1151. graph.finalize(scene);
  1152. }
  1153. /*
  1154. * Tests:
  1155. * - Folding of RGB Curves with zero Fac.
  1156. */
  1157. TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0)
  1158. {
  1159. EXPECT_ANY_MESSAGE(log);
  1160. CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to socket Attribute::Color.");
  1161. array<float3> curve;
  1162. init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
  1163. builder.add_attribute("Attribute")
  1164. .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
  1165. .set(&CurvesNode::curves, curve)
  1166. .set(&CurvesNode::min_x, 0.1f)
  1167. .set(&CurvesNode::max_x, 0.9f)
  1168. .set("Fac", 0.0f))
  1169. .add_connection("Attribute::Color", "Curves::Color")
  1170. .output_color("Curves::Color");
  1171. graph.finalize(scene);
  1172. }
  1173. /*
  1174. * Tests:
  1175. * - Folding of RGB Curves with zero Fac and all constant inputs.
  1176. */
  1177. TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const)
  1178. {
  1179. EXPECT_ANY_MESSAGE(log);
  1180. CORRECT_INFO_MESSAGE(log, "Folding Curves::Color to constant (0.3, 0.5, 0.7).");
  1181. array<float3> curve;
  1182. init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
  1183. builder
  1184. .add_node(ShaderNodeBuilder<RGBCurvesNode>("Curves")
  1185. .set(&CurvesNode::curves, curve)
  1186. .set(&CurvesNode::min_x, 0.1f)
  1187. .set(&CurvesNode::max_x, 0.9f)
  1188. .set("Fac", 0.0f)
  1189. .set("Color", make_float3(0.3f, 0.5f, 0.7f)))
  1190. .output_color("Curves::Color");
  1191. graph.finalize(scene);
  1192. }
  1193. /*
  1194. * Tests:
  1195. * - Folding of Vector Curves with all constant inputs.
  1196. */
  1197. TEST_F(RenderGraph, constant_fold_vector_curves)
  1198. {
  1199. EXPECT_ANY_MESSAGE(log);
  1200. CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to constant (0.275, 0.5, 0.475).");
  1201. array<float3> curve;
  1202. init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
  1203. builder
  1204. .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
  1205. .set(&CurvesNode::curves, curve)
  1206. .set(&CurvesNode::min_x, 0.1f)
  1207. .set(&CurvesNode::max_x, 0.9f)
  1208. .set("Fac", 0.5f)
  1209. .set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
  1210. .output_color("Curves::Vector");
  1211. graph.finalize(scene);
  1212. }
  1213. /*
  1214. * Tests:
  1215. * - Folding of Vector Curves with zero Fac.
  1216. */
  1217. TEST_F(RenderGraph, constant_fold_vector_curves_fac_0)
  1218. {
  1219. EXPECT_ANY_MESSAGE(log);
  1220. CORRECT_INFO_MESSAGE(log, "Folding Curves::Vector to socket Attribute::Vector.");
  1221. array<float3> curve;
  1222. init_test_curve(curve, make_float3(0.0f, 0.25f, 1.0f), make_float3(1.0f, 0.75f, 0.0f), 257);
  1223. builder.add_attribute("Attribute")
  1224. .add_node(ShaderNodeBuilder<VectorCurvesNode>("Curves")
  1225. .set(&CurvesNode::curves, curve)
  1226. .set(&CurvesNode::min_x, 0.1f)
  1227. .set(&CurvesNode::max_x, 0.9f)
  1228. .set("Fac", 0.0f))
  1229. .add_connection("Attribute::Vector", "Curves::Vector")
  1230. .output_color("Curves::Vector");
  1231. graph.finalize(scene);
  1232. }
  1233. /*
  1234. * Tests:
  1235. * - Folding of Color Ramp with all constant inputs.
  1236. */
  1237. TEST_F(RenderGraph, constant_fold_rgb_ramp)
  1238. {
  1239. EXPECT_ANY_MESSAGE(log);
  1240. CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.14, 0.39, 0.64).");
  1241. CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.89).");
  1242. array<float3> curve;
  1243. array<float> alpha;
  1244. init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
  1245. init_test_curve(alpha, 0.75f, 1.0f, 9);
  1246. builder
  1247. .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
  1248. .set(&RGBRampNode::ramp, curve)
  1249. .set(&RGBRampNode::ramp_alpha, alpha)
  1250. .set(&RGBRampNode::interpolate, true)
  1251. .set("Fac", 0.56f))
  1252. .add_node(ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_ADD))
  1253. .add_connection("Ramp::Color", "Mix::Color1")
  1254. .add_connection("Ramp::Alpha", "Mix::Color2")
  1255. .output_color("Mix::Color");
  1256. graph.finalize(scene);
  1257. }
  1258. /*
  1259. * Tests:
  1260. * - Folding of Color Ramp with all constant inputs (interpolate false).
  1261. */
  1262. TEST_F(RenderGraph, constant_fold_rgb_ramp_flat)
  1263. {
  1264. EXPECT_ANY_MESSAGE(log);
  1265. CORRECT_INFO_MESSAGE(log, "Folding Ramp::Color to constant (0.125, 0.375, 0.625).");
  1266. CORRECT_INFO_MESSAGE(log, "Folding Ramp::Alpha to constant (0.875).");
  1267. array<float3> curve;
  1268. array<float> alpha;
  1269. init_test_curve(curve, make_float3(0.0f, 0.25f, 0.5f), make_float3(0.25f, 0.5f, 0.75f), 9);
  1270. init_test_curve(alpha, 0.75f, 1.0f, 9);
  1271. builder
  1272. .add_node(ShaderNodeBuilder<RGBRampNode>("Ramp")
  1273. .set(&RGBRampNode::ramp, curve)
  1274. .set(&RGBRampNode::ramp_alpha, alpha)
  1275. .set(&RGBRampNode::interpolate, false)
  1276. .set("Fac", 0.56f))
  1277. .add_node(ShaderNodeBuilder<MixNode>("Mix").set(&MixNode::type, NODE_MIX_ADD))
  1278. .add_connection("Ramp::Color", "Mix::Color1")
  1279. .add_connection("Ramp::Alpha", "Mix::Color2")
  1280. .output_color("Mix::Color");
  1281. graph.finalize(scene);
  1282. }
  1283. /*
  1284. * Tests:
  1285. * - Folding of redundant conversion of float to color to float.
  1286. */
  1287. TEST_F(RenderGraph, constant_fold_convert_float_color_float)
  1288. {
  1289. EXPECT_ANY_MESSAGE(log);
  1290. CORRECT_INFO_MESSAGE(log,
  1291. "Folding Invert::Color to socket convert_float_to_color::value_color.");
  1292. CORRECT_INFO_MESSAGE(log,
  1293. "Folding convert_color_to_float::value_float to socket Attribute::Fac.");
  1294. builder.add_attribute("Attribute")
  1295. .add_node(ShaderNodeBuilder<InvertNode>("Invert").set("Fac", 0.0f))
  1296. .add_connection("Attribute::Fac", "Invert::Color")
  1297. .output_value("Invert::Color");
  1298. graph.finalize(scene);
  1299. }
  1300. /*
  1301. * Tests:
  1302. * - Folding of redundant conversion of color to vector to color.
  1303. */
  1304. TEST_F(RenderGraph, constant_fold_convert_color_vector_color)
  1305. {
  1306. EXPECT_ANY_MESSAGE(log);
  1307. CORRECT_INFO_MESSAGE(log,
  1308. "Folding VecAdd::Vector to socket convert_color_to_vector::value_vector.");
  1309. CORRECT_INFO_MESSAGE(log,
  1310. "Folding convert_vector_to_color::value_color to socket Attribute::Color.");
  1311. builder.add_attribute("Attribute")
  1312. .add_node(ShaderNodeBuilder<VectorMathNode>("VecAdd")
  1313. .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD)
  1314. .set("Vector2", make_float3(0, 0, 0)))
  1315. .add_connection("Attribute::Color", "VecAdd::Vector1")
  1316. .output_color("VecAdd::Vector");
  1317. graph.finalize(scene);
  1318. }
  1319. /*
  1320. * Tests:
  1321. * - NOT folding conversion of color to float to color.
  1322. */
  1323. TEST_F(RenderGraph, constant_fold_convert_color_float_color)
  1324. {
  1325. EXPECT_ANY_MESSAGE(log);
  1326. CORRECT_INFO_MESSAGE(log,
  1327. "Folding MathAdd::Value to socket convert_color_to_float::value_float.");
  1328. INVALID_INFO_MESSAGE(log, "Folding convert_float_to_color::");
  1329. builder.add_attribute("Attribute")
  1330. .add_node(ShaderNodeBuilder<MathNode>("MathAdd")
  1331. .set(&MathNode::type, NODE_MATH_ADD)
  1332. .set("Value2", 0.0f))
  1333. .add_connection("Attribute::Color", "MathAdd::Value1")
  1334. .output_color("MathAdd::Value");
  1335. graph.finalize(scene);
  1336. }
  1337. CCL_NAMESPACE_END