LEFT | RIGHT |
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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 } |
130 | 130 |
131 | 131 |
132 | 132 |
133 void | 133 void |
134 ShadingExecution::bind (ShadingContext *context, ShaderUse use, | 134 ShadingExecution::bind (ShaderInstance *instance) |
135 int layerindex, ShaderInstance *instance) | |
136 { | 135 { |
137 ASSERT (! m_bound); // avoid double-binding | 136 ASSERT (! m_bound); // avoid double-binding |
138 ASSERT (context != NULL && instance != NULL); | 137 ASSERT (instance != NULL); |
139 | 138 |
140 m_shadingsys = &context->shadingsys (); | 139 m_shadingsys = &m_context->shadingsys (); |
141 m_debug = shadingsys()->debug(); | 140 m_debug = shadingsys()->debug(); |
142 bool debugnan = m_shadingsys->debug_nan (); | 141 bool debugnan = m_shadingsys->debug_nan (); |
143 if (m_debug) | 142 if (m_debug) |
144 shadingsys()->info ("bind ctx %p use %s layer %d", context, | 143 shadingsys()->info ("bind ctx %p use %s layer %d", m_context, |
145 shaderusename(use), layerindex); | 144 shaderusename(shaderuse()), layer()); |
146 m_use = use; | 145 ++m_context->m_binds; |
147 | 146 |
148 // Take various shortcuts if we are re-binding the same instance as | 147 // Take various shortcuts if we are re-binding the same instance as |
149 // last time. | 148 // last time. |
150 bool rebind = (shadingsys()->allow_rebind() && | 149 bool rebind = (shadingsys()->allow_rebind() && |
151 instance->id() == m_last_instance_id && | 150 instance->id() == m_last_instance_id && |
152 m_npoints_bound >= m_context->npoints()); | 151 m_npoints_bound >= m_context->npoints()); |
153 if (rebind) { | 152 if (rebind) { |
154 ++context->m_rebinds; | 153 ++m_context->m_rebinds; |
155 } else { | 154 } else { |
156 m_context = context; | |
157 m_instance = instance; | 155 m_instance = instance; |
158 m_master = instance->master (); | 156 m_master = instance->master (); |
159 m_renderer = m_shadingsys->renderer (); | 157 m_renderer = m_shadingsys->renderer (); |
160 m_last_instance_id = instance->id (); | 158 m_last_instance_id = instance->id (); |
161 m_npoints_bound = m_context->npoints (); | 159 m_npoints_bound = m_context->npoints (); |
162 ASSERT (m_master && m_context && m_shadingsys && m_renderer); | 160 ASSERT (m_master && m_context && m_shadingsys && m_renderer); |
163 // 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 |
164 // 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 |
165 // below, and reuse all the heap offsets and pointers. We can | 163 // below, and reuse all the heap offsets and pointers. We can |
166 // do that optimization later. | 164 // do that optimization later. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 // No derivs anyway -- don't copy the user's data | 271 // No derivs anyway -- don't copy the user's data |
274 sym.has_derivs (false); | 272 sym.has_derivs (false); |
275 sym.data (valref->ptr()); sym.step (valref->step()); | 273 sym.data (valref->ptr()); sym.step (valref->step()); |
276 // FIXME -- Hmmm... which is better, to avoid the copy | 274 // FIXME -- Hmmm... which is better, to avoid the copy |
277 // here but possibly have the data spread out strangely, | 275 // here but possibly have the data spread out strangely, |
278 // or to copy but then end up with the data contiguous | 276 // or to copy but then end up with the data contiguous |
279 // and in cache? Experiment at some point. | 277 // and in cache? Experiment at some point. |
280 } | 278 } |
281 ASSERT (sym.data() != NULL); | 279 ASSERT (sym.data() != NULL); |
282 } | 280 } |
| 281 float badval; |
| 282 bool badderiv; |
| 283 int point; |
| 284 if (debugnan && check_nan (sym, badval, badderiv, point)) |
| 285 m_shadingsys->warning ("Found %s%g in shader \"%s\" when binding
%s", |
| 286 badderiv ? "bad derivative " : "", |
| 287 badval, m_master->shadername().c_str(), |
| 288 sym.name().c_str());···················· |
283 | 289 |
284 } else if (sym.symtype() == SymTypeParam || | 290 } else if (sym.symtype() == SymTypeParam || |
285 sym.symtype() == SymTypeOutputParam) { | 291 sym.symtype() == SymTypeOutputParam) { |
| 292 m_context->m_paramstobind++; |
286 if (sym.typespec().is_closure()) { | 293 if (sym.typespec().is_closure()) { |
287 // Special case -- closures store pointers in the heap | 294 // Special case -- closures store pointers in the heap |
288 sym.dataoffset (m_context->closure_allot (m_npoints)); | 295 sym.dataoffset (m_context->closure_allot (m_npoints)); |
289 sym.data (m_context->heapaddr (sym.dataoffset())); | 296 sym.data (m_context->heapaddr (sym.dataoffset())); |
290 sym.step (sizeof (ClosureColor *)); | 297 sym.step (sizeof (ClosureColor *)); |
291 } else if (sym.typespec().simpletype().basetype != TypeDesc::UNKNOWN
) { | 298 } else if (sym.typespec().simpletype().basetype != TypeDesc::UNKNOWN
) { |
292 size_t addr = context->heap_allot (sym.derivsize() * m_npoints); | 299 size_t addr = m_context->heap_allot (sym.derivsize() * m_npoints
); |
293 sym.data (m_context->heapaddr (addr)); | 300 sym.data (m_context->heapaddr (addr)); |
294 sym.step (0); // FIXME | 301 sym.step (0); |
295 // Copy the parameter value | |
296 // FIXME -- if the parameter is not being overridden and is | |
297 // not writeable, I think we should just point to the parameter | |
298 // data, not copy it? Or does it matter? | |
299 if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT) | |
300 memcpy (sym.data(), &instance->m_fparams[sym.dataoffset()], | |
301 sym.typespec().simpletype().size()); | |
302 else if (sym.typespec().simpletype().basetype == TypeDesc::INT) | |
303 memcpy (sym.data(), &instance->m_iparams[sym.dataoffset()], | |
304 sym.typespec().simpletype().size()); | |
305 else if (sym.typespec().simpletype().basetype == TypeDesc::STRIN
G) | |
306 memcpy (sym.data(), &instance->m_sparams[sym.dataoffset()], | |
307 sym.typespec().simpletype().size()); | |
308 else { | |
309 ASSERT (0 && "unrecognized type -- no default value"); | |
310 } | |
311 if (sym.has_derivs ()) | |
312 zero_derivs (sym); | |
313 } else { | 302 } else { |
314 sym.data ((void*) 0); // reset data ptr -- this symbol should nev
er be used | 303 sym.data ((void*) 0); // reset data ptr -- this symbol should nev
er be used |
315 sym.step (0); | 304 sym.step (0); |
316 } | 305 } |
317 } else if (sym.symtype() == SymTypeLocal || | 306 } else if (sym.symtype() == SymTypeLocal || |
318 sym.symtype() == SymTypeTemp) { | 307 sym.symtype() == SymTypeTemp) { |
319 ASSERT (sym.dataoffset() < 0); | 308 ASSERT (sym.dataoffset() < 0); |
320 if (sym.typespec().is_closure()) { | 309 if (sym.typespec().is_closure()) { |
321 // Special case -- closures store pointers in the heap, and | 310 // Special case -- closures store pointers in the heap, and |
322 // they are always varying. | 311 // they are always varying. |
(...skipping 18 matching lines...) Expand all Loading... |
341 ASSERT (sym.data() != NULL && | 330 ASSERT (sym.data() != NULL && |
342 "Const symbol should already have valid data address"); | 331 "Const symbol should already have valid data address"); |
343 } else { | 332 } else { |
344 ASSERT (0 && "Should never get here"); | 333 ASSERT (0 && "Should never get here"); |
345 } | 334 } |
346 if (m_debug) | 335 if (m_debug) |
347 m_shadingsys->info (" bound %s to address %p, step %d, size %d %s", | 336 m_shadingsys->info (" bound %s to address %p, step %d, size %d %s", |
348 sym.mangled().c_str(), sym.data(), | 337 sym.mangled().c_str(), sym.data(), |
349 sym.step(), sym.size(), | 338 sym.step(), sym.size(), |
350 sym.has_derivs() ? "(derivs)" : "(no derivs)"); | 339 sym.has_derivs() ? "(derivs)" : "(no derivs)"); |
351 float badval; | 340 } |
352 bool badderiv; | |
353 int point; | |
354 if (debugnan && | |
355 (sym.symtype() != SymTypeLocal && sym.symtype() != SymTypeTemp) && | |
356 check_nan (sym, badval, badderiv, point)) | |
357 m_shadingsys->warning ("Found %s%g in shader \"%s\" when binding %s"
, | |
358 badderiv ? "bad derivative " : "", | |
359 badval, m_master->shadername().c_str(), | |
360 sym.name().c_str());···················· | |
361 } | |
362 | |
363 // Handle all of the symbols that are connected to earlier layers. | |
364 bind_connections (); | |
365 | |
366 // Mark symbols that map to user-data on the geometry | |
367 bind_mark_geom_variables (m_instance); | |
368 | 341 |
369 // OK, we're successfully bound. | 342 // OK, we're successfully bound. |
370 m_bound = true; | 343 m_bound = true; |
371 | 344 |
372 #ifdef DEBUG_ADJUST_VARYING | 345 #ifdef DEBUG_ADJUST_VARYING |
373 m_adjust_calls = 0; | 346 m_adjust_calls = 0; |
374 m_keep_varying = 0; | 347 m_keep_varying = 0; |
375 m_keep_uniform = 0; | 348 m_keep_uniform = 0; |
376 m_make_varying = 0; | 349 m_make_varying = 0; |
377 m_make_uniform = 0; | 350 m_make_uniform = 0; |
378 #endif | 351 #endif |
379 } | 352 } |
380 | 353 |
381 | 354 |
382 | 355 |
383 void | 356 void |
384 ShadingExecution::bind_initialize_params (ShaderInstance *inst) | 357 ShadingExecution::bind_initialize_param (Symbol *sym, int symindex) |
385 { | 358 { |
386 ShaderMaster *master = inst->master(); | 359 ASSERT (! sym->initialized ()); |
387 bool debugnan = m_shadingsys->debug_nan (); | 360 m_context->m_paramsbound++; |
388 for (int i = master->m_firstparam; i <= master->m_lastparam; ++i) { | 361 |
389 Symbol *sym = symptr (i); | 362 // Resolve symbols that map to user-data on the geometry |
390 if (sym->valuesource() == Symbol::DefaultVal) { | 363 if (sym->valuesource() != Symbol::ConnectedVal) { |
391 // Execute init ops, if there are any | 364 if (renderer_has_userdata (sym->name(), sym->typespec().simpletype(), |
392 if (sym->initbegin() != sym->initend()) { | 365 &m_context->m_globals->renderstate[0])) { |
393 run (context()->m_original_runflags, | 366 sym->valuesource(Symbol::GeomVal); |
394 context()->m_original_indices, | 367 } |
395 context()->m_original_nindices, | 368 } |
396 sym->initbegin(), sym->initend()); | 369 |
| 370 if (sym->valuesource() == Symbol::DefaultVal || |
| 371 sym->valuesource() == Symbol::InstanceVal) { |
| 372 |
| 373 if (sym->valuesource() == Symbol::DefaultVal && |
| 374 sym->initbegin() != sym->initend()) { |
| 375 // If it's still a default value and it's determined by init |
| 376 // ops, run them now |
| 377 int old_ip = m_ip; // Save the instruction pointer |
| 378 run (context()->m_original_runflags, |
| 379 context()->m_original_indices, context()->m_original_nindices, |
| 380 sym->initbegin(), sym->initend()); |
| 381 m_ip = old_ip; |
| 382 } |
| 383 else if (!sym->typespec().is_closure() && !sym->typespec().is_structure(
)) { |
| 384 // Otherwise, if it's a normal data type (non-closure, |
| 385 // non-struct) copy its instance and/or default value now. |
| 386 DASSERT (sym->step() == 0); |
| 387 if (sym->typespec().simpletype().basetype == TypeDesc::FLOAT) |
| 388 memcpy (sym->data(), &m_instance->m_fparams[sym->dataoffset()], |
| 389 sym->typespec().simpletype().size()); |
| 390 else if (sym->typespec().simpletype().basetype == TypeDesc::INT) |
| 391 memcpy (sym->data(), &m_instance->m_iparams[sym->dataoffset()], |
| 392 sym->typespec().simpletype().size()); |
| 393 else if (sym->typespec().simpletype().basetype == TypeDesc::STRING) |
| 394 memcpy (sym->data(), &m_instance->m_sparams[sym->dataoffset()], |
| 395 sym->typespec().simpletype().size()); |
| 396 else { |
| 397 std::cerr << "Type is " << sym->typespec().c_str() << "\n"; |
| 398 ASSERT (0 && "unrecognized type -- no default value"); |
397 } | 399 } |
398 } else if (sym->valuesource() == Symbol::InstanceVal) { | 400 if (sym->has_derivs ()) |
399 // FIXME -- eventually, copy the instance values here, | 401 zero_derivs (*sym); |
400 // rather than above in bind(), so that we skip the | 402 // FIXME -- is there anything to be gained by just pointing |
401 // unnecessary copying if the values came from geom or | 403 // to the parameter data, not copying it? |
402 // connections. As it stands now, there is some redundancy. | 404 } |
403 } else if (sym->valuesource() == Symbol::GeomVal) { | 405 |
404 adjust_varying(*sym, true, false /* don't keep old values */); | 406 } else if (sym->valuesource() == Symbol::GeomVal) { |
405 bool wants_derivatives = (sym->typespec().is_float() || sym->typespe
c().is_triple()); | 407 adjust_varying(*sym, true, false /* don't keep old values */); |
406 ShaderGlobals *globals = m_context->m_globals; | 408 bool wants_derivatives = (sym->typespec().is_float() || sym->typespec().
is_triple()); |
407 if (!get_renderer_userdata(context()->m_original_runflags, m_npoints
, wants_derivatives, | 409 ShaderGlobals *globals = m_context->m_globals; |
408 sym->name(), sym->typespec().simpletype(
), | 410 if (!get_renderer_userdata(context()->m_original_runflags, m_npoints, wa
nts_derivatives, |
409 &globals->renderstate[0], globals->rende
rstate.step(), | 411 sym->name(), sym->typespec().simpletype(), |
410 sym->data(), sym->step())) { | 412 &globals->renderstate[0], globals->renderstat
e.step(), |
| 413 sym->data(), sym->step())) { |
411 #ifdef DEBUG | 414 #ifdef DEBUG |
412 std::cerr << "could not find previously found userdata '" << sym
->name() << "'\n"; | 415 std::cerr << "could not find previously found userdata '" << sym->na
me() << "'\n"; |
413 #endif | 416 #endif |
| 417 } |
| 418 } else if (sym->valuesource() == Symbol::ConnectedVal) { |
| 419 // Run through all connections for this layer |
| 420 ExecutionLayers &execlayers (m_context->execlayer (shaderuse())); |
| 421 for (int c = 0; c < m_instance->nconnections(); ++c) { |
| 422 const Connection &con (m_instance->connection (c)); |
| 423 // If the connection gives a value to this param AND the earlier |
| 424 // layer it comes from has not yet been executed, do so now. |
| 425 if (con.dst.param == symindex && |
| 426 ! execlayers[con.srclayer].executed()) { |
| 427 run_connected_layer (con.srclayer); |
414 } | 428 } |
415 float badval; | 429 } |
416 bool badderiv; | 430 } |
417 int point; | 431 |
418 if (debugnan && check_nan (*sym, badval, badderiv, point)) | 432 float badval; |
419 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpo
lating %s", | 433 bool badderiv; |
420 badderiv ? "bad derivative " : "", | 434 int point; |
421 badval, m_master->shadername().c_str(), | 435 if (m_shadingsys->debug_nan() && |
422 sym->name().c_str()); | 436 check_nan (*sym, badval, badderiv, point)) |
423 } else if (sym->valuesource() == Symbol::ConnectedVal) { | 437 m_shadingsys->warning ("Found %s%g in shader \"%s\" when interpolating %
s", |
424 // Nothing to do if it fully came from an earlier layer | 438 badderiv ? "bad derivative " : "", |
425 } | 439 badval, m_master->shadername().c_str(), |
426 } | 440 sym->name().c_str()); |
427 } | 441 |
428 | 442 sym->initialized (true); |
429 | |
430 | |
431 void | |
432 ShadingExecution::bind_mark_geom_variables (ShaderInstance *inst) | |
433 { | |
434 ShaderGlobals *globals (m_context->m_globals); | |
435 ShaderMaster *master = inst->master(); | |
436 for (int i = master->m_firstparam; i <= master->m_lastparam; ++i) { | |
437 Symbol *sym = symptr (i); | |
438 if (sym->valuesource() != Symbol::ConnectedVal) { | |
439 if (renderer_has_userdata (sym->name(), sym->typespec().simpletype()
, &globals->renderstate[0])) { | |
440 sym->valuesource(Symbol::GeomVal); | |
441 } | |
442 } | |
443 } | |
444 } | 443 } |
445 | 444 |
446 | 445 |
447 | 446 |
448 void | 447 void |
449 ShadingExecution::bind_connections () | 448 ShadingExecution::bind_connections () |
450 { | 449 { |
| 450 // std::cerr << " bind_connections " << m_instance->nconnections() << "\n"; |
451 for (int i = 0; i < m_instance->nconnections(); ++i) | 451 for (int i = 0; i < m_instance->nconnections(); ++i) |
452 bind_connection (m_instance->connection (i)); | 452 bind_connection (m_instance->connection (i)); |
453 // FIXME -- you know, the connectivity is fixed for the whole group | 453 // FIXME -- you know, the connectivity is fixed for the whole group |
454 // and its instances. We *could* mark them as connected and possibly | 454 // and its instances. We *could* mark them as connected and possibly |
455 // 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 |
456 // once per execution. Come back to this later and investigate. | 456 // once per execution. Come back to this later and investigate. |
457 } | 457 } |
458 | 458 |
459 | 459 |
460 | 460 |
461 void | 461 void |
462 ShadingExecution::bind_connection (const Connection &con) | 462 ShadingExecution::bind_connection (const Connection &con, bool forcebind) |
463 { | 463 { |
464 int symindex = con.dst.param; | 464 int symindex = con.dst.param; |
465 Symbol &dstsym (sym (symindex)); | 465 Symbol &dstsym (sym (symindex)); |
466 ExecutionLayers &execlayers (context()->execlayer (shaderuse())); | 466 ExecutionLayers &execlayers (context()->execlayer (shaderuse())); |
467 ShadingExecution &srcexec (execlayers[con.srclayer]); | 467 ShadingExecution &srcexec (execlayers[con.srclayer]); |
468 ASSERT (srcexec.m_bound); | 468 if (! srcexec.m_bound) { |
| 469 if (! forcebind) { |
| 470 // If we're not forcing a full bind now (because it may be |
| 471 // lazy), just mark the symbol as connectted but don't bind |
| 472 // its dependency or copy any values yet. |
| 473 dstsym.valuesource (Symbol::ConnectedVal); |
| 474 return; |
| 475 } |
| 476 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); |
| 477 srcexec.bind (sgroup[con.srclayer]); |
| 478 } |
469 Symbol &srcsym (srcexec.sym (con.src.param)); | 479 Symbol &srcsym (srcexec.sym (con.src.param)); |
470 #if 0 | 480 #if 0 |
471 std::cerr << " bind_connection: layer " << con.srclayer << ' ' | 481 std::cerr << " bind_connection: layer " << con.srclayer << ' ' |
472 << srcexec.instance()->layername() << ' ' << srcsym.name() | 482 << srcexec.instance()->layername() << ' ' << srcsym.name() |
473 << " to " << m_instance->layername() << ' ' | 483 << " to " << m_instance->layername() << ' ' |
474 << dstsym.name() << "\n"; | 484 << dstsym.name() << "\n"; |
475 #endif | 485 #endif |
476 | 486 |
477 // Try to identify the simple case where we can just alias the | 487 // Try to identify the simple case where we can just alias the |
478 // variable, with no copying. | 488 // variable, with no copying. |
(...skipping 19 matching lines...) Expand all Loading... |
498 srcsym.typespec().c_str(), srcsym.name().c_str(), | 508 srcsym.typespec().c_str(), srcsym.name().c_str(), |
499 dstsym.typespec().c_str(), dstsym.name().c_str()); | 509 dstsym.typespec().c_str(), dstsym.name().c_str()); |
500 return; | 510 return; |
501 } | 511 } |
502 dstsym.connected (true); | 512 dstsym.connected (true); |
503 } | 513 } |
504 | 514 |
505 | 515 |
506 | 516 |
507 void | 517 void |
508 ShadingExecution::unbind () | |
509 { | |
510 m_bound = false; | |
511 m_executed = false; | |
512 } | |
513 | |
514 | |
515 | |
516 void | |
517 ShadingExecution::run (Runflag *rf, int *ind, int nind, 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 ASSERT (m_bound); // We'd better be bound at this point | 527 // Bind now if it is not already bound. |
| 528 if (! m_bound) { |
| 529 ShaderGroup &sgroup (context()->attribs()->shadergroup (shaderuse())); |
| 530 bind (sgroup[layer()]); |
| 531 } |
527 | 532 |
528 // Make space for new runflags | 533 // Make space for new runflags |
529 #if USE_RUNFLAGS | 534 #if USE_RUNFLAGS |
530 Runflag *runflags = ALLOCA (Runflag, m_npoints); | 535 Runflag *runflags = ALLOCA (Runflag, m_npoints); |
531 int *indices = NULL; | 536 int *indices = NULL; |
532 int nindices = 0; | 537 int nindices = 0; |
533 if (rf) { | 538 if (rf) { |
534 // Passed runflags -- copy those | 539 // Passed runflags -- copy those |
535 memcpy (runflags, rf, m_npoints*sizeof(Runflag)); | 540 memcpy (runflags, rf, m_npoints*sizeof(Runflag)); |
536 } else if (ind) { | 541 } else if (ind) { |
537 // Passed indices -- need to convert to runflags | 542 // Passed indices -- need to convert to runflags |
538 memset (runflags, RunflagOff, m_npoints*sizeof(Runflag)); | 543 memset (runflags, RunflagOff, m_npoints*sizeof(Runflag)); |
539 for (int i = 0; i < nind; ++i) | 544 for (int i = 0; i < nind; ++i) |
540 runflags[indices[i]] = RunflagOn; | 545 runflags[indices[i]] = RunflagOn; |
541 } else { | 546 } else { |
542 // If not passed runflags, make new ones | 547 // If not passed runflags, make new ones |
543 for (int i = 0; i < m_npoints; ++i) | 548 for (int i = 0; i < m_npoints; ++i) |
544 runflags[i] = RunflagOn; | 549 runflags[i] = RunflagOn; |
545 } | 550 } |
546 #elif USE_RUNINDICES | 551 #elif USE_RUNINDICES |
547 Runflag *runflags = NULL; | 552 Runflag *runflags = NULL; |
(...skipping 26 matching lines...) Expand all Loading... |
574 runflags_to_spans (rf, 0, m_npoints, indices, nindices); | 579 runflags_to_spans (rf, 0, m_npoints, indices, nindices); |
575 } else { | 580 } else { |
576 // If not passed either, make new ones | 581 // If not passed either, make new ones |
577 indices = ALLOCA (int, 2); // max space we could need | 582 indices = ALLOCA (int, 2); // max space we could need |
578 nindices = 2; | 583 nindices = 2; |
579 indices[0] = 0; | 584 indices[0] = 0; |
580 indices[1] = m_npoints; | 585 indices[1] = m_npoints; |
581 } | 586 } |
582 #endif | 587 #endif |
583 | 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"; |
| 593 |
584 m_conditional_level = 0; | 594 m_conditional_level = 0; |
585 push_runflags (runflags, 0, m_npoints, indices, nindices); | 595 push_runflags (runflags, 0, m_npoints, indices, nindices); |
586 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 |
587 run (beginop, endop); | 597 run (beginop, endop); |
588 else { // Default (<0) means run param init ops + main code | 598 else { // Default (<0) means run param init ops + main code |
589 bind_initialize_params (m_instance); // run param init code | 599 bind_connections (); // Handle syms connected to earlier layers |
590 run (m_master->m_maincodebegin, m_master->m_maincodeend); | 600 run (m_master->m_maincodebegin, m_master->m_maincodeend); |
591 m_executed = true; | 601 m_executed = true; |
592 } | 602 } |
593 pop_runflags (); | 603 pop_runflags (); |
594 } | 604 } |
595 | 605 |
596 | 606 |
597 | 607 |
598 void | 608 void |
599 ShadingExecution::run (int beginop, int endop) | 609 ShadingExecution::run (int beginop, int endop) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 SHADE_LOOP_END | 718 SHADE_LOOP_END |
709 } | 719 } |
710 return false; | 720 return false; |
711 } | 721 } |
712 | 722 |
713 | 723 |
714 | 724 |
715 void | 725 void |
716 ShadingExecution::run_connected_layer (int layer) | 726 ShadingExecution::run_connected_layer (int layer) |
717 { | 727 { |
718 ShadingContext *ctx = context(); | 728 ExecutionLayers &execlayers (m_context->execlayer (shaderuse())); |
719 ShaderUse use = ctx->use(); | |
720 ExecutionLayers &execlayers (ctx->execlayer (use)); | |
721 ShadingExecution &connected (execlayers[layer]); | 729 ShadingExecution &connected (execlayers[layer]); |
722 ASSERT (! connected.executed ()); | 730 ASSERT (! connected.executed ()); |
723 | 731 |
724 // Run the earlier layer using the runflags we were originally | 732 // Run the earlier layer using the runflags we were originally |
725 // called with. | 733 // called with. |
726 ShaderGroup &sgroup (ctx->attribs()->shadergroup (use)); | 734 ShaderGroup &sgroup (m_context->attribs()->shadergroup (shaderuse())); |
727 size_t nlayers = (int) sgroup.nlayers (); | 735 size_t nlayers = (int) sgroup.nlayers (); |
728 if (! connected.m_bound) | 736 #if 0 |
729 connected.bind (ctx, use, layer, sgroup[layer]); | 737 std::cerr << "Lazy running layer " << layer << ' ' << "\n"; |
730 connected.run (ctx->m_original_runflags,· | 738 #endif |
731 ctx->m_original_indices, ctx->m_original_nindices); | 739 connected.run (m_context->m_original_runflags,· |
732 ctx->m_lazy_evals += 1; | 740 m_context->m_original_indices, |
| 741 m_context->m_original_nindices); |
| 742 m_context->m_lazy_evals += 1; |
733 | 743 |
734 // Now re-bind the connections between that layer and all other | 744 // Now re-bind the connections between that layer and all other |
735 // later layers that have not yet executed. | 745 // later layers that have not yet executed. |
736 for (int i = layer+1; i < (int)nlayers; ++i) { | 746 for (int i = layer+1; i < (int)nlayers; ++i) { |
737 ShadingExecution &exec (execlayers[i]); | 747 ShadingExecution &exec (execlayers[i]); |
738 if (exec.m_bound && ! exec.m_executed) { | 748 if (exec.m_bound && ! exec.m_executed) { |
739 ShaderInstance *inst = exec.instance(); | 749 ShaderInstance *inst = exec.instance(); |
740 for (int c = 0; c < inst->nconnections(); ++c) { | 750 for (int c = 0; c < inst->nconnections(); ++c) { |
741 const Connection &con (inst->connection (c)); | 751 const Connection &con (inst->connection (c)); |
742 if (con.srclayer == layer) | 752 if (con.srclayer == layer) |
743 exec.bind_connection (con); | 753 exec.bind_connection (con, true /* force dependent bind */); |
744 } | 754 } |
745 } | 755 } |
746 } | 756 } |
747 } | 757 } |
748 | 758 |
749 | 759 |
750 | 760 |
751 void | 761 void |
752 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, |
753 bool preserve_value) | 790 bool preserve_value) |
754 { | 791 { |
755 // 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 |
756 // enumerate them by the current symbol varyingness, the assignent | 793 // enumerate them by the current symbol varyingness, the assignent |
757 // varyingness, and whether all points in the grid are active: | 794 // varyingness, and whether all points in the grid are active: |
758 // case sym assignment diverged action | 795 // case sym assignment diverged action |
759 // 0 v v y v (leave alone) | 796 // 0 v v y v (leave alone) |
760 // 1 v v n v (leave alone) | 797 // 1 v v n v (leave alone) |
761 // 2 v u y v (leave alone) | 798 // 2 v u y v (leave alone) |
762 // 3 v u n u (demote) | 799 // 3 v u n u (demote) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 return; | 834 return; |
798 | 835 |
799 if (varying_assignment) { | 836 if (varying_assignment) { |
800 // sym is uniform, but we're either assigning a new varying | 837 // sym is uniform, but we're either assigning a new varying |
801 // value or we're inside a conditional. Promote sym to varying. | 838 // value or we're inside a conditional. Promote sym to varying. |
802 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(); |
803 sym.step (size); | 840 sym.step (size); |
804 if (preserve_value || diverged()) { | 841 if (preserve_value || diverged()) { |
805 // Propagate the value from slot 0 to other slots | 842 // Propagate the value from slot 0 to other slots |
806 char *data = (char *) sym.data(); | 843 char *data = (char *) sym.data(); |
807 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 |
808 memcpy (data + i*size, data, size); | 854 memcpy (data + i*size, data, size); |
| 855 SHADE_LOOP_END |
809 } | 856 } |
810 } else { | 857 } else { |
811 // 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 |
812 // 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. |
813 if (sym.symtype() != SymTypeGlobal) { // DO NOT demote a global | 860 if (sym.symtype() != SymTypeGlobal) { // DO NOT demote a global |
814 sym.step (0); | 861 sym.step (0); |
815 if (sym.has_derivs()) | 862 if (sym.has_derivs()) { |
816 zero_derivs (sym); | 863 size_t deriv_step = sym.deriv_step(); |
| 864 memset ((char *)sym.data()+deriv_step, 0, 2*deriv_step); |
| 865 } |
817 } | 866 } |
818 } | 867 } |
819 } | 868 } |
820 | 869 |
821 | 870 |
822 | 871 |
823 void | 872 void |
824 ShadingExecution::zero (Symbol &sym) | 873 ShadingExecution::zero (Symbol &sym) |
825 { | 874 { |
826 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(); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 get_matrix (Mfrom, from, whichpoint); | 1140 get_matrix (Mfrom, from, whichpoint); |
1092 get_inverse_matrix (Mto, to, whichpoint); | 1141 get_inverse_matrix (Mto, to, whichpoint); |
1093 result = Mfrom * Mto; | 1142 result = Mfrom * Mto; |
1094 } | 1143 } |
1095 | 1144 |
1096 | 1145 |
1097 | 1146 |
1098 | 1147 |
1099 }; // namespace pvt | 1148 }; // namespace pvt |
1100 }; // namespace OSL | 1149 }; // namespace OSL |
LEFT | RIGHT |