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 22 matching lines...) Expand all Loading... |
33 | 33 |
34 #include "boost/foreach.hpp" | 34 #include "boost/foreach.hpp" |
35 | 35 |
36 #include "OpenImageIO/dassert.h" | 36 #include "OpenImageIO/dassert.h" |
37 #include "OpenImageIO/thread.h" | 37 #include "OpenImageIO/thread.h" |
38 #include "OpenImageIO/strutil.h" | 38 #include "OpenImageIO/strutil.h" |
39 #include "OpenImageIO/sysutil.h" | 39 #include "OpenImageIO/sysutil.h" |
40 | 40 |
41 #include "oslexec_pvt.h" | 41 #include "oslexec_pvt.h" |
42 #include "dual.h" | 42 #include "dual.h" |
| 43 #include "oslops.h" |
43 | 44 |
44 | 45 |
45 namespace OSL { | 46 namespace OSL { |
46 namespace pvt { // OSL::pvt | 47 namespace pvt { // OSL::pvt |
47 | 48 |
48 | 49 |
49 | 50 |
50 ShadingExecution::ShadingExecution () | 51 ShadingExecution::ShadingExecution () |
51 : m_context(NULL), m_instance(NULL), m_master(NULL), | 52 : m_context(NULL), m_instance(NULL), m_master(NULL), |
52 m_npoints_bound(0), | 53 m_npoints_bound(0), |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 // FIXME -- Hmmm... which is better, to avoid the copy | 274 // FIXME -- Hmmm... which is better, to avoid the copy |
274 // here but possibly have the data spread out strangely, | 275 // here but possibly have the data spread out strangely, |
275 // or to copy but then end up with the data contiguous | 276 // or to copy but then end up with the data contiguous |
276 // and in cache? Experiment at some point. | 277 // and in cache? Experiment at some point. |
277 } | 278 } |
278 ASSERT (sym.data() != NULL); | 279 ASSERT (sym.data() != NULL); |
279 } | 280 } |
280 float badval; | 281 float badval; |
281 bool badderiv; | 282 bool badderiv; |
282 int point; | 283 int point; |
283 if (debugnan && check_nan (sym, m_context->m_original_runflags, | 284 if (debugnan && check_nan (sym, badval, badderiv, point)) |
284 0, m_npoints, badval, badderiv, point)) | |
285 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", |
286 badderiv ? "bad derivative " : "", | 286 badderiv ? "bad derivative " : "", |
287 badval, m_master->shadername().c_str(), | 287 badval, m_master->shadername().c_str(), |
288 sym.name().c_str());···················· | 288 sym.name().c_str());···················· |
289 | 289 |
290 } else if (sym.symtype() == SymTypeParam || | 290 } else if (sym.symtype() == SymTypeParam || |
291 sym.symtype() == SymTypeOutputParam) { | 291 sym.symtype() == SymTypeOutputParam) { |
292 m_context->m_paramstobind++; | 292 m_context->m_paramstobind++; |
293 if (sym.typespec().is_closure()) { | 293 if (sym.typespec().is_closure()) { |
294 // Special case -- closures store pointers in the heap | 294 // Special case -- closures store pointers in the heap |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 369 |
370 if (sym->valuesource() == Symbol::DefaultVal || | 370 if (sym->valuesource() == Symbol::DefaultVal || |
371 sym->valuesource() == Symbol::InstanceVal) { | 371 sym->valuesource() == Symbol::InstanceVal) { |
372 | 372 |
373 if (sym->valuesource() == Symbol::DefaultVal && | 373 if (sym->valuesource() == Symbol::DefaultVal && |
374 sym->initbegin() != sym->initend()) { | 374 sym->initbegin() != sym->initend()) { |
375 // If it's still a default value and it's determined by init | 375 // If it's still a default value and it's determined by init |
376 // ops, run them now | 376 // ops, run them now |
377 int old_ip = m_ip; // Save the instruction pointer | 377 int old_ip = m_ip; // Save the instruction pointer |
378 run (context()->m_original_runflags, | 378 run (context()->m_original_runflags, |
| 379 context()->m_original_indices, context()->m_original_nindices, |
379 sym->initbegin(), sym->initend()); | 380 sym->initbegin(), sym->initend()); |
380 m_ip = old_ip; | 381 m_ip = old_ip; |
381 } | 382 } |
382 else if (!sym->typespec().is_closure() && !sym->typespec().is_structure(
)) { | 383 else if (!sym->typespec().is_closure() && !sym->typespec().is_structure(
)) { |
383 // Otherwise, if it's a normal data type (non-closure, | 384 // Otherwise, if it's a normal data type (non-closure, |
384 // non-struct) copy its instance and/or default value now. | 385 // non-struct) copy its instance and/or default value now. |
385 DASSERT (sym->step() == 0); | 386 DASSERT (sym->step() == 0); |
386 if (sym->typespec().simpletype().basetype == TypeDesc::FLOAT) | 387 if (sym->typespec().simpletype().basetype == TypeDesc::FLOAT) |
387 memcpy (sym->data(), &m_instance->m_fparams[sym->dataoffset()], | 388 memcpy (sym->data(), &m_instance->m_fparams[sym->dataoffset()], |
388 sym->typespec().simpletype().size()); | 389 sym->typespec().simpletype().size()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 ! execlayers[con.srclayer].executed()) { | 426 ! execlayers[con.srclayer].executed()) { |
426 run_connected_layer (con.srclayer); | 427 run_connected_layer (con.srclayer); |
427 } | 428 } |
428 } | 429 } |
429 } | 430 } |
430 | 431 |
431 float badval; | 432 float badval; |
432 bool badderiv; | 433 bool badderiv; |
433 int point; | 434 int point; |
434 if (m_shadingsys->debug_nan() && | 435 if (m_shadingsys->debug_nan() && |
435 check_nan (*sym, context()->m_original_runflags, | 436 check_nan (*sym, badval, badderiv, point)) |
436 m_beginpoint, m_endpoint, badval, badderiv, point)) | |
437 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpolating %
s", | 437 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpolating %
s", |
438 badderiv ? "bad derivative " : "", | 438 badderiv ? "bad derivative " : "", |
439 badval, m_master->shadername().c_str(), | 439 badval, m_master->shadername().c_str(), |
440 sym->name().c_str()); | 440 sym->name().c_str()); |
441 | 441 |
442 sym->initialized (true); | 442 sym->initialized (true); |
443 } | 443 } |
444 | 444 |
445 | 445 |
446 | 446 |
447 void | 447 void |
448 ShadingExecution::bind_connections () | 448 ShadingExecution::bind_connections () |
449 { | 449 { |
| 450 // std::cerr << " bind_connections " << m_instance->nconnections() << "\n"; |
450 for (int i = 0; i < m_instance->nconnections(); ++i) | 451 for (int i = 0; i < m_instance->nconnections(); ++i) |
451 bind_connection (m_instance->connection (i)); | 452 bind_connection (m_instance->connection (i)); |
452 // FIXME -- you know, the connectivity is fixed for the whole group | 453 // FIXME -- you know, the connectivity is fixed for the whole group |
453 // and its instances. We *could* mark them as connected and possibly | 454 // and its instances. We *could* mark them as connected and possibly |
454 // do some of the other connection work once per instance rather than | 455 // do some of the other connection work once per instance rather than |
455 // once per execution. Come back to this later and investigate. | 456 // once per execution. Come back to this later and investigate. |
456 } | 457 } |
457 | 458 |
458 | 459 |
459 | 460 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 srcsym.typespec().c_str(), srcsym.name().c_str(), | 508 srcsym.typespec().c_str(), srcsym.name().c_str(), |
508 dstsym.typespec().c_str(), dstsym.name().c_str()); | 509 dstsym.typespec().c_str(), dstsym.name().c_str()); |
509 return; | 510 return; |
510 } | 511 } |
511 dstsym.connected (true); | 512 dstsym.connected (true); |
512 } | 513 } |
513 | 514 |
514 | 515 |
515 | 516 |
516 void | 517 void |
517 ShadingExecution::run (Runflag *rf, int beginop, int endop) | 518 ShadingExecution::run (Runflag *rf, int *ind, int nind, int beginop, int endop) |
518 { | 519 { |
519 if (m_executed) | 520 if (m_executed) |
520 return; // Already executed | 521 return; // Already executed |
521 | 522 |
522 if (m_debug) | 523 if (m_debug) |
523 m_shadingsys->info ("Running ShadeExec %p, shader %s", | 524 m_shadingsys->info ("Running ShadeExec %p, shader %s", |
524 this, m_master->shadername().c_str()); | 525 this, m_master->shadername().c_str()); |
525 | 526 |
526 // Bind now if it is not already bound. | 527 // Bind now if it is not already bound. |
527 if (! m_bound) { | 528 if (! m_bound) { |
528 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); | 529 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); |
529 bind (sgroup[layer()]); | 530 bind (sgroup[layer()]); |
530 } | 531 } |
531 | 532 |
532 // Make space for new runflags | 533 // Make space for new runflags |
| 534 #if USE_RUNFLAGS |
533 Runflag *runflags = ALLOCA (Runflag, m_npoints); | 535 Runflag *runflags = ALLOCA (Runflag, m_npoints); |
| 536 int *indices = NULL; |
| 537 int nindices = 0; |
534 if (rf) { | 538 if (rf) { |
535 // Passed runflags -- copy those | 539 // Passed runflags -- copy those |
536 memcpy (runflags, rf, m_npoints*sizeof(Runflag)); | 540 memcpy (runflags, rf, m_npoints*sizeof(Runflag)); |
| 541 } else if (ind) { |
| 542 // Passed indices -- need to convert to runflags |
| 543 memset (runflags, RunflagOff, m_npoints*sizeof(Runflag)); |
| 544 for (int i = 0; i < nind; ++i) |
| 545 runflags[indices[i]] = RunflagOn; |
537 } else { | 546 } else { |
538 // If not passed runflags, make new ones | 547 // If not passed runflags, make new ones |
539 for (int i = 0; i < m_npoints; ++i) | 548 for (int i = 0; i < m_npoints; ++i) |
540 runflags[i] = RunflagOn; | 549 runflags[i] = RunflagOn; |
541 } | 550 } |
| 551 #elif USE_RUNINDICES |
| 552 Runflag *runflags = NULL; |
| 553 int *indices = ALLOCA (int, m_npoints); |
| 554 int nindices = nind; |
| 555 if (ind) { |
| 556 memcpy (indices, ind, nind*sizeof(indices[0])); |
| 557 } else if (rf) { |
| 558 // Passed runflags -- convert those to indices |
| 559 for (int i = 0; i < m_npoints; ++i) |
| 560 if (rf[i]) |
| 561 indices[nindices++] = i; |
| 562 } else { |
| 563 // If not passed either, make new ones |
| 564 nindices = m_npoints; |
| 565 for (int i = 0; i < nindices; ++i) |
| 566 indices[i] = i; |
| 567 } |
| 568 #elif USE_RUNSPANS |
| 569 Runflag *runflags = NULL; |
| 570 int *indices = NULL; |
| 571 int nindices = nind; |
| 572 if (ind) { |
| 573 indices = ALLOCA (int, nind); |
| 574 memcpy (indices, ind, nind*sizeof(indices[0])); |
| 575 } else if (rf) { |
| 576 // Passed runflags -- convert those to spans |
| 577 indices = ALLOCA (int, m_npoints*2); |
| 578 nindices = 0; |
| 579 runflags_to_spans (rf, 0, m_npoints, indices, nindices); |
| 580 } else { |
| 581 // If not passed either, make new ones |
| 582 indices = ALLOCA (int, 2); // max space we could need |
| 583 nindices = 2; |
| 584 indices[0] = 0; |
| 585 indices[1] = m_npoints; |
| 586 } |
| 587 #endif |
| 588 |
| 589 // Handle all of the symbols that are connected to earlier layers. |
| 590 // std::cerr << "About to bind connections\n"; |
| 591 bind_connections (); |
| 592 // std::cerr << "done bind connections\n"; |
542 | 593 |
543 m_conditional_level = 0; | 594 m_conditional_level = 0; |
544 push_runflags (runflags, 0, m_npoints); | 595 push_runflags (runflags, 0, m_npoints, indices, nindices); |
545 if (beginop >= 0) // Run just the op range supplied, and no init ops | 596 if (beginop >= 0) // Run just the op range supplied, and no init ops |
546 run (beginop, endop); | 597 run (beginop, endop); |
547 else { // Default (<0) means run param init ops + main code | 598 else { // Default (<0) means run param init ops + main code |
548 bind_connections (); // Handle syms connected to earlier layers | 599 bind_connections (); // Handle syms connected to earlier layers |
549 run (m_master->m_maincodebegin, m_master->m_maincodeend); | 600 run (m_master->m_maincodebegin, m_master->m_maincodeend); |
550 m_executed = true; | 601 m_executed = true; |
551 } | 602 } |
552 pop_runflags (); | 603 pop_runflags (); |
553 } | 604 } |
554 | 605 |
555 | 606 |
556 | 607 |
557 void | 608 void |
558 ShadingExecution::run (int beginop, int endop) | 609 ShadingExecution::run (int beginop, int endop) |
559 { | 610 { |
560 if (m_debug) | 611 if (m_debug) |
561 m_shadingsys->info ("Running ShadeExec %p, shader %s ops [%d,%d)", | 612 m_shadingsys->info ("Running ShadeExec %p, shader %s ops [%d,%d)", |
562 this, m_master->shadername().c_str(), | 613 this, m_master->shadername().c_str(), |
563 beginop, endop); | 614 beginop, endop); |
564 const int *args = &m_master->m_args[0]; | 615 const int *args = &m_master->m_args[0]; |
565 bool debugnan = m_shadingsys->debug_nan (); | 616 bool debugnan = m_shadingsys->debug_nan (); |
566 for (m_ip = beginop; m_ip < endop && m_beginpoint < m_endpoint; ++m_ip) { | 617 for (m_ip = beginop; m_ip < endop && m_runstate.beginpoint < m_runstate.endp
oint; ++m_ip) { |
567 DASSERT (m_ip >= 0 && m_ip < (int)m_master->m_ops.size()); | 618 DASSERT (m_ip >= 0 && m_ip < (int)m_master->m_ops.size()); |
568 Opcode &op (this->op ()); | 619 Opcode &op (this->op ()); |
| 620 |
| 621 #if 0 |
| 622 // Debugging tool -- sample the run flags |
| 623 static atomic_ll count; |
| 624 if (((++count) % 172933ul /*1142821ul*/) == 0) { // 12117689ul |
| 625 std::cerr << "rf "; |
| 626 for (int i = 0; i < npoints(); ++i) |
| 627 std::cerr << (int)(m_runstate.runflags[i] ? 1 : 0) << ' '; |
| 628 std::cerr << std::endl; |
| 629 } |
| 630 #endif |
| 631 |
569 #if 0 | 632 #if 0 |
570 if (m_debug) { | 633 if (m_debug) { |
571 m_shadingsys->info ("Before running op %d %s, values are:", | 634 m_shadingsys->info ("Before running op %d %s, values are:", |
572 m_ip, op.opname().c_str()); | 635 m_ip, op.opname().c_str()); |
573 for (int i = 0; i < op.nargs(); ++i) { | 636 for (int i = 0; i < op.nargs(); ++i) { |
574 Symbol &s (sym (args[op.firstarg()+i])); | 637 Symbol &s (sym (args[op.firstarg()+i])); |
575 m_shadingsys->info (" %s\n%s", s.mangled().c_str(), | 638 m_shadingsys->info (" %s\n%s", s.mangled().c_str(), |
576 printsymbolval(s).c_str()); | 639 printsymbolval(s).c_str()); |
577 } | 640 } |
578 } | 641 } |
579 #endif | 642 #endif |
580 ASSERT (op.implementation() && "Unimplemented op!"); | 643 ASSERT (op.implementation() && "Unimplemented op!"); |
581 op (this, op.nargs(), args+op.firstarg(), | 644 op (this, op.nargs(), args+op.firstarg()); |
582 m_runflags, m_beginpoint, m_endpoint); | |
583 | 645 |
584 #if 0 | 646 #if 0 |
585 if (m_debug) { | 647 if (m_debug) { |
586 m_shadingsys->info ("After running %s, new values are:", | 648 m_shadingsys->info ("After running %s, new values are:", |
587 op.opname().c_str()); | 649 op.opname().c_str()); |
588 for (int i = 0; i < op.nargs(); ++i) { | 650 for (int i = 0; i < op.nargs(); ++i) { |
589 Symbol &s (sym (args[op.firstarg()+i])); | 651 Symbol &s (sym (args[op.firstarg()+i])); |
590 m_shadingsys->info (" %s\n%s", s.mangled().c_str(), | 652 m_shadingsys->info (" %s\n%s", s.mangled().c_str(), |
591 printsymbolval(s).c_str()); | 653 printsymbolval(s).c_str()); |
592 } | 654 } |
(...skipping 12 matching lines...) Expand all Loading... |
605 // Check every writable argument of this op, at every shading point | 667 // Check every writable argument of this op, at every shading point |
606 // that's turned on, check for NaN and Inf values, and print a | 668 // that's turned on, check for NaN and Inf values, and print a |
607 // warning if found. | 669 // warning if found. |
608 for (int a = 0; a < op.nargs(); ++a) { | 670 for (int a = 0; a < op.nargs(); ++a) { |
609 if (! op.argwrite (a)) | 671 if (! op.argwrite (a)) |
610 continue; // Skip args that weren't written | 672 continue; // Skip args that weren't written |
611 Symbol &s (sym (m_master->m_args[op.firstarg()+a])); | 673 Symbol &s (sym (m_master->m_args[op.firstarg()+a])); |
612 float badval; | 674 float badval; |
613 bool badderiv; | 675 bool badderiv; |
614 int point; | 676 int point; |
615 if (check_nan (s, m_runflags, m_beginpoint, m_endpoint, badval, badderiv
, point)) | 677 if (check_nan (s, badval, badderiv, point)) |
616 m_shadingsys->warning ("Generated %s%g in shader \"%s\",\n" | 678 m_shadingsys->warning ("Generated %s%g in shader \"%s\",\n" |
617 "\tsource \"%s\", line %d (instruction %s, ar
g %d)\n" | 679 "\tsource \"%s\", line %d (instruction %s, ar
g %d)\n" |
618 "\tsymbol \"%s\", %s (step %d), point %d of %
d", | 680 "\tsymbol \"%s\", %s (step %d), point %d of %
d", |
619 badderiv ? "bad derivative " : "", | 681 badderiv ? "bad derivative " : "", |
620 badval, m_master->shadername().c_str(), | 682 badval, m_master->shadername().c_str(), |
621 op.sourcefile().c_str(), | 683 op.sourcefile().c_str(), |
622 op.sourceline(), op.opname().c_str(), a, | 684 op.sourceline(), op.opname().c_str(), a, |
623 s.name().c_str(), s.is_uniform() ? "uniform"
: "varying", s.step(), point, npoints() ); | 685 s.name().c_str(), s.is_uniform() ? "uniform"
: "varying", s.step(), point, npoints() ); |
624 } | 686 } |
625 } | 687 } |
626 | 688 |
627 | 689 |
628 | 690 |
629 bool | 691 bool |
630 ShadingExecution::check_nan (Symbol &sym, Runflag *runflags, | 692 ShadingExecution::check_nan (Symbol &sym, float &badval, |
631 int beginpoint, int endpoint, float &badval, | |
632 bool &badderiv, int &point) | 693 bool &badderiv, int &point) |
633 { | 694 { |
634 if (sym.typespec().is_closure()) | 695 if (sym.typespec().is_closure()) |
635 return false; | 696 return false; |
636 TypeDesc t (sym.typespec().simpletype()); | 697 TypeDesc t (sym.typespec().simpletype()); |
637 badval = 0; | 698 badval = 0; |
638 badderiv = false; | 699 badderiv = false; |
639 if (t.basetype == TypeDesc::FLOAT) { | 700 if (t.basetype == TypeDesc::FLOAT) { |
640 int agg = t.aggregate * t.numelements(); | 701 int agg = t.aggregate * t.numelements(); |
641 for (int i = beginpoint; i < endpoint; ++i) { | 702 ShadingExecution *exec = this; |
642 if (runflags == NULL || runflags[i]) { | 703 SHADE_LOOP_BEGIN |
643 float *f = (float *)((char *)sym.data()+sym.step()*i); | 704 float *f = (float *)((char *)sym.data()+sym.step()*i); |
644 for (int d = 0; d < 3; ++d) { // for each of val, dx, dy | 705 for (int d = 0; d < 3; ++d) { // for each of val, dx, dy |
645 for (int c = 0; c < agg; ++c) | 706 for (int c = 0; c < agg; ++c) |
646 if (! std::isfinite (f[c])) { | 707 if (! std::isfinite (f[c])) { |
647 badval = f[c]; | 708 badval = f[c]; |
648 badderiv = (d > 0); | 709 badderiv = (d > 0); |
649 point = i; | 710 point = i; |
650 return true; | 711 return true; |
651 } | 712 } |
652 if (! sym.has_derivs()) | 713 if (! sym.has_derivs()) |
653 break; // don't advance to next deriv if no derivs | 714 break; // don't advance to next deriv if no derivs |
654 // Step to next derivative | 715 // Step to next derivative |
655 f = (float *)((char *)f + sym.deriv_step()); | 716 f = (float *)((char *)f + sym.deriv_step()); |
656 } | |
657 } | 717 } |
658 } | 718 SHADE_LOOP_END |
659 } | 719 } |
660 return false; | 720 return false; |
661 } | 721 } |
662 | 722 |
663 | 723 |
664 | 724 |
665 void | 725 void |
666 ShadingExecution::run_connected_layer (int layer) | 726 ShadingExecution::run_connected_layer (int layer) |
667 { | 727 { |
668 ExecutionLayers &execlayers (m_context->execlayer (shaderuse())); | 728 ExecutionLayers &execlayers (m_context->execlayer (shaderuse())); |
669 ShadingExecution &connected (execlayers[layer]); | 729 ShadingExecution &connected (execlayers[layer]); |
670 ASSERT (! connected.executed ()); | 730 ASSERT (! connected.executed ()); |
671 | 731 |
672 // Run the earlier layer using the runflags we were originally | 732 // Run the earlier layer using the runflags we were originally |
673 // called with. | 733 // called with. |
674 ShaderGroup &sgroup (m_context->attribs()->shadergroup (shaderuse())); | 734 ShaderGroup &sgroup (m_context->attribs()->shadergroup (shaderuse())); |
675 size_t nlayers = (int) sgroup.nlayers (); | 735 size_t nlayers = (int) sgroup.nlayers (); |
676 #if 0 | 736 #if 0 |
677 std::cerr << "Lazy running layer " << layer << ' ' << "\n"; | 737 std::cerr << "Lazy running layer " << layer << ' ' << "\n"; |
678 #endif | 738 #endif |
679 connected.run (m_context->m_original_runflags); | 739 connected.run (m_context->m_original_runflags,· |
| 740 m_context->m_original_indices, |
| 741 m_context->m_original_nindices); |
680 m_context->m_lazy_evals += 1; | 742 m_context->m_lazy_evals += 1; |
681 | 743 |
682 // Now re-bind the connections between that layer and all other | 744 // Now re-bind the connections between that layer and all other |
683 // later layers that have not yet executed. | 745 // later layers that have not yet executed. |
684 for (int i = layer+1; i < (int)nlayers; ++i) { | 746 for (int i = layer+1; i < (int)nlayers; ++i) { |
685 ShadingExecution &exec (execlayers[i]); | 747 ShadingExecution &exec (execlayers[i]); |
686 if (exec.m_bound && ! exec.m_executed) { | 748 if (exec.m_bound && ! exec.m_executed) { |
687 ShaderInstance *inst = exec.instance(); | 749 ShaderInstance *inst = exec.instance(); |
688 for (int c = 0; c < inst->nconnections(); ++c) { | 750 for (int c = 0; c < inst->nconnections(); ++c) { |
689 const Connection &con (inst->connection (c)); | 751 const Connection &con (inst->connection (c)); |
690 if (con.srclayer == layer) | 752 if (con.srclayer == layer) |
691 exec.bind_connection (con, true /* force dependent bind */); | 753 exec.bind_connection (con, true /* force dependent bind */); |
692 } | 754 } |
693 } | 755 } |
694 } | 756 } |
695 } | 757 } |
696 | 758 |
697 | 759 |
698 | 760 |
699 void | 761 void |
700 ShadingExecution::adjust_varying (Symbol &sym, bool varying_assignment, | 762 ShadingExecution::adjust_varying_makevarying (Symbol &sym, bool preserve_value) |
| 763 { |
| 764 // sym is uniform, but we're either assigning a new varying |
| 765 // value or we're inside a conditional. Promote sym to varying. |
| 766 size_t size = sym.has_derivs() ? 3*sym.deriv_step() : sym.size(); |
| 767 sym.step (size); |
| 768 if (preserve_value || diverged()) { |
| 769 // Propagate the value from slot 0 to other slots |
| 770 char *data = (char *) sym.data(); |
| 771 #if USE_RUNFLAGS |
| 772 SHADE_LOOP_RUNFLAGS_BEGIN (context()->m_original_runflags, |
| 773 0, m_npoints) |
| 774 #elif USE_RUNINDICES |
| 775 SHADE_LOOP_INDICES_BEGIN (context()->m_original_indices, |
| 776 context()->m_original_nindices) |
| 777 #elif USE_RUNSPANS |
| 778 SHADE_LOOP_SPANS_BEGIN (context()->m_original_indices, |
| 779 context()->m_original_nindices) |
| 780 #endif |
| 781 memcpy (data + i*size, data, size); |
| 782 SHADE_LOOP_END |
| 783 } |
| 784 } |
| 785 |
| 786 |
| 787 |
| 788 void |
| 789 ShadingExecution::adjust_varying_full (Symbol &sym, bool varying_assignment, |
701 bool preserve_value) | 790 bool preserve_value) |
702 { | 791 { |
703 // This is tricky. To make sure we're catching all the cases, let's | 792 // This is tricky. To make sure we're catching all the cases, let's |
704 // enumerate them by the current symbol varyingness, the assignent | 793 // enumerate them by the current symbol varyingness, the assignent |
705 // varyingness, and whether all points in the grid are active: | 794 // varyingness, and whether all points in the grid are active: |
706 // case sym assignment all_pts_on action | 795 // case sym assignment diverged action |
707 // 0 v v n v (leave alone) | 796 // 0 v v y v (leave alone) |
708 // 1 v v y v (leave alone) | 797 // 1 v v n v (leave alone) |
709 // 2 v u n v (leave alone) | 798 // 2 v u y v (leave alone) |
710 // 3 v u y u (demote) | 799 // 3 v u n u (demote) |
711 // 4 u v n v (promote) | 800 // 4 u v y v (promote) |
712 // 5 u v y v (promote) | 801 // 5 u v n v (promote) |
713 // 6 u u n v (promote) | 802 // 6 u u y v (promote) |
714 // 7 u u y u (leave alone) | 803 // 7 u u n u (leave alone) |
715 | 804 |
716 // If we're inside a conditional of any kind, even a uniform assignment | 805 // If we're inside a conditional of any kind, even a uniform assignment |
717 // makes the result varying.·· | 806 // makes the result varying.·· |
718 varying_assignment |= diverged(); | 807 varying_assignment |= diverged(); |
719 | 808 |
720 // This reduces us to just four cases: | 809 // This reduces us to just four cases: |
721 // case sym assignment action | 810 // case sym assignment action |
722 // 0/1/2 v v v (leave alone) | 811 // 0/1/2 v v v (leave alone) |
723 // 3 v u u (demote) | 812 // 3 v u u (demote) |
724 // 4/5/6 u v v (promote) | 813 // 4/5/6 u v v (promote) |
(...skipping 20 matching lines...) Expand all Loading... |
745 return; | 834 return; |
746 | 835 |
747 if (varying_assignment) { | 836 if (varying_assignment) { |
748 // sym is uniform, but we're either assigning a new varying | 837 // sym is uniform, but we're either assigning a new varying |
749 // value or we're inside a conditional. Promote sym to varying. | 838 // value or we're inside a conditional. Promote sym to varying. |
750 size_t size = sym.has_derivs() ? 3*sym.deriv_step() : sym.size(); | 839 size_t size = sym.has_derivs() ? 3*sym.deriv_step() : sym.size(); |
751 sym.step (size); | 840 sym.step (size); |
752 if (preserve_value || diverged()) { | 841 if (preserve_value || diverged()) { |
753 // Propagate the value from slot 0 to other slots | 842 // Propagate the value from slot 0 to other slots |
754 char *data = (char *) sym.data(); | 843 char *data = (char *) sym.data(); |
755 for (int i = 1; i < m_npoints; ++i) | 844 #if USE_RUNFLAGS |
| 845 SHADE_LOOP_RUNFLAGS_BEGIN (context()->m_original_runflags, |
| 846 0, m_npoints) |
| 847 #elif USE_RUNINDICES |
| 848 SHADE_LOOP_INDICES_BEGIN (context()->m_original_indices, |
| 849 context()->m_original_nindices) |
| 850 #elif USE_RUNSPANS |
| 851 SHADE_LOOP_SPANS_BEGIN (context()->m_original_indices, |
| 852 context()->m_original_nindices) |
| 853 #endif |
756 memcpy (data + i*size, data, size); | 854 memcpy (data + i*size, data, size); |
| 855 SHADE_LOOP_END |
757 } | 856 } |
758 } else { | 857 } else { |
759 // sym is varying, but we're assigning a new uniform value AND | 858 // sym is varying, but we're assigning a new uniform value AND |
760 // we're not inside a conditional. Safe to demote sym to uniform. | 859 // we're not inside a conditional. Safe to demote sym to uniform. |
761 if (sym.symtype() != SymTypeGlobal) { // DO NOT demote a global | 860 if (sym.symtype() != SymTypeGlobal) { // DO NOT demote a global |
762 sym.step (0); | 861 sym.step (0); |
763 if (sym.has_derivs()) | 862 if (sym.has_derivs()) { |
764 zero_derivs (sym); | 863 size_t deriv_step = sym.deriv_step(); |
| 864 memset ((char *)sym.data()+deriv_step, 0, 2*deriv_step); |
| 865 } |
765 } | 866 } |
766 } | 867 } |
767 } | 868 } |
768 | 869 |
769 | 870 |
770 | 871 |
771 void | 872 void |
772 ShadingExecution::zero (Symbol &sym) | 873 ShadingExecution::zero (Symbol &sym) |
773 { | 874 { |
774 size_t size = sym.has_derivs() ? sym.deriv_step()*3 : sym.size(); | 875 size_t size = sym.has_derivs() ? sym.deriv_step()*3 : sym.size(); |
775 if (sym.is_uniform ()) | 876 if (sym.is_uniform ()) { |
776 memset (sym.data(), 0, size); | 877 memset (sym.data(), 0, size); |
777 else if (sym.is_varying() && all_points_on()) { | 878 #if 0 |
| 879 } else if (sym.is_varying() && all_points_on()) { |
778 // Varying, but we can do one big memset | 880 // Varying, but we can do one big memset |
779 memset (sym.data(), 0, size * m_npoints); | 881 memset (sym.data(), 0, size * m_npoints); |
| 882 #endif |
780 } else { | 883 } else { |
781 // Varying, with some points on and some off | 884 // Varying, with some points on and some off |
782 char *data = (char *)sym.data() + m_beginpoint * sym.step(); | 885 ShadingExecution *exec = this; |
783 for (int i = m_beginpoint; i < m_endpoint; ++i, data += sym.step()) | 886 SHADE_LOOP_BEGIN |
784 if (m_runflags[i]) | 887 memset ((char *)sym.data() + i * sym.step(), 0, size); |
785 memset (data, 0, size); | 888 SHADE_LOOP_END |
786 } | 889 } |
787 } | 890 } |
788 | 891 |
789 | 892 |
790 | 893 |
791 void | 894 void |
792 ShadingExecution::zero_derivs (Symbol &sym) | 895 ShadingExecution::zero_derivs (Symbol &sym) |
793 { | 896 { |
794 DASSERT (sym.has_derivs ()); | 897 DASSERT (sym.has_derivs ()); |
795 size_t deriv_step = sym.deriv_step (); | 898 size_t deriv_step = sym.deriv_step (); |
796 size_t deriv_size = 2 * deriv_step; | 899 size_t deriv_size = 2 * deriv_step; |
797 char *data = (char *)sym.data() + deriv_step; | 900 char *data = (char *)sym.data() + deriv_step; |
798 if (sym.is_uniform ()) | 901 if (sym.is_uniform ()) |
799 memset (data, 0, deriv_size); | 902 memset (data, 0, deriv_size); |
800 else { | 903 else { |
801 data += m_beginpoint * sym.step(); | 904 ShadingExecution *exec = this; |
802 for (int i = m_beginpoint; i < m_endpoint; ++i, data += sym.step()) | 905 SHADE_LOOP_BEGIN |
803 if (m_runflags[i]) | 906 memset (data + i*sym.step(), 0, deriv_size); |
804 memset (data, 0, deriv_size); | 907 SHADE_LOOP_END |
805 } | 908 } |
806 } | 909 } |
807 | 910 |
808 | 911 |
809 | 912 |
810 void | 913 void |
811 ShadingExecution::push_runflags (Runflag *runflags, | 914 ShadingExecution::push_runflags (Runflag *runflags, |
812 int beginpoint, int endpoint) | 915 int beginpoint, int endpoint, |
| 916 int *indices, int nindices) |
813 { | 917 { |
814 ASSERT (runflags != NULL); | 918 ASSERT (runflags != NULL || (indices != NULL /* && nindices != 0*/)); |
815 m_runflags = runflags; | 919 m_runstate.runflags = runflags; |
| 920 m_runstate.init (runflags, beginpoint, endpoint, //m_runstate.allpointson, |
| 921 indices, nindices); |
| 922 #if USE_RUNFLAGS |
816 new_runflag_range (beginpoint, endpoint); | 923 new_runflag_range (beginpoint, endpoint); |
817 m_runflag_stack.push_back (Runstate (m_runflags, m_beginpoint, | 924 #endif |
818 m_endpoint, m_all_points_on)); | 925 m_runflag_stack.push_back (m_runstate); |
819 if (! m_context->m_original_runflags) | 926 if (! m_context->m_original_runflags) |
820 m_context->m_original_runflags = m_runflags; | 927 m_context->m_original_runflags = runflags; |
| 928 if (! m_context->m_original_indices) { |
| 929 m_context->m_original_indices = indices; |
| 930 m_context->m_original_nindices = nindices; |
| 931 } |
821 } | 932 } |
822 | 933 |
823 | 934 |
824 | 935 |
825 void | 936 void |
826 ShadingExecution::pop_runflags () | 937 ShadingExecution::pop_runflags () |
827 { | 938 { |
828 m_runflag_stack.pop_back (); | 939 m_runflag_stack.pop_back (); |
829 if (m_runflag_stack.size()) { | 940 if (m_runflag_stack.size()) { |
830 const Runstate &r (m_runflag_stack.back()); | 941 m_runstate = m_runflag_stack.back(); |
831 m_runflags = r.runflags; | |
832 m_beginpoint = r.beginpoint; | |
833 m_endpoint = r.endpoint; | |
834 m_all_points_on = r.allpointson; | |
835 } else { | 942 } else { |
836 m_runflags = NULL; | 943 m_runstate.runflags = NULL; |
| 944 m_runstate.indices = NULL; |
| 945 m_runstate.nindices = 0; |
837 } | 946 } |
838 } | 947 } |
839 | 948 |
840 | 949 |
841 | 950 |
842 void | 951 void |
843 ShadingExecution::new_runflag_range (int begin, int end) | 952 ShadingExecution::new_runflag_range (int begin, int end) |
844 { | 953 { |
845 m_beginpoint = INT_MAX; | 954 if (! m_runstate.runflags) |
846 m_endpoint = -1; | 955 return; |
847 m_all_points_on = (begin == 0 && end == m_npoints); | 956 m_runstate.beginpoint = INT_MAX; |
| 957 m_runstate.endpoint = -1; |
| 958 // m_runstate.allpointson = (begin == 0 && end == m_npoints); |
848 for (int i = begin; i < end; ++i) { | 959 for (int i = begin; i < end; ++i) { |
849 if (m_runflags[i]) { | 960 if (m_runstate.runflags[i]) { |
850 if (i < m_beginpoint) | 961 if (i < m_runstate.beginpoint) |
851 m_beginpoint = i; | 962 m_runstate.beginpoint = i; |
852 if (i >= m_endpoint) | 963 if (i >= m_runstate.endpoint) |
853 m_endpoint = i+1; | 964 m_runstate.endpoint = i+1; |
854 } else { | 965 } else { |
855 m_all_points_on = false; | 966 // m_runstate.allpointson = false; |
856 } | 967 } |
857 } | 968 } |
858 } | 969 } |
859 | 970 |
860 | 971 |
861 | 972 |
862 std::string | 973 std::string |
863 ShadingExecution::format_symbol (const std::string &format, | 974 ShadingExecution::format_symbol (const std::string &format, |
864 Symbol &sym, int whichpoint) | 975 Symbol &sym, int whichpoint) |
865 { | 976 { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 return s; | 1011 return s; |
901 } | 1012 } |
902 | 1013 |
903 | 1014 |
904 | 1015 |
905 std::string | 1016 std::string |
906 ShadingExecution::printsymbolval (Symbol &sym) | 1017 ShadingExecution::printsymbolval (Symbol &sym) |
907 { | 1018 { |
908 std::stringstream out; | 1019 std::stringstream out; |
909 TypeDesc type = sym.typespec().simpletype(); | 1020 TypeDesc type = sym.typespec().simpletype(); |
910 const char *data = (const char *) sym.data (); | 1021 ShadingExecution *exec = this; |
911 data += m_beginpoint * sym.step(); | 1022 SHADE_LOOP_BEGIN |
912 for (int i = m_beginpoint; i < m_endpoint; ++i, data += sym.step()) { | |
913 if (sym.is_uniform()) | 1023 if (sym.is_uniform()) |
914 out << "\tuniform"; | 1024 out << "\tuniform"; |
915 else if (i == m_beginpoint || (i%8) == 0) | 1025 else if (i == beginpoint() || (i%8) == 0) |
916 out << "\t" << i << ": "; | 1026 out << "\t" << i << ": "; |
917 if (sym.typespec().is_closure()) | 1027 if (sym.typespec().is_closure()) |
918 out << format_symbol (" %s", sym, i); | 1028 out << format_symbol (" %s", sym, i); |
919 else if (type.basetype == TypeDesc::FLOAT) | 1029 else if (type.basetype == TypeDesc::FLOAT) |
920 out << format_symbol (" %g", sym, i); | 1030 out << format_symbol (" %g", sym, i); |
921 else if (type.basetype == TypeDesc::INT) | 1031 else if (type.basetype == TypeDesc::INT) |
922 out << format_symbol (" %d", sym, i); | 1032 out << format_symbol (" %d", sym, i); |
923 else if (type.basetype == TypeDesc::STRING) | 1033 else if (type.basetype == TypeDesc::STRING) |
924 out << format_symbol (" \"%s\"", sym, i); | 1034 out << format_symbol (" \"%s\"", sym, i); |
925 if (i == m_endpoint-1 || (i%8) == 7 || | 1035 if (i == endpoint()-1 || (i%8) == 7 || |
926 sym.is_uniform() || sym.typespec().is_closure()) | 1036 sym.is_uniform() || sym.typespec().is_closure()) |
927 out << "\n"; | 1037 out << "\n"; |
928 if (sym.is_uniform()) | 1038 if (sym.is_uniform()) |
929 break; | 1039 break; |
930 } | 1040 SHADE_LOOP_END |
931 return out.str (); | 1041 return out.str (); |
932 } | 1042 } |
933 | 1043 |
934 | 1044 |
935 | 1045 |
936 void | 1046 void |
937 ShadingExecution::get_matrix (Matrix44 &result, ustring from, int whichpoint) | 1047 ShadingExecution::get_matrix (Matrix44 &result, ustring from, int whichpoint) |
938 { | 1048 { |
939 if (from == Strings::common || from == m_shadingsys->commonspace_synonym())
{ | 1049 if (from == Strings::common || from == m_shadingsys->commonspace_synonym())
{ |
940 result.makeIdentity (); | 1050 result.makeIdentity (); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 get_matrix (Mfrom, from, whichpoint); | 1140 get_matrix (Mfrom, from, whichpoint); |
1031 get_inverse_matrix (Mto, to, whichpoint); | 1141 get_inverse_matrix (Mto, to, whichpoint); |
1032 result = Mfrom * Mto; | 1142 result = Mfrom * Mto; |
1033 } | 1143 } |
1034 | 1144 |
1035 | 1145 |
1036 | 1146 |
1037 | 1147 |
1038 }; // namespace pvt | 1148 }; // namespace pvt |
1039 }; // namespace OSL | 1149 }; // namespace OSL |
OLD | NEW |