OLD | NEW |
1 /* | 1 /* |
2 Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. | 2 Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. |
3 All Rights Reserved. | 3 All Rights Reserved. |
4 | 4 |
5 Redistribution and use in source and binary forms, with or without | 5 Redistribution and use in source and binary forms, with or without |
6 modification, are permitted provided that the following conditions are | 6 modification, are permitted provided that the following conditions are |
7 met: | 7 met: |
8 * Redistributions of source code must retain the above copyright | 8 * Redistributions of source code must retain the above copyright |
9 notice, this list of conditions and the following disclaimer. | 9 notice, this list of conditions and the following disclaimer. |
10 * Redistributions in binary form must reproduce the above copyright | 10 * Redistributions in binary form must reproduce the above copyright |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 va_end (ap); | 109 va_end (ap); |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 | 113 |
114 void | 114 void |
115 ShadingExecution::error_arg_types () | 115 ShadingExecution::error_arg_types () |
116 { | 116 { |
117 std::stringstream out; | 117 std::stringstream out; |
118 const Opcode &op (this->op()); | 118 const Opcode &op (this->op()); |
119 const int *args = &m_master->m_args[0]; | 119 const int *args = &(instance()->args()[0]); |
120 out << "Don't know how to compute " | 120 out << "Don't know how to compute " |
121 << sym(args[op.firstarg()]).typespec().string() << " " << op.opname() <<
" ("; | 121 << sym(args[op.firstarg()]).typespec().string() << " " << op.opname() <<
" ("; |
122 for (int i = 1; i < op.nargs(); ++i) { | 122 for (int i = 1; i < op.nargs(); ++i) { |
123 if (i > 1) | 123 if (i > 1) |
124 out << ", "; | 124 out << ", "; |
125 out << sym(args[op.firstarg()+i]).typespec().string(); | 125 out << sym(args[op.firstarg()+i]).typespec().string(); |
126 } | 126 } |
127 out << ")"; | 127 out << ")"; |
128 error ("%s", out.str().c_str()); | 128 error ("%s", out.str().c_str()); |
129 } | 129 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 // FIXME -- if the number of points we need now is <= last time | 161 // FIXME -- if the number of points we need now is <= last time |
162 // we bound to this context, we can even skip much of the work | 162 // we bound to this context, we can even skip much of the work |
163 // below, and reuse all the heap offsets and pointers. We can | 163 // below, and reuse all the heap offsets and pointers. We can |
164 // do that optimization later. | 164 // do that optimization later. |
165 | 165 |
166 // Make a fresh copy of symbols from the instance. Don't copy the | 166 // Make a fresh copy of symbols from the instance. Don't copy the |
167 // whole vector, which may do an element-by-element copy of each | 167 // whole vector, which may do an element-by-element copy of each |
168 // Symbol. We humans know that the definition of Symbol has no | 168 // Symbol. We humans know that the definition of Symbol has no |
169 // elements that can't be memcpy'd, there is no allocated memory | 169 // elements that can't be memcpy'd, there is no allocated memory |
170 // that can leak, so we go the fast route and memcpy. | 170 // that can leak, so we go the fast route and memcpy. |
171 m_symbols.resize (m_instance->m_symbols.size()); | 171 m_symbols.resize (m_instance->m_instsymbols.size()); |
172 if (m_symbols.size() /* && !rebind */) | 172 if (m_symbols.size() /* && !rebind */) |
173 memcpy (&m_symbols[0], &m_instance->m_symbols[0],· | 173 memcpy (&m_symbols[0], &m_instance->m_instsymbols[0],· |
174 m_instance->m_symbols.size() * sizeof(Symbol)); | 174 m_instance->m_instsymbols.size() * sizeof(Symbol)); |
175 } | 175 } |
176 | 176 |
177 m_npoints = m_context->npoints (); | 177 m_npoints = m_context->npoints (); |
178 | 178 |
179 ShaderGlobals *globals (m_context->m_globals); | 179 ShaderGlobals *globals (m_context->m_globals); |
180 | 180 |
181 // FIXME: bind the symbols -- get the syms ready and pointing to the | 181 // FIXME: bind the symbols -- get the syms ready and pointing to the |
182 // right place in the heap,, interpolate primitive variables, handle | 182 // right place in the heap,, interpolate primitive variables, handle |
183 // connections, initialize all parameters | 183 // connections, initialize all parameters |
184 BOOST_FOREACH (Symbol &sym, m_symbols) { | 184 BOOST_FOREACH (Symbol &sym, m_symbols) { |
| 185 #if 0 |
185 if (m_debug) | 186 if (m_debug) |
186 m_shadingsys->info (" bind %s, offset %d", | 187 m_shadingsys->info (" bind %s, offset %d", |
187 sym.mangled().c_str(), sym.dataoffset()); | 188 sym.mangled().c_str(), sym.dataoffset()); |
| 189 #endif |
188 if (sym.symtype() == SymTypeGlobal) { | 190 if (sym.symtype() == SymTypeGlobal) { |
189 // FIXME -- reset sym's data pointer? | 191 // FIXME -- reset sym's data pointer? |
190 | 192 |
191 // Instead of duplicating the logic for each possible global | 193 // Instead of duplicating the logic for each possible global |
192 // variable, we just decode the name and store pointers to | 194 // variable, we just decode the name and store pointers to |
193 // the VaringRef's (for value, and for some cases, | 195 // the VaringRef's (for value, and for some cases, |
194 // derivatives) into valref, dxref, and dyref, then handle | 196 // derivatives) into valref, dxref, and dyref, then handle |
195 // them with a single logic block below. Note that rather | 197 // them with a single logic block below. Note that rather |
196 // than worry about the float and triple cases separately, | 198 // than worry about the float and triple cases separately, |
197 // we just cast them all to VR<float> for now, since it's | 199 // we just cast them all to VR<float> for now, since it's |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 // and in cache? Experiment at some point. | 277 // and in cache? Experiment at some point. |
276 } | 278 } |
277 ASSERT (sym.data() != NULL); | 279 ASSERT (sym.data() != NULL); |
278 } | 280 } |
279 float badval; | 281 float badval; |
280 bool badderiv; | 282 bool badderiv; |
281 int point; | 283 int point; |
282 if (debugnan && check_nan (sym, badval, badderiv, point)) | 284 if (debugnan && check_nan (sym, badval, badderiv, point)) |
283 m_shadingsys->warning ("Found %s%g in shader \"%s\" when binding
%s", | 285 m_shadingsys->warning ("Found %s%g in shader \"%s\" when binding
%s", |
284 badderiv ? "bad derivative " : "", | 286 badderiv ? "bad derivative " : "", |
285 badval, m_master->shadername().c_str(), | 287 badval, shadername().c_str(), |
286 sym.name().c_str());···················· | 288 sym.name().c_str());···················· |
287 | 289 |
288 } else if (sym.symtype() == SymTypeParam || | 290 } else if (sym.symtype() == SymTypeParam || |
289 sym.symtype() == SymTypeOutputParam) { | 291 sym.symtype() == SymTypeOutputParam) { |
290 m_context->m_paramstobind++; | 292 m_context->m_paramstobind++; |
291 if (sym.typespec().is_closure()) { | 293 if (sym.typespec().is_closure()) { |
292 // Special case -- closures store pointers in the heap | 294 // Special case -- closures store pointers in the heap |
293 sym.dataoffset (m_context->closure_allot (m_npoints)); | 295 sym.dataoffset (m_context->closure_allot (m_npoints)); |
294 sym.data (m_context->heapaddr (sym.dataoffset())); | 296 sym.data (m_context->heapaddr (sym.dataoffset())); |
295 sym.step (sizeof (ClosureColor *)); | 297 sym.step (sizeof (ClosureColor *)); |
(...skipping 27 matching lines...) Expand all Loading... |
323 // for now we're just taking care of it here. | 325 // for now we're just taking care of it here. |
324 sym.step (0); | 326 sym.step (0); |
325 ((ustring *)sym.data())->clear (); | 327 ((ustring *)sym.data())->clear (); |
326 } | 328 } |
327 } else if (sym.symtype() == SymTypeConst) { | 329 } else if (sym.symtype() == SymTypeConst) { |
328 ASSERT (sym.data() != NULL && | 330 ASSERT (sym.data() != NULL && |
329 "Const symbol should already have valid data address"); | 331 "Const symbol should already have valid data address"); |
330 } else { | 332 } else { |
331 ASSERT (0 && "Should never get here"); | 333 ASSERT (0 && "Should never get here"); |
332 } | 334 } |
| 335 #if 0 |
333 if (m_debug) | 336 if (m_debug) |
334 m_shadingsys->info (" bound %s to address %p, step %d, size %d %s", | 337 m_shadingsys->info (" bound %s to address %p, step %d, size %d %s", |
335 sym.mangled().c_str(), sym.data(), | 338 sym.mangled().c_str(), sym.data(), |
336 sym.step(), sym.size(), | 339 sym.step(), sym.size(), |
337 sym.has_derivs() ? "(derivs)" : "(no derivs)"); | 340 sym.has_derivs() ? "(derivs)" : "(no derivs)"); |
| 341 #endif |
338 } | 342 } |
339 | 343 |
340 // Mark the parameters that are driven by connections | 344 // Mark the parameters that are driven by connections |
341 for (int i = 0; i < m_instance->nconnections(); ++i) { | 345 for (int i = 0; i < m_instance->nconnections(); ++i) { |
342 const Connection &con = m_instance->connection (i); | 346 const Connection &con = m_instance->connection (i); |
343 sym (con.dst.param).valuesource (Symbol::ConnectedVal); | 347 sym (con.dst.param).valuesource (Symbol::ConnectedVal); |
344 } | 348 } |
345 // FIXME -- you know, the connectivity is fixed for the whole group | 349 // FIXME -- you know, the connectivity is fixed for the whole group |
346 // and its instances. We *could* mark them as connected and possibly | 350 // and its instances. We *could* mark them as connected and possibly |
347 // do some of the other connection work once per instance rather than | 351 // do some of the other connection work once per instance rather than |
(...skipping 12 matching lines...) Expand all Loading... |
360 } | 364 } |
361 | 365 |
362 | 366 |
363 | 367 |
364 void | 368 void |
365 ShadingExecution::bind_initialize_param (Symbol &sym, int symindex) | 369 ShadingExecution::bind_initialize_param (Symbol &sym, int symindex) |
366 { | 370 { |
367 ASSERT (! sym.initialized ()); | 371 ASSERT (! sym.initialized ()); |
368 ASSERT (m_runstate_stack.size() > 0); | 372 ASSERT (m_runstate_stack.size() > 0); |
369 m_context->m_paramsbound++; | 373 m_context->m_paramsbound++; |
| 374 sym.initialized (true); //FIXME -- shouldn't be necessary utl_spi_float_v1 |
370 | 375 |
371 // Lazy parameter binding: we figure out the value for this parameter based | 376 // Lazy parameter binding: we figure out the value for this parameter based |
372 // on the following priority: | 377 // on the following priority: |
373 // 1) connection(s) from an earlier layer | 378 // 1) connection(s) from an earlier layer |
374 // 2) geometry attribute on the surface of the same name | 379 // 2) geometry attribute on the surface of the same name |
375 // 3) instance values | 380 // 3) instance values |
376 // 4) default values (may include "init-ops") | 381 // 4) default values (may include "init-ops") |
377 | 382 |
378 if (sym.valuesource() == Symbol::ConnectedVal) { | 383 if (sym.valuesource() == Symbol::ConnectedVal) { |
379 // Run through all connections for this layer | 384 // Run through all connections for this layer |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 456 } |
452 float badval; | 457 float badval; |
453 bool badderiv; | 458 bool badderiv; |
454 int point; | 459 int point; |
455 // FIXME: uses wrong runstate (only the currently active points will be | 460 // FIXME: uses wrong runstate (only the currently active points will be |
456 // checked for nan, even though we evaluated all of them) | 461 // checked for nan, even though we evaluated all of them) |
457 if (m_shadingsys->debug_nan() && | 462 if (m_shadingsys->debug_nan() && |
458 check_nan (sym, badval, badderiv, point)) | 463 check_nan (sym, badval, badderiv, point)) |
459 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpolating %
s", | 464 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpolating %
s", |
460 badderiv ? "bad derivative " : "", | 465 badderiv ? "bad derivative " : "", |
461 badval, m_master->shadername().c_str(), | 466 badval, shadername().c_str(), |
462 sym.name().c_str()); | 467 sym.name().c_str()); |
463 | 468 |
464 sym.initialized (true); | 469 sym.initialized (true); |
465 } | 470 } |
466 | 471 |
467 | 472 |
468 | 473 |
469 void | 474 void |
470 ShadingExecution::bind_connection (const Connection &con) | 475 ShadingExecution::bind_connection (const Connection &con) |
471 { | 476 { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 dstsym.connected (true); | 529 dstsym.connected (true); |
525 } | 530 } |
526 | 531 |
527 | 532 |
528 | 533 |
529 void | 534 void |
530 ShadingExecution::run (Runflag *runflags, int *indices, int nindices, int begino
p, int endop) | 535 ShadingExecution::run (Runflag *runflags, int *indices, int nindices, int begino
p, int endop) |
531 { | 536 { |
532 if (m_debug) | 537 if (m_debug) |
533 m_shadingsys->info ("Running ShadeExec %p, shader %s", | 538 m_shadingsys->info ("Running ShadeExec %p, shader %s", |
534 this, m_master->shadername().c_str()); | 539 this, shadername().c_str()); |
535 | 540 |
536 push_runstate (runflags, 0, m_context->npoints(), indices, nindices); | 541 push_runstate (runflags, 0, m_context->npoints(), indices, nindices); |
537 | 542 |
538 if (beginop >= 0) { | 543 if (beginop >= 0) { |
539 ASSERT (m_bound); | 544 ASSERT (m_bound); |
540 ASSERT (m_npoints == m_context->npoints()); | 545 ASSERT (m_npoints == m_context->npoints()); |
541 /* | 546 /* |
542 * Run just the op range supplied (this is used for on-demand init ops) | 547 * Run just the op range supplied (this is used for on-demand init ops) |
543 * We might be running the init ops from inside a conditional, but the | 548 * We might be running the init ops from inside a conditional, but the |
544 * init ops themselves should act as if they were run from outside. | 549 * init ops themselves should act as if they were run from outside. |
(...skipping 11 matching lines...) Expand all Loading... |
556 ASSERT (!m_executed); | 561 ASSERT (!m_executed); |
557 /* | 562 /* |
558 * Default (<0) means run main code block. This should happen only once | 563 * Default (<0) means run main code block. This should happen only once |
559 * per shader. | 564 * per shader. |
560 */ | 565 */ |
561 // Bind symbols before running the shader | 566 // Bind symbols before running the shader |
562 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); | 567 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); |
563 bind (sgroup[layer()]); | 568 bind (sgroup[layer()]); |
564 | 569 |
565 m_conditional_level = 0; | 570 m_conditional_level = 0; |
566 run (m_master->m_maincodebegin, m_master->m_maincodeend); | 571 run (m_instance->maincodebegin(), m_instance->maincodeend()); |
567 m_executed = true; | 572 m_executed = true; |
568 ASSERT(m_conditional_level == 0); // make sure we nested our loops and i
fs correctly | 573 ASSERT(m_conditional_level == 0); // make sure we nested our loops and i
fs correctly |
569 } | 574 } |
570 pop_runstate (); | 575 pop_runstate (); |
571 } | 576 } |
572 | 577 |
573 | 578 |
574 | 579 |
575 void | 580 void |
576 ShadingExecution::run (int beginop, int endop) | 581 ShadingExecution::run (int beginop, int endop) |
577 { | 582 { |
578 if (m_debug) | 583 if (m_debug) |
579 m_shadingsys->info ("Running ShadeExec %p, shader %s ops [%d,%d)", | 584 m_shadingsys->info ("Running ShadeExec %p, shader %s ops [%d,%d)", |
580 this, m_master->shadername().c_str(), | 585 this, shadername().c_str(), |
581 beginop, endop); | 586 beginop, endop); |
582 const int *args = &m_master->m_args[0]; | 587 const int *args = &(instance()->args()[0]); |
583 bool debugnan = m_shadingsys->debug_nan (); | 588 bool debugnan = m_shadingsys->debug_nan (); |
| 589 OpcodeVec &code (m_instance->ops()); |
584 for (m_ip = beginop; m_ip < endop && m_runstate.beginpoint < m_runstate.endp
oint; ++m_ip) { | 590 for (m_ip = beginop; m_ip < endop && m_runstate.beginpoint < m_runstate.endp
oint; ++m_ip) { |
585 DASSERT (m_ip >= 0 && m_ip < (int)m_master->m_ops.size()); | 591 DASSERT (m_ip >= 0 && m_ip < (int)instance()->ops().size()); |
586 Opcode &op (this->op ()); | 592 Opcode &op (code[m_ip]); |
587 | 593 |
588 #if 0 | 594 #if 0 |
589 // Debugging tool -- sample the run flags | 595 // Debugging tool -- sample the run flags |
590 static atomic_ll count; | 596 static atomic_ll count; |
591 if (((++count) % 172933ul /*1142821ul*/) == 0) { // 12117689ul | 597 if (((++count) % 172933ul /*1142821ul*/) == 0) { // 12117689ul |
592 std::cerr << "rf "; | 598 std::cerr << "rf "; |
593 for (int i = 0; i < npoints(); ++i) | 599 for (int i = 0; i < npoints(); ++i) |
594 std::cerr << (int)(m_runstate.runflags[i] ? 1 : 0) << ' '; | 600 std::cerr << (int)(m_runstate.runflags[i] ? 1 : 0) << ' '; |
595 std::cerr << std::endl; | 601 std::cerr << std::endl; |
596 } | 602 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 636 |
631 void | 637 void |
632 ShadingExecution::check_nan (Opcode &op) | 638 ShadingExecution::check_nan (Opcode &op) |
633 { | 639 { |
634 // Check every writable argument of this op, at every shading point | 640 // Check every writable argument of this op, at every shading point |
635 // that's turned on, check for NaN and Inf values, and print a | 641 // that's turned on, check for NaN and Inf values, and print a |
636 // warning if found. | 642 // warning if found. |
637 for (int a = 0; a < op.nargs(); ++a) { | 643 for (int a = 0; a < op.nargs(); ++a) { |
638 if (! op.argwrite (a)) | 644 if (! op.argwrite (a)) |
639 continue; // Skip args that weren't written | 645 continue; // Skip args that weren't written |
640 Symbol &s (sym (m_master->m_args[op.firstarg()+a])); | 646 Symbol &s (sym (instance()->args()[op.firstarg()+a])); |
641 float badval; | 647 float badval; |
642 bool badderiv; | 648 bool badderiv; |
643 int point; | 649 int point; |
644 if (check_nan (s, badval, badderiv, point)) | 650 if (check_nan (s, badval, badderiv, point)) |
645 m_shadingsys->warning ("Generated %s%g in shader \"%s\",\n" | 651 m_shadingsys->warning ("Generated %s%g in shader \"%s\",\n" |
646 "\tsource \"%s\", line %d (instruction %s, ar
g %d)\n" | 652 "\tsource \"%s\", line %d (instruction %s, ar
g %d)\n" |
647 "\tsymbol \"%s\", %s (step %d), point %d of %
d", | 653 "\tsymbol \"%s\", %s (step %d), point %d of %
d", |
648 badderiv ? "bad derivative " : "", | 654 badderiv ? "bad derivative " : "", |
649 badval, m_master->shadername().c_str(), | 655 badval, shadername().c_str(), |
650 op.sourcefile().c_str(), | 656 op.sourcefile().c_str(), |
651 op.sourceline(), op.opname().c_str(), a, | 657 op.sourceline(), op.opname().c_str(), a, |
652 s.name().c_str(), s.is_uniform() ? "uniform"
: "varying", s.step(), point, npoints() ); | 658 s.name().c_str(), s.is_uniform() ? "uniform"
: "varying", s.step(), point, npoints() ); |
653 } | 659 } |
654 } | 660 } |
655 | 661 |
656 | 662 |
657 | 663 |
658 bool | 664 bool |
659 ShadingExecution::check_nan (Symbol &sym, float &badval, | 665 ShadingExecution::check_nan (Symbol &sym, float &badval, |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 get_matrix (Mfrom, from, whichpoint); | 1089 get_matrix (Mfrom, from, whichpoint); |
1084 get_inverse_matrix (Mto, to, whichpoint); | 1090 get_inverse_matrix (Mto, to, whichpoint); |
1085 result = Mfrom * Mto; | 1091 result = Mfrom * Mto; |
1086 } | 1092 } |
1087 | 1093 |
1088 | 1094 |
1089 | 1095 |
1090 | 1096 |
1091 }; // namespace pvt | 1097 }; // namespace pvt |
1092 }; // namespace OSL | 1098 }; // namespace OSL |
OLD | NEW |