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 29 matching lines...) Expand all Loading... |
40 #ifdef OSL_NAMESPACE | 40 #ifdef OSL_NAMESPACE |
41 namespace OSL_NAMESPACE { | 41 namespace OSL_NAMESPACE { |
42 #endif | 42 #endif |
43 | 43 |
44 namespace OSL { | 44 namespace OSL { |
45 namespace pvt { | 45 namespace pvt { |
46 | 46 |
47 | 47 |
48 /// Macro that defines the arguments to shading opcode implementations | 48 /// Macro that defines the arguments to shading opcode implementations |
49 /// | 49 /// |
50 #define OPARGSDECL ShadingExecution *exec, int nargs, const int *args, \ | 50 #define OPARGSDECL ShadingExecution *exec, int nargs, const int *args |
51 Runflag *runflags, int beginpoint, int endpoint | |
52 | 51 |
53 /// Macro that defines the full declaration of a shading opcode | 52 /// Macro that defines the full declaration of a shading opcode |
54 /// implementation | 53 /// implementation |
55 #define DECLOP(name) void name (OPARGSDECL) | 54 #define DECLOP(name) void name (OPARGSDECL) |
56 | 55 |
57 | 56 |
58 // Declarations of all our shader opcodes follow: | 57 // Declarations of all our shader opcodes follow: |
59 | 58 |
60 //DECLOP (OP_aastep); | 59 //DECLOP (OP_aastep); |
61 DECLOP (OP_aassign); | 60 DECLOP (OP_aassign); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 DECLOP (OP_vector); | 225 DECLOP (OP_vector); |
227 DECLOP (OP_ward); | 226 DECLOP (OP_ward); |
228 DECLOP (OP_warning); | 227 DECLOP (OP_warning); |
229 DECLOP (OP_westin_backscatter); | 228 DECLOP (OP_westin_backscatter); |
230 DECLOP (OP_westin_sheen); | 229 DECLOP (OP_westin_sheen); |
231 DECLOP (OP_xor); | 230 DECLOP (OP_xor); |
232 | 231 |
233 DECLOP (OP_missing); | 232 DECLOP (OP_missing); |
234 | 233 |
235 | 234 |
| 235 |
| 236 // Below are macros that define handy ways to loop over all active shade |
| 237 // points in a uniform way regardless of whether we are using runflags, |
| 238 // indices, or spans. |
| 239 // |
| 240 // Runflags are an array of npoints true/false values saying whether |
| 241 // each point is on or off. |
| 242 // Indices are an array of nindices giving the index of each point |
| 243 // that is on. |
| 244 // Spans are like indices, but give the [begin,end) range spans of "on" |
| 245 // points, so the length of the array is 2*nspans. |
| 246 |
| 247 #if USE_RUNFLAGS |
| 248 # define SHADE_LOOP_RUNFLAGS_BEGIN(r,b,e) \ |
| 249 { \ |
| 250 const Runflag *runflags_ = r; \ |
| 251 int end_ = e; \ |
| 252 for (int i = b; i < end_; ++i) \ |
| 253 if (runflags_[i]) { |
| 254 |
| 255 # define SHADE_LOOP_BEGIN \ |
| 256 SHADE_LOOP_RUNFLAGS_BEGIN (exec->runstate().runflags, \ |
| 257 exec->runstate().beginpoint, \ |
| 258 exec->runstate().endpoint) |
| 259 |
| 260 #elif USE_RUNINDICES |
| 261 # define SHADE_LOOP_INDICES_BEGIN(ind,n) \ |
| 262 { \ |
| 263 const RunIndex *indices_ = ind; \ |
| 264 int nindices_ = n; \ |
| 265 for (int ind_ = 0; ind_ < nindices_; ++ind_) { \ |
| 266 int i = indices_[ind_]; |
| 267 |
| 268 # define SHADE_LOOP_BEGIN \ |
| 269 SHADE_LOOP_INDICES_BEGIN (exec->runstate().indices, \ |
| 270 exec->runstate().nindices) |
| 271 |
| 272 #elif USE_RUNSPANS |
| 273 # define SHADE_LOOP_SPANS_BEGIN(ind,n) \ |
| 274 { \ |
| 275 const int *spans_ = ind; \ |
| 276 int nspans_ = n/2; \ |
| 277 for ( ; nspans_; --nspans_, spans_ += 2) \ |
| 278 for (int i = spans_[0]; i < spans_[1]; ++i) { |
| 279 |
| 280 # define SHADE_LOOP_BEGIN \ |
| 281 SHADE_LOOP_SPANS_BEGIN (exec->runstate().indices, \ |
| 282 exec->runstate().nindices) |
| 283 |
| 284 // Utility to convert something that looks like runflags to spans |
| 285 template<class RF> |
| 286 inline bool runflags_to_spans (RF &rf, int beg, int end, |
| 287 int *indices, int &nindices, int onval = 1) |
| 288 { |
| 289 bool any_off = false; |
| 290 for (int i = beg; i < end; ++i) { |
| 291 if (rf[i] == onval) { |
| 292 indices[nindices++] = i; |
| 293 while (i < end && rf[i] == onval) // Skip to next 0 |
| 294 ++i; |
| 295 indices[nindices++] = i; |
| 296 any_off |= (i < end); // stopped because of an off point |
| 297 } else { |
| 298 any_off = true; |
| 299 } |
| 300 } |
| 301 return any_off; |
| 302 } |
| 303 |
| 304 // Utility to copy spans-to-spans, but only when the thing that looks like |
| 305 // runflags matches the 'onval'. |
| 306 template<class RF> |
| 307 inline bool spans_runflags_to_spans (int *spans, int spanlength, RF &rf, |
| 308 int *indices, int &nindices, int onval=1) |
| 309 { |
| 310 bool any_off = false; |
| 311 for (int s = 0; s < spanlength; s += 2) |
| 312 any_off |= runflags_to_spans (rf, spans[s], spans[s+1], |
| 313 indices, nindices, onval); |
| 314 return any_off; |
| 315 } |
| 316 |
| 317 #endif |
| 318 |
| 319 # define SHADE_LOOP_END }} |
| 320 |
| 321 #define SHADE_LOOP(x) SHADE_LOOP_BEGIN x SHADE_LOOP_END |
| 322 |
| 323 |
| 324 |
| 325 |
236 // Heavy lifting of the math and other ternary ops, this is a templated | 326 // Heavy lifting of the math and other ternary ops, this is a templated |
237 // version that knows the types of the arguments and the operation to | 327 // version that knows the types of the arguments and the operation to |
238 // perform (given by a functor). | 328 // perform (given by a functor). |
239 template <class RET, class ATYPE, class BTYPE, class CTYPE, class DTYPE, class F
UNCTION> | 329 template <class RET, class ATYPE, class BTYPE, class CTYPE, class DTYPE, class F
UNCTION> |
240 inline void | 330 inline void |
241 quaternary_op_guts (Symbol &Result, Symbol &A, Symbol &B, Symbol &C, Symbol &D, | 331 quaternary_op_guts (Symbol &Result, Symbol &A, Symbol &B, Symbol &C, Symbol &D, |
242 ShadingExecution *exec, | 332 ShadingExecution *exec, bool zero_derivs=true) |
243 Runflag *runflags, int beginpoint, int endpoint, | |
244 bool zero_derivs=true) | |
245 { | 333 { |
246 // Adjust the result's uniform/varying status | 334 // Adjust the result's uniform/varying status |
247 exec->adjust_varying (Result, A.is_varying() | B.is_varying() | C.is_varying
() | D.is_varying(), | 335 exec->adjust_varying (Result, A.is_varying() | B.is_varying() | C.is_varying
() | D.is_varying(), |
248 A.data() == Result.data() || B.data() == Result.data()
|| | 336 A.data() == Result.data() || B.data() == Result.data()
|| |
249 C.data() == Result.data() || D.data() == Result.data()
); | 337 C.data() == Result.data() || D.data() == Result.data()
); |
250 | 338 |
251 // Loop over points, do the operation | 339 // Loop over points, do the operation |
252 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 340 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
253 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); | 341 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); |
254 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); | 342 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); |
255 VaryingRef<CTYPE> c ((CTYPE *)C.data(), C.step()); | 343 VaryingRef<CTYPE> c ((CTYPE *)C.data(), C.step()); |
256 VaryingRef<DTYPE> d ((DTYPE *)D.data(), D.step()); | 344 VaryingRef<DTYPE> d ((DTYPE *)D.data(), D.step()); |
257 FUNCTION function (exec); | 345 FUNCTION function (exec); |
258 if (result.is_uniform()) { | 346 if (result.is_uniform()) { |
259 // Uniform case | 347 // Uniform case |
260 function (*result, *a, *b, *c, *d); | 348 function (*result, *a, *b, *c, *d); |
261 } else if (A.is_uniform() && B.is_uniform() && C.is_uniform()) { | 349 } else if (A.is_uniform() && B.is_uniform() && C.is_uniform()) { |
262 // Operands are uniform but we're assigning to a varying (it can | 350 // Operands are uniform but we're assigning to a varying (it can |
263 // happen if we're in a conditional). Take a shortcut by doing | 351 // happen if we're in a conditional). Take a shortcut by doing |
264 // the operation only once. | 352 // the operation only once. |
265 RET r; | 353 RET r; |
266 function (r, *a, *b, *c, *d); | 354 function (r, *a, *b, *c, *d); |
267 for (int i = beginpoint; i < endpoint; ++i) | 355 SHADE_LOOP_BEGIN |
268 if (runflags[i]) | 356 result[i] = r; |
269 result[i] = r; | 357 SHADE_LOOP_END |
270 } else { | 358 } else { |
271 // Fully varying case | 359 // Fully varying case |
272 for (int i = beginpoint; i < endpoint; ++i) | 360 SHADE_LOOP_BEGIN |
273 if (runflags[i]) | 361 function (result[i], a[i], b[i], c[i], d[i]); |
274 function (result[i], a[i], b[i], c[i], d[i]); | 362 SHADE_LOOP_END |
275 } | 363 } |
276 | 364 |
277 if (zero_derivs && Result.has_derivs ()) | 365 if (zero_derivs && Result.has_derivs ()) |
278 exec->zero_derivs (Result); | 366 exec->zero_derivs (Result); |
279 } | 367 } |
280 | 368 |
281 | 369 |
282 | 370 |
283 // this is a quaternary function where only the "A" and "B" arguments contribute | 371 // this is a quaternary function where only the "A" and "B" arguments contribute |
284 // to the result's derivatives | 372 // to the result's derivatives |
285 template <typename RET, typename ATYPE, typename BTYPE, | 373 template <typename RET, typename ATYPE, typename BTYPE, |
286 typename CTYPE, typename DTYPE, typename FUNCTION> | 374 typename CTYPE, typename DTYPE, typename FUNCTION> |
287 DECLOP (quaternary_op_binary_derivs) | 375 DECLOP (quaternary_op_binary_derivs) |
288 { | 376 { |
289 // Get references to the symbols this op accesses | 377 // Get references to the symbols this op accesses |
290 Symbol &Result (exec->sym (args[0])); | 378 Symbol &Result (exec->sym (args[0])); |
291 Symbol &A (exec->sym (args[1])); | 379 Symbol &A (exec->sym (args[1])); |
292 Symbol &B (exec->sym (args[2])); | 380 Symbol &B (exec->sym (args[2])); |
293 Symbol &C (exec->sym (args[3])); | 381 Symbol &C (exec->sym (args[3])); |
294 Symbol &D (exec->sym (args[4])); | 382 Symbol &D (exec->sym (args[4])); |
295 | 383 |
296 if (Result.has_derivs()) { | 384 if (Result.has_derivs()) { |
297 if (A.has_derivs()) { | 385 if (A.has_derivs()) { |
298 if (B.has_derivs()) | 386 if (B.has_derivs()) |
299 quaternary_op_guts<Dual2<RET>,Dual2<ATYPE>,Dual2<BTYPE>,CTYPE,DT
YPE,FUNCTION> (Result, A, B, C, D, exec, | 387 quaternary_op_guts<Dual2<RET>,Dual2<ATYPE>,Dual2<BTYPE>,CTYPE,DT
YPE,FUNCTION> (Result, A, B, C, D, exec, false); |
300 runflags, beginpoint, endpoint, false); | |
301 else | 388 else |
302 quaternary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,CTYPE,DTYPE,FUN
CTION> (Result, A, B, C, D, exec, | 389 quaternary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,CTYPE,DTYPE,FUN
CTION> (Result, A, B, C, D, exec, false); |
303 runflags, beginpoint, endpoint, false); | |
304 } else if (B.has_derivs()) { | 390 } else if (B.has_derivs()) { |
305 quaternary_op_guts<Dual2<RET>,ATYPE,Dual2<BTYPE>,CTYPE,DTYPE,FUNCTIO
N> (Result, A, B, C, D, exec, | 391 quaternary_op_guts<Dual2<RET>,ATYPE,Dual2<BTYPE>,CTYPE,DTYPE,FUNCTIO
N> (Result, A, B, C, D, exec, false); |
306 runflags, beginpoint, endpoint, false); | |
307 } else { | 392 } else { |
308 quaternary_op_guts<RET,ATYPE,BTYPE,CTYPE,DTYPE,FUNCTION> (Result, A,
B, C, D, exec, | 393 quaternary_op_guts<RET,ATYPE,BTYPE,CTYPE,DTYPE,FUNCTION> (Result, A,
B, C, D, exec, true); |
309 runflags, beginpoint, endpoint,true); | |
310 } | 394 } |
311 } else { | 395 } else { |
312 quaternary_op_guts<RET,ATYPE,BTYPE,CTYPE,DTYPE,FUNCTION> (Result, A, B,
C, D, exec, | 396 quaternary_op_guts<RET,ATYPE,BTYPE,CTYPE,DTYPE,FUNCTION> (Result, A, B,
C, D, exec, false); |
313 runflags, beginpoint, endpoint, false); | |
314 } | 397 } |
315 } | 398 } |
316 | 399 |
317 | 400 |
318 | 401 |
319 // Heavy lifting of the math and other ternary ops, this is a templated | 402 // Heavy lifting of the math and other ternary ops, this is a templated |
320 // version that knows the types of the arguments and the operation to | 403 // version that knows the types of the arguments and the operation to |
321 // perform (given by a functor). | 404 // perform (given by a functor). |
322 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> | 405 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> |
323 inline void | 406 inline void |
324 ternary_op_guts (Symbol &Result, Symbol &A, Symbol &B, Symbol &C, | 407 ternary_op_guts (Symbol &Result, Symbol &A, Symbol &B, Symbol &C, |
325 ShadingExecution *exec, | 408 ShadingExecution *exec, bool zero_derivs=true) |
326 Runflag *runflags, int beginpoint, int endpoint, | |
327 bool zero_derivs=true) | |
328 { | 409 { |
329 // Adjust the result's uniform/varying status | 410 // Adjust the result's uniform/varying status |
330 exec->adjust_varying (Result, A.is_varying() | B.is_varying() | C.is_varying
(), | 411 exec->adjust_varying (Result, A.is_varying() | B.is_varying() | C.is_varying
(), |
331 A.data() == Result.data() || B.data() == Result.data()
|| C.data() == Result.data()); | 412 A.data() == Result.data() || B.data() == Result.data()
|| C.data() == Result.data()); |
332 | 413 |
333 // Loop over points, do the operation | 414 // Loop over points, do the operation |
334 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 415 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
335 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); | 416 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); |
336 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); | 417 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); |
337 VaryingRef<CTYPE> c ((CTYPE *)C.data(), C.step()); | 418 VaryingRef<CTYPE> c ((CTYPE *)C.data(), C.step()); |
338 FUNCTION function (exec); | 419 FUNCTION function (exec); |
339 if (result.is_uniform()) { | 420 if (result.is_uniform()) { |
340 // Uniform case | 421 // Uniform case |
341 function (*result, *a, *b, *c); | 422 function (*result, *a, *b, *c); |
342 } else if (A.is_uniform() && B.is_uniform() && C.is_uniform()) { | 423 } else if (A.is_uniform() && B.is_uniform() && C.is_uniform()) { |
343 // Operands are uniform but we're assigning to a varying (it can | 424 // Operands are uniform but we're assigning to a varying (it can |
344 // happen if we're in a conditional). Take a shortcut by doing | 425 // happen if we're in a conditional). Take a shortcut by doing |
345 // the operation only once. | 426 // the operation only once. |
346 RET r; | 427 RET r; |
347 function (r, *a, *b, *c); | 428 function (r, *a, *b, *c); |
348 for (int i = beginpoint; i < endpoint; ++i) | 429 SHADE_LOOP_BEGIN |
349 if (runflags[i]) | 430 result[i] = r; |
350 result[i] = r; | 431 SHADE_LOOP_END |
351 } else { | 432 } else { |
352 // Fully varying case | 433 // Fully varying case |
353 for (int i = beginpoint; i < endpoint; ++i) | 434 SHADE_LOOP_BEGIN |
354 if (runflags[i]) | 435 function (result[i], a[i], b[i], c[i]); |
355 function (result[i], a[i], b[i], c[i]); | 436 SHADE_LOOP_END |
356 } | 437 } |
357 if (zero_derivs && Result.has_derivs ()) | 438 if (zero_derivs && Result.has_derivs ()) |
358 exec->zero_derivs (Result); | 439 exec->zero_derivs (Result); |
359 } | 440 } |
360 | 441 |
361 // Wrapper around ternary_op_guts that does has he call signature of an | 442 // Wrapper around ternary_op_guts that does has he call signature of an |
362 // ordinary shadeop. | 443 // ordinary shadeop. |
363 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> | 444 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> |
364 DECLOP (ternary_op_noderivs) | 445 DECLOP (ternary_op_noderivs) |
365 { | 446 { |
366 // Get references to the symbols this op accesses | 447 // Get references to the symbols this op accesses |
367 Symbol &Result (exec->sym (args[0])); | 448 Symbol &Result (exec->sym (args[0])); |
368 Symbol &A (exec->sym (args[1])); | 449 Symbol &A (exec->sym (args[1])); |
369 Symbol &B (exec->sym (args[2])); | 450 Symbol &B (exec->sym (args[2])); |
370 Symbol &C (exec->sym (args[3])); | 451 Symbol &C (exec->sym (args[3])); |
371 | 452 |
372 ternary_op_guts<RET,ATYPE,BTYPE,CTYPE,FUNCTION> (Result, A, B, C, exec, | 453 ternary_op_guts<RET,ATYPE,BTYPE,CTYPE,FUNCTION> (Result, A, B, C, exec); |
373 runflags, beginpoint, endpoint); | |
374 } | 454 } |
375 | 455 |
376 // Wrapper around ternary_op_guts that does has he call signature of an | 456 // Wrapper around ternary_op_guts that does has he call signature of an |
377 // ordinary shadeop, with support for derivatives | 457 // ordinary shadeop, with support for derivatives |
378 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> | 458 template <class RET, class ATYPE, class BTYPE, class CTYPE, class FUNCTION> |
379 DECLOP (ternary_op) | 459 DECLOP (ternary_op) |
380 { | 460 { |
381 // Get references to the symbols this op accesses | 461 // Get references to the symbols this op accesses |
382 Symbol &Result (exec->sym (args[0])); | 462 Symbol &Result (exec->sym (args[0])); |
383 Symbol &A (exec->sym (args[1])); | 463 Symbol &A (exec->sym (args[1])); |
384 Symbol &B (exec->sym (args[2])); | 464 Symbol &B (exec->sym (args[2])); |
385 Symbol &C (exec->sym (args[3])); | 465 Symbol &C (exec->sym (args[3])); |
386 | 466 |
387 if (Result.has_derivs()) { | 467 if (Result.has_derivs()) { |
388 if (A.has_derivs()) { | 468 if (A.has_derivs()) { |
389 if (B.has_derivs()) { | 469 if (B.has_derivs()) { |
390 if (C.has_derivs()) { | 470 if (C.has_derivs()) { |
391 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, Dual2<BTYPE>, Dual2
<CTYPE>, FUNCTION> | 471 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, Dual2<BTYPE>, Dual2
<CTYPE>, FUNCTION> |
392 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 472 (Result, A, B, C, exec, false); |
393 } else { | 473 } else { |
394 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, Dual2<BTYPE>, CTYPE
, FUNCTION> | 474 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, Dual2<BTYPE>, CTYPE
, FUNCTION> |
395 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 475 (Result, A, B, C, exec, false); |
396 } | 476 } |
397 } | 477 } |
398 else { | 478 else { |
399 if (C.has_derivs()) { | 479 if (C.has_derivs()) { |
400 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, BTYPE, Dual2<CTYPE>
, FUNCTION> | 480 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, BTYPE, Dual2<CTYPE>
, FUNCTION> |
401 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 481 (Result, A, B, C, exec, false); |
402 } else { | 482 } else { |
403 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, BTYPE, CTYPE, FUNCT
ION> | 483 ternary_op_guts<Dual2<RET>, Dual2<ATYPE>, BTYPE, CTYPE, FUNCT
ION> |
404 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 484 (Result, A, B, C, exec, false); |
405 } | 485 } |
406 } | 486 } |
407 } | 487 } |
408 else { | 488 else { |
409 if (B.has_derivs()) { | 489 if (B.has_derivs()) { |
410 if (C.has_derivs()) { | 490 if (C.has_derivs()) { |
411 ternary_op_guts<Dual2<RET>, ATYPE, Dual2<BTYPE>, Dual2<CTYPE>
, FUNCTION> | 491 ternary_op_guts<Dual2<RET>, ATYPE, Dual2<BTYPE>, Dual2<CTYPE>
, FUNCTION> |
412 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 492 (Result, A, B, C, exec, false); |
413 } else { | 493 } else { |
414 ternary_op_guts<Dual2<RET>, ATYPE, Dual2<BTYPE>, CTYPE, FUNCT
ION> | 494 ternary_op_guts<Dual2<RET>, ATYPE, Dual2<BTYPE>, CTYPE, FUNCT
ION> |
415 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 495 (Result, A, B, C, exec, false); |
416 } | 496 } |
417 } else { | 497 } else { |
418 if (C.has_derivs()) { | 498 if (C.has_derivs()) { |
419 ternary_op_guts<Dual2<RET>, ATYPE, BTYPE, Dual2<CTYPE>, FUNCT
ION> | 499 ternary_op_guts<Dual2<RET>, ATYPE, BTYPE, Dual2<CTYPE>, FUNCT
ION> |
420 (Result, A, B, C, exec, runflags, beginpoint, endpoint, f
alse); | 500 (Result, A, B, C, exec, false); |
421 } else { | 501 } else { |
422 ternary_op_guts<Dual2<RET>, ATYPE, BTYPE, CTYPE, FUNCTION> | 502 ternary_op_guts<Dual2<RET>, ATYPE, BTYPE, CTYPE, FUNCTION> |
423 (Result, A, B, C, exec, runflags, beginpoint, endpoint, t
rue); | 503 (Result, A, B, C, exec, true); |
424 } | 504 } |
425 } | 505 } |
426 } | 506 } |
427 } | 507 } |
428 else { | 508 else { |
429 ternary_op_guts<RET,ATYPE,BTYPE,CTYPE,FUNCTION> (Result, A, B, C, exec, | 509 ternary_op_guts<RET,ATYPE,BTYPE,CTYPE,FUNCTION> (Result, A, B, C, exec,
false); |
430 runflags, beginpoint, endpoint, fa
lse); | |
431 } | 510 } |
432 } | 511 } |
433 | 512 |
434 | 513 |
435 // Heavy lifting of the math and other binary ops, this is a templated | 514 // Heavy lifting of the math and other binary ops, this is a templated |
436 // version that knows the types of the arguments and the operation to | 515 // version that knows the types of the arguments and the operation to |
437 // perform (given by a functor). This version can compute derivatives as long | 516 // perform (given by a functor). This version can compute derivatives as long |
438 // as FUNCTION has the required Dual2 operator implementations. | 517 // as FUNCTION has the required Dual2 operator implementations. |
439 template <class RET, class ATYPE, class BTYPE, class FUNCTION> | 518 template <class RET, class ATYPE, class BTYPE, class FUNCTION> |
440 inline void | 519 inline void |
441 binary_op_guts (Symbol &Result, Symbol &A, Symbol &B, | 520 binary_op_guts (Symbol &Result, Symbol &A, Symbol &B, |
442 ShadingExecution *exec, | 521 ShadingExecution *exec, bool zero_derivs=true) |
443 Runflag *runflags, int beginpoint, int endpoint, | |
444 bool zero_derivs=true) | |
445 { | 522 { |
446 // Adjust the result's uniform/varying status | 523 // Adjust the result's uniform/varying status |
447 exec->adjust_varying (Result, A.is_varying() | B.is_varying(), | 524 exec->adjust_varying (Result, A.is_varying() | B.is_varying(), |
448 A.data() == Result.data() || B.data() == Result.data()
); | 525 A.data() == Result.data() || B.data() == Result.data()
); |
449 | 526 |
450 // Loop over points, do the operation | 527 // Loop over points, do the operation |
451 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 528 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
452 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); | 529 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); |
453 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); | 530 VaryingRef<BTYPE> b ((BTYPE *)B.data(), B.step()); |
454 FUNCTION function (exec); | 531 FUNCTION function (exec); |
455 if (result.is_uniform()) { | 532 if (result.is_uniform()) { |
456 // Uniform case | 533 // Uniform case |
457 function (*result, *a, *b); | 534 function (*result, *a, *b); |
458 } else if (A.is_uniform() && B.is_uniform()) { | 535 } else if (A.is_uniform() && B.is_uniform()) { |
459 // Operands are uniform but we're assigning to a varying (it can | 536 // Operands are uniform but we're assigning to a varying (it can |
460 // happen if we're in a conditional). Take a shortcut by doing | 537 // happen if we're in a conditional). Take a shortcut by doing |
461 // the operation only once. | 538 // the operation only once. |
462 RET r; | 539 RET r; |
463 function (r, *a, *b); | 540 function (r, *a, *b); |
464 for (int i = beginpoint; i < endpoint; ++i) | 541 SHADE_LOOP_BEGIN |
465 if (runflags[i]) | 542 result[i] = r; |
466 result[i] = r; | 543 SHADE_LOOP_END |
467 } else { | 544 } else { |
468 // Fully varying case | 545 // Fully varying case |
469 for (int i = beginpoint; i < endpoint; ++i) | 546 SHADE_LOOP_BEGIN |
470 if (runflags[i]) | 547 function (result[i], a[i], b[i]); |
471 function (result[i], a[i], b[i]); | 548 SHADE_LOOP_END |
472 } | 549 } |
473 if (zero_derivs && Result.has_derivs ()) | 550 if (zero_derivs && Result.has_derivs ()) |
474 exec->zero_derivs (Result); | 551 exec->zero_derivs (Result); |
475 } | 552 } |
476 | 553 |
477 // Wrapper around binary_op_guts that has the call signature of an ordinary | 554 // Wrapper around binary_op_guts that has the call signature of an ordinary |
478 // shadeop. | 555 // shadeop. |
479 template <class RET, class ATYPE, class BTYPE, class FUNCTION> | 556 template <class RET, class ATYPE, class BTYPE, class FUNCTION> |
480 DECLOP (binary_op_noderivs) | 557 DECLOP (binary_op_noderivs) |
481 { | 558 { |
482 // Get references to the symbols this op accesses | 559 // Get references to the symbols this op accesses |
483 Symbol &Result (exec->sym (args[0])); | 560 Symbol &Result (exec->sym (args[0])); |
484 Symbol &A (exec->sym (args[1])); | 561 Symbol &A (exec->sym (args[1])); |
485 Symbol &B (exec->sym (args[2])); | 562 Symbol &B (exec->sym (args[2])); |
486 | 563 |
487 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, | 564 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec); |
488 runflags, beginpoint, endpoint); | |
489 } | 565 } |
490 | 566 |
491 | 567 |
492 | 568 |
493 // Wrapper around binary_op_guts that does has he call signature of an | 569 // Wrapper around binary_op_guts that does has he call signature of an |
494 // ordinary shadeop, with support for derivatives. | 570 // ordinary shadeop, with support for derivatives. |
495 // TODO: the presence of derivatives is static, but this shadeop checks | 571 // TODO: the presence of derivatives is static, but this shadeop checks |
496 // Symbol::has_derivs() everytime | 572 // Symbol::has_derivs() everytime |
497 template <class RET, class ATYPE, class BTYPE, class FUNCTION> | 573 template <class RET, class ATYPE, class BTYPE, class FUNCTION> |
498 DECLOP (binary_op) | 574 DECLOP (binary_op) |
499 { | 575 { |
500 // Get references to the symbols this op accesses | 576 // Get references to the symbols this op accesses |
501 Symbol &Result (exec->sym (args[0])); | 577 Symbol &Result (exec->sym (args[0])); |
502 Symbol &A (exec->sym (args[1])); | 578 Symbol &A (exec->sym (args[1])); |
503 Symbol &B (exec->sym (args[2])); | 579 Symbol &B (exec->sym (args[2])); |
504 | 580 |
505 if (Result.has_derivs()) { | 581 if (Result.has_derivs()) { |
506 if (A.has_derivs()) { | 582 if (A.has_derivs()) { |
507 if (B.has_derivs()) | 583 if (B.has_derivs()) |
508 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,Dual2<BTYPE>,FUNCTION> (R
esult, A, B, exec, | 584 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,Dual2<BTYPE>,FUNCTION> (R
esult, A, B, exec, false); |
509 runflags, beginpoint, endpoint, false
); | |
510 else | 585 else |
511 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,FUNCTION> (Result,
A, B, exec, | 586 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,FUNCTION> (Result,
A, B, exec, false); |
512 runflags, beginpoint, endpoint, false
); | |
513 } else if (B.has_derivs()) { | 587 } else if (B.has_derivs()) { |
514 binary_op_guts<Dual2<RET>,ATYPE,Dual2<BTYPE>,FUNCTION> (Result, A, B
, exec, | 588 binary_op_guts<Dual2<RET>,ATYPE,Dual2<BTYPE>,FUNCTION> (Result, A, B
, exec, false); |
515 runflags, beginpoint, endpoint, false
); | |
516 } else { | 589 } else { |
517 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, | 590 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, true); |
518 runflags, beginpoint, endpoint,true); | |
519 } | 591 } |
520 } else { | 592 } else { |
521 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, | 593 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, false); |
522 runflags, beginpoint, endpoint
, false); | |
523 } | 594 } |
524 } | 595 } |
525 | 596 |
526 | 597 |
527 | 598 |
528 // this is a binary function where only the "A" argument contributes to the | 599 // this is a binary function where only the "A" argument contributes to the |
529 // result's derivatives | 600 // result's derivatives |
530 template <typename RET, typename ATYPE, typename BTYPE, typename FUNCTION> | 601 template <typename RET, typename ATYPE, typename BTYPE, typename FUNCTION> |
531 DECLOP (binary_op_unary_derivs) | 602 DECLOP (binary_op_unary_derivs) |
532 { | 603 { |
533 // Get references to the symbols this op accesses | 604 // Get references to the symbols this op accesses |
534 Symbol &Result (exec->sym (args[0])); | 605 Symbol &Result (exec->sym (args[0])); |
535 Symbol &A (exec->sym (args[1])); | 606 Symbol &A (exec->sym (args[1])); |
536 Symbol &B (exec->sym (args[2])); | 607 Symbol &B (exec->sym (args[2])); |
537 | 608 |
538 if (Result.has_derivs() && A.has_derivs()) { | 609 if (Result.has_derivs() && A.has_derivs()) { |
539 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,FUNCTION> (Result, A, B, ex
ec, | 610 binary_op_guts<Dual2<RET>,Dual2<ATYPE>,BTYPE,FUNCTION> (Result, A, B, ex
ec, false); |
540 runflags, beginpoint, endpoint, false); | |
541 } else { | 611 } else { |
542 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, | 612 binary_op_guts<RET,ATYPE,BTYPE,FUNCTION> (Result, A, B, exec, true); |
543 runflags, beginpoint, endpoint, true); | |
544 } | 613 } |
545 } | 614 } |
546 | 615 |
547 | 616 |
548 | 617 |
549 // Heavy lifting of the math and other unary ops, this is a templated | 618 // Heavy lifting of the math and other unary ops, this is a templated |
550 // version that knows the types of the arguments and the operation to | 619 // version that knows the types of the arguments and the operation to |
551 // perform (given by a functor). This version is unaware of how to | 620 // perform (given by a functor). This version is unaware of how to |
552 // compute derivatives, so just clears them. | 621 // compute derivatives, so just clears them. |
553 template <class RET, class ATYPE, class FUNCTION> | 622 template <class RET, class ATYPE, class FUNCTION> |
554 inline void | 623 inline void |
555 unary_op_guts_noderivs (Symbol &Result, Symbol &A, | 624 unary_op_guts_noderivs (Symbol &Result, Symbol &A, |
556 ShadingExecution *exec,· | 625 ShadingExecution *exec) |
557 Runflag *runflags, int beginpoint, int endpoint) | |
558 { | 626 { |
559 // Adjust the result's uniform/varying status | 627 // Adjust the result's uniform/varying status |
560 exec->adjust_varying (Result, A.is_varying(), A.data() == Result.data()); | 628 exec->adjust_varying (Result, A.is_varying(), A.data() == Result.data()); |
561 | 629 |
562 // FIXME -- clear derivs for now, make it right later. | 630 // FIXME -- clear derivs for now, make it right later. |
563 if (Result.has_derivs ()) | 631 if (Result.has_derivs ()) |
564 exec->zero_derivs (Result); | 632 exec->zero_derivs (Result); |
565 | 633 |
566 // Loop over points, do the operation | 634 // Loop over points, do the operation |
567 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 635 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
568 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); | 636 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); |
569 FUNCTION function (exec); | 637 FUNCTION function (exec); |
570 if (result.is_uniform()) { | 638 if (result.is_uniform()) { |
571 // Uniform case | 639 // Uniform case |
572 function (*result, *a); | 640 function (*result, *a); |
573 } else if (A.is_uniform()) { | 641 } else if (A.is_uniform()) { |
574 // Operands are uniform but we're assigning to a varying (it can | 642 // Operands are uniform but we're assigning to a varying (it can |
575 // happen if we're in a conditional). Take a shortcut by doing | 643 // happen if we're in a conditional). Take a shortcut by doing |
576 // the operation only once. | 644 // the operation only once. |
577 RET r; | 645 RET r; |
578 function (r, *a); | 646 function (r, *a); |
579 for (int i = beginpoint; i < endpoint; ++i) | 647 SHADE_LOOP_BEGIN |
580 if (runflags[i]) | 648 result[i] = r; |
581 result[i] = r; | 649 SHADE_LOOP_END |
582 } else { | 650 } else { |
583 // Fully varying case | 651 // Fully varying case |
584 for (int i = beginpoint; i < endpoint; ++i) | 652 SHADE_LOOP_BEGIN |
585 if (runflags[i]) | 653 function (result[i], a[i]); |
586 function (result[i], a[i]); | 654 SHADE_LOOP_END |
587 } | 655 } |
588 } | 656 } |
589 | 657 |
590 | 658 |
591 | 659 |
592 // Heavy lifting of the math and other unary ops, this is a templated | 660 // Heavy lifting of the math and other unary ops, this is a templated |
593 // version that knows the types of the arguments and the operation to | 661 // version that knows the types of the arguments and the operation to |
594 // perform (given by a functor). This version computes derivatives. | 662 // perform (given by a functor). This version computes derivatives. |
595 template <class RET, class ATYPE, class FUNCTION> | 663 template <class RET, class ATYPE, class FUNCTION> |
596 inline void | 664 inline void |
597 unary_op_guts (Symbol &Result, Symbol &A, | 665 unary_op_guts (Symbol &Result, Symbol &A, |
598 ShadingExecution *exec,· | 666 ShadingExecution *exec) |
599 Runflag *runflags, int beginpoint, int endpoint) | |
600 { | 667 { |
601 // Adjust the result's uniform/varying status | 668 // Adjust the result's uniform/varying status |
602 exec->adjust_varying (Result, A.is_varying(), A.data() == Result.data()); | 669 exec->adjust_varying (Result, A.is_varying(), A.data() == Result.data()); |
603 | 670 |
604 // Loop over points, do the operation | 671 // Loop over points, do the operation |
605 FUNCTION function (exec); | 672 FUNCTION function (exec); |
606 if (Result.is_uniform()) { | 673 if (Result.is_uniform()) { |
607 // Uniform case | 674 // Uniform case |
608 function (*((RET *)Result.data()), *(ATYPE *)A.data()); | 675 function (*((RET *)Result.data()), *(ATYPE *)A.data()); |
609 if (Result.has_derivs()) | 676 if (Result.has_derivs()) |
610 exec->zero_derivs (Result); | 677 exec->zero_derivs (Result); |
611 } else if (A.is_uniform()) { | 678 } else if (A.is_uniform()) { |
612 // Operands are uniform but we're assigning to a varying (it can | 679 // Operands are uniform but we're assigning to a varying (it can |
613 // happen if we're in a conditional). Take a shortcut by doing | 680 // happen if we're in a conditional). Take a shortcut by doing |
614 // the operation only once. | 681 // the operation only once. |
615 RET r; | 682 RET r; |
616 function (r, *(ATYPE *)A.data()); | 683 function (r, *(ATYPE *)A.data()); |
617 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 684 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
618 for (int i = beginpoint; i < endpoint; ++i) | 685 SHADE_LOOP_BEGIN |
619 if (runflags[i]) | 686 result[i] = r; |
620 result[i] = r; | 687 SHADE_LOOP_END |
621 if (Result.has_derivs()) | 688 if (Result.has_derivs()) |
622 exec->zero_derivs (Result); | 689 exec->zero_derivs (Result); |
623 } else { | 690 } else { |
624 // Fully varying case | 691 // Fully varying case |
625 if (Result.has_derivs() && A.has_derivs()) { | 692 if (Result.has_derivs() && A.has_derivs()) { |
626 VaryingRef<Dual2<RET> > result ((Dual2<RET> *)Result.data(), Result.
step()); | 693 VaryingRef<Dual2<RET> > result ((Dual2<RET> *)Result.data(), Result.
step()); |
627 VaryingRef<Dual2<ATYPE> > a ((Dual2<ATYPE> *)A.data(), A.step()); | 694 VaryingRef<Dual2<ATYPE> > a ((Dual2<ATYPE> *)A.data(), A.step()); |
628 for (int i = beginpoint; i < endpoint; ++i) | 695 SHADE_LOOP_BEGIN |
629 if (runflags[i]) | 696 function (result[i], a[i]); |
630 function (result[i], a[i]); | 697 SHADE_LOOP_END |
631 } else { | 698 } else { |
632 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); | 699 VaryingRef<RET> result ((RET *)Result.data(), Result.step()); |
633 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); | 700 VaryingRef<ATYPE> a ((ATYPE *)A.data(), A.step()); |
634 for (int i = beginpoint; i < endpoint; ++i) | 701 SHADE_LOOP_BEGIN |
635 if (runflags[i]) | 702 function (result[i], a[i]); |
636 function (result[i], a[i]); | 703 SHADE_LOOP_END |
637 if (Result.has_derivs()) | 704 if (Result.has_derivs()) |
638 exec->zero_derivs (Result); | 705 exec->zero_derivs (Result); |
639 } | 706 } |
640 } | 707 } |
641 } | 708 } |
642 | 709 |
643 | 710 |
644 | 711 |
645 // Heavy lifting of the math and other unary ops, this is a templated | 712 // Heavy lifting of the math and other unary ops, this is a templated |
646 // version that knows the types of the arguments and the operation to | 713 // version that knows the types of the arguments and the operation to |
647 // perform (given by a functor). | 714 // perform (given by a functor). |
648 template <class RET, class ATYPE, class FUNCTION> | 715 template <class RET, class ATYPE, class FUNCTION> |
649 DECLOP (unary_op_noderivs) | 716 DECLOP (unary_op_noderivs) |
650 { | 717 { |
651 // Get references to the symbols this op accesses | 718 // Get references to the symbols this op accesses |
652 Symbol &Result (exec->sym (args[0])); | 719 Symbol &Result (exec->sym (args[0])); |
653 Symbol &A (exec->sym (args[1])); | 720 Symbol &A (exec->sym (args[1])); |
654 | 721 |
655 unary_op_guts_noderivs<RET,ATYPE,FUNCTION> (Result, A, exec, | 722 unary_op_guts_noderivs<RET,ATYPE,FUNCTION> (Result, A, exec); |
656 runflags, beginpoint, endpoint); | |
657 } | 723 } |
658 | 724 |
659 | 725 |
660 template <class RET, class ATYPE, class FUNCTION> | 726 template <class RET, class ATYPE, class FUNCTION> |
661 DECLOP (unary_op) | 727 DECLOP (unary_op) |
662 { | 728 { |
663 // Get references to the symbols this op accesses | 729 // Get references to the symbols this op accesses |
664 Symbol &Result (exec->sym (args[0])); | 730 Symbol &Result (exec->sym (args[0])); |
665 Symbol &A (exec->sym (args[1])); | 731 Symbol &A (exec->sym (args[1])); |
666 | 732 |
667 unary_op_guts<RET,ATYPE,FUNCTION> (Result, A, exec, | 733 unary_op_guts<RET,ATYPE,FUNCTION> (Result, A, exec); |
668 runflags, beginpoint, endpoint); | |
669 } | 734 } |
670 | 735 |
671 | 736 |
672 /// Implements the opcode for a specific ClosurePrimitive in the "standard way | 737 /// Implements the opcode for a specific ClosurePrimitive in the "standard way |
673 template <typename Primitive, int NumArgs> inline | 738 template <typename Primitive, int NumArgs> inline |
674 DECLOP (closure_op_guts) | 739 DECLOP (closure_op_guts) |
675 { | 740 { |
676 ASSERT (nargs >= NumArgs); // TODO: switch to DASSERT at some point | 741 ASSERT (nargs >= NumArgs); // TODO: switch to DASSERT at some point |
677 | 742 |
678 Symbol &Result (exec->sym (args[0])); | 743 Symbol &Result (exec->sym (args[0])); |
(...skipping 24 matching lines...) Expand all Loading... |
703 exec->error ("Unknown closure optional argument: \"%s\", <%s> (%s:%d
)", | 768 exec->error ("Unknown closure optional argument: \"%s\", <%s> (%s:%d
)", |
704 name.c_str(), | 769 name.c_str(), |
705 Val.typespec().c_str(), | 770 Val.typespec().c_str(), |
706 exec->op().sourcefile().c_str(), | 771 exec->op().sourcefile().c_str(), |
707 exec->op().sourceline()); | 772 exec->op().sourceline()); |
708 } | 773 } |
709 } | 774 } |
710 | 775 |
711 /* N.B. Closures don't have derivs */ | 776 /* N.B. Closures don't have derivs */ |
712 VaryingRef<ClosureColor *> result ((ClosureColor **)Result.data(), Result.st
ep()); | 777 VaryingRef<ClosureColor *> result ((ClosureColor **)Result.data(), Result.st
ep()); |
713 for (int i = beginpoint; i < endpoint; ++i) { | 778 SHADE_LOOP_BEGIN |
714 if (runflags[i]) { | 779 char* mem = result[i]->allocate_component (sizeof (Primitive)); |
715 char* mem = result[i]->allocate_component (sizeof (Primitive)); | 780 ClosurePrimitive::Sidedness side = ClosurePrimitive::Front; |
716 ClosurePrimitive::Sidedness side = ClosurePrimitive::Front; | 781 if (sidedness) { |
717 if (sidedness) { | 782 if (sidedness[i] == Strings::front) |
718 if (sidedness[i] == Strings::front) | 783 side = ClosurePrimitive::Front; |
719 side = ClosurePrimitive::Front; | 784 else if (sidedness[i] == Strings::back) |
720 else if (sidedness[i] == Strings::back) | 785 side = ClosurePrimitive::Back; |
721 side = ClosurePrimitive::Back; | 786 else if (sidedness[i] == Strings::both) |
722 else if (sidedness[i] == Strings::both) | 787 side = ClosurePrimitive::Both; |
723 side = ClosurePrimitive::Both; | 788 else |
724 else | 789 side = ClosurePrimitive::None; |
725 side = ClosurePrimitive::None; | |
726 } | |
727 ClosurePrimitive *prim = new (mem) Primitive (i, exec, nargs, args,
side); | |
728 for (int l = 0; l < nlabels; ++l) | |
729 prim->set_custom_label(l, labels[l][i]); | |
730 // Label list must be NONE terminated | |
731 prim->set_custom_label(nlabels, Labels::NONE); | |
732 } | 790 } |
733 } | 791 ClosurePrimitive *prim = new (mem) Primitive (i, exec, nargs, args, side
); |
| 792 for (int l = 0; l < nlabels; ++l) |
| 793 prim->set_custom_label(l, labels[l][i]); |
| 794 // Label list must be NONE terminated |
| 795 prim->set_custom_label(nlabels, Labels::NONE); |
| 796 SHADE_LOOP_END |
734 } | 797 } |
735 | 798 |
736 /// Fetch the value of an opcode argument given its index in the arglist | 799 /// Fetch the value of an opcode argument given its index in the arglist |
737 template <typename T> inline | 800 template <typename T> inline |
738 void fetch_value (T &v, int argidx, int idx, ShadingExecution *exec, int nargs,
const int *args) | 801 void fetch_value (T &v, int argidx, int idx, ShadingExecution *exec, int nargs,
const int *args) |
739 { | 802 { |
740 DASSERT (argidx < nargs); | 803 DASSERT (argidx < nargs); |
741 // TODO: typecheck assert? | 804 // TODO: typecheck assert? |
742 Symbol &Sym = exec->sym (args[argidx]); | 805 Symbol &Sym = exec->sym (args[argidx]); |
743 VaryingRef<T> values ((T*) Sym.data(), Sym.step()); | 806 VaryingRef<T> values ((T*) Sym.data(), Sym.step()); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 }; // namespace pvt | 947 }; // namespace pvt |
885 }; // namespace OSL | 948 }; // namespace OSL |
886 | 949 |
887 #ifdef OSL_NAMESPACE | 950 #ifdef OSL_NAMESPACE |
888 }; // end namespace OSL_NAMESPACE | 951 }; // end namespace OSL_NAMESPACE |
889 using namespace OSL_NAMESPACE; | 952 using namespace OSL_NAMESPACE; |
890 #endif | 953 #endif |
891 | 954 |
892 | 955 |
893 #endif /* OSLOPS_H */ | 956 #endif /* OSLOPS_H */ |
OLD | NEW |