1 //
2 //   Copyright 2015 Pixar
3 //
4 //   Licensed under the Apache License, Version 2.0 (the "Apache License")
5 //   with the following modification; you may not use this file except in
6 //   compliance with the Apache License and the following modification to it:
7 //   Section 6. Trademarks. is deleted and replaced with:
8 //
9 //   6. Trademarks. This License does not grant permission to use the trade
10 //      names, trademarks, service marks, or product names of the Licensor
11 //      and its affiliates, except as required to comply with Section 4(c) of
12 //      the License and to reproduce the content of the NOTICE file.
13 //
14 //   You may obtain a copy of the Apache License at
15 //
16 //       http://www.apache.org/licenses/LICENSE-2.0
17 //
18 //   Unless required by applicable law or agreed to in writing, software
19 //   distributed under the Apache License with the above modification is
20 //   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 //   KIND, either express or implied. See the Apache License for the specific
22 //   language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef OPENSUBDIV3_OSD_OMP_EVALUATOR_H
26 #define OPENSUBDIV3_OSD_OMP_EVALUATOR_H
27 
28 #include "../version.h"
29 #include "../osd/bufferDescriptor.h"
30 #include "../osd/types.h"
31 
32 #include <cstddef>
33 
34 namespace OpenSubdiv {
35 namespace OPENSUBDIV_VERSION {
36 
37 namespace Osd {
38 
39 class OmpEvaluator {
40 public:
41     /// ----------------------------------------------------------------------
42     ///
43     ///   Stencil evaluations with StencilTable
44     ///
45     /// ----------------------------------------------------------------------
46 
47     /// \brief Generic static eval stencils function. This function has a same
48     ///        signature as other device kernels have so that it can be called
49     ///        in the same way from OsdMesh template interface.
50     ///
51     /// @param srcBuffer      Input primvar buffer.
52     ///                       must have BindCpuBuffer() method returning a
53     ///                       const float pointer for read
54     ///
55     /// @param srcDesc        vertex buffer descriptor for the input buffer
56     ///
57     /// @param dstBuffer      Output primvar buffer
58     ///                       must have BindCpuBuffer() method returning a
59     ///                       float pointer for write
60     ///
61     /// @param dstDesc        vertex buffer descriptor for the output buffer
62     ///
63     /// @param stencilTable   Far::StencilTable or equivalent
64     ///
65     /// @param instance       not used in the omp kernel
66     ///                       (declared as a typed pointer to prevent
67     ///                        undesirable template resolution)
68     ///
69     /// @param deviceContext  not used in the omp kernel
70     ///
71     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
72     static bool EvalStencils(
73         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
74         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
75         STENCIL_TABLE const *stencilTable,
76         const OmpEvaluator *instance = NULL,
77         void * deviceContext = NULL) {
78 
79         (void)instance;       // unused
80         (void)deviceContext;  // unused
81 
82         if (stencilTable->GetNumStencils() == 0)
83             return false;
84 
85         return EvalStencils(srcBuffer->BindCpuBuffer(), srcDesc,
86                             dstBuffer->BindCpuBuffer(), dstDesc,
87                             &stencilTable->GetSizes()[0],
88                             &stencilTable->GetOffsets()[0],
89                             &stencilTable->GetControlIndices()[0],
90                             &stencilTable->GetWeights()[0],
91                             /*start = */ 0,
92                             /*end   = */ stencilTable->GetNumStencils());
93     }
94 
95     /// \brief Static eval stencils function which takes raw CPU pointers for
96     ///        input and output.
97     ///
98     /// @param src            Input primvar pointer. An offset of srcDesc
99     ///                       will be applied internally (i.e. the pointer
100     ///                       should not include the offset)
101     ///
102     /// @param srcDesc        vertex buffer descriptor for the input buffer
103     ///
104     /// @param dst            Output primvar pointer. An offset of dstDesc
105     ///                       will be applied internally.
106     ///
107     /// @param dstDesc        vertex buffer descriptor for the output buffer
108     ///
109     /// @param sizes          pointer to the sizes buffer of the stencil table
110     ///
111     /// @param offsets        pointer to the offsets buffer of the stencil table
112     ///
113     /// @param indices        pointer to the indices buffer of the stencil table
114     ///
115     /// @param weights        pointer to the weights buffer of the stencil table
116     ///
117     /// @param start          start index of stencil table
118     ///
119     /// @param end            end index of stencil table
120     ///
121     static bool EvalStencils(
122         const float *src, BufferDescriptor const &srcDesc,
123         float *dst,       BufferDescriptor const &dstDesc,
124         const int * sizes,
125         const int * offsets,
126         const int * indices,
127         const float * weights,
128         int start, int end);
129 
130     /// \brief Generic static eval stencils function with derivatives.
131     ///        This function has a same signature as other device kernels
132     ///        have so that it can be called in the same way from OsdMesh
133     ///        template interface.
134     ///
135     /// @param srcBuffer      Input primvar buffer.
136     ///                       must have BindCpuBuffer() method returning a
137     ///                       const float pointer for read
138     ///
139     /// @param srcDesc        vertex buffer descriptor for the input buffer
140     ///
141     /// @param dstBuffer      Output primvar buffer
142     ///                       must have BindCpuBuffer() method returning a
143     ///                       float pointer for write
144     ///
145     /// @param dstDesc        vertex buffer descriptor for the output buffer
146     ///
147     /// @param duBuffer       Output buffer derivative wrt u
148     ///                       must have BindCpuBuffer() method returning a
149     ///                       float pointer for write
150     ///
151     /// @param duDesc         vertex buffer descriptor for the duBuffer
152     ///
153     /// @param dvBuffer       Output buffer derivative wrt v
154     ///                       must have BindCpuBuffer() method returning a
155     ///                       float pointer for write
156     ///
157     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
158     ///
159     /// @param stencilTable   Far::StencilTable or equivalent
160     ///
161     /// @param instance       not used in the omp kernel
162     ///                       (declared as a typed pointer to prevent
163     ///                        undesirable template resolution)
164     ///
165     /// @param deviceContext  not used in the omp kernel
166     ///
167     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
168     static bool EvalStencils(
169         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
170         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
171         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
172         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
173         STENCIL_TABLE const *stencilTable,
174         const OmpEvaluator *instance = NULL,
175         void * deviceContext = NULL) {
176 
177         (void)instance;       // unused
178         (void)deviceContext;  // unused
179 
180         return EvalStencils(srcBuffer->BindCpuBuffer(), srcDesc,
181                             dstBuffer->BindCpuBuffer(), dstDesc,
182                             duBuffer->BindCpuBuffer(),  duDesc,
183                             dvBuffer->BindCpuBuffer(),  dvDesc,
184                             &stencilTable->GetSizes()[0],
185                             &stencilTable->GetOffsets()[0],
186                             &stencilTable->GetControlIndices()[0],
187                             &stencilTable->GetWeights()[0],
188                             &stencilTable->GetDuWeights()[0],
189                             &stencilTable->GetDvWeights()[0],
190                             /*start = */ 0,
191                             /*end   = */ stencilTable->GetNumStencils());
192     }
193 
194     /// \brief Static eval stencils function with derivatives, which takes
195     ///        raw CPU pointers for input and output.
196     ///
197     /// @param src            Input primvar pointer. An offset of srcDesc
198     ///                       will be applied internally (i.e. the pointer
199     ///                       should not include the offset)
200     ///
201     /// @param srcDesc        vertex buffer descriptor for the input buffer
202     ///
203     /// @param dst            Output primvar pointer. An offset of dstDesc
204     ///                       will be applied internally.
205     ///
206     /// @param dstDesc        vertex buffer descriptor for the output buffer
207     ///
208     /// @param du             Output pointer derivative wrt u. An offset of
209     ///                       duDesc will be applied internally.
210     ///
211     /// @param duDesc         vertex buffer descriptor for the duBuffer
212     ///
213     /// @param dv             Output pointer derivative wrt v. An offset of
214     ///                       dvDesc will be applied internally.
215     ///
216     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
217     ///
218     /// @param sizes          pointer to the sizes buffer of the stencil table
219     ///
220     /// @param offsets        pointer to the offsets buffer of the stencil table
221     ///
222     /// @param indices        pointer to the indices buffer of the stencil table
223     ///
224     /// @param weights        pointer to the weights buffer of the stencil table
225     ///
226     /// @param duWeights      pointer to the du-weights buffer of the stencil table
227     ///
228     /// @param dvWeights      pointer to the dv-weights buffer of the stencil table
229     ///
230     /// @param start          start index of stencil table
231     ///
232     /// @param end            end index of stencil table
233     ///
234     static bool EvalStencils(
235         const float *src, BufferDescriptor const &srcDesc,
236         float *dst,       BufferDescriptor const &dstDesc,
237         float *du,        BufferDescriptor const &duDesc,
238         float *dv,        BufferDescriptor const &dvDesc,
239         const int * sizes,
240         const int * offsets,
241         const int * indices,
242         const float * weights,
243         const float * duWeights,
244         const float * dvWeights,
245         int start, int end);
246 
247     /// \brief Generic static eval stencils function with derivatives.
248     ///        This function has a same signature as other device kernels
249     ///        have so that it can be called in the same way from OsdMesh
250     ///        template interface.
251     ///
252     /// @param srcBuffer      Input primvar buffer.
253     ///                       must have BindCpuBuffer() method returning a
254     ///                       const float pointer for read
255     ///
256     /// @param srcDesc        vertex buffer descriptor for the input buffer
257     ///
258     /// @param dstBuffer      Output primvar buffer
259     ///                       must have BindCpuBuffer() method returning a
260     ///                       float pointer for write
261     ///
262     /// @param dstDesc        vertex buffer descriptor for the output buffer
263     ///
264     /// @param duBuffer       Output buffer derivative wrt u
265     ///                       must have BindCpuBuffer() method returning a
266     ///                       float pointer for write
267     ///
268     /// @param duDesc         vertex buffer descriptor for the duBuffer
269     ///
270     /// @param dvBuffer       Output buffer derivative wrt v
271     ///                       must have BindCpuBuffer() method returning a
272     ///                       float pointer for write
273     ///
274     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
275     ///
276     /// @param duuBuffer      Output buffer 2nd derivative wrt u
277     ///                       must have BindCpuBuffer() method returning a
278     ///                       float pointer for write
279     ///
280     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
281     ///
282     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
283     ///                       must have BindCpuBuffer() method returning a
284     ///                       float pointer for write
285     ///
286     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
287     ///
288     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
289     ///                       must have BindCpuBuffer() method returning a
290     ///                       float pointer for write
291     ///
292     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
293     ///
294     /// @param stencilTable   Far::StencilTable or equivalent
295     ///
296     /// @param instance       not used in the omp kernel
297     ///                       (declared as a typed pointer to prevent
298     ///                        undesirable template resolution)
299     ///
300     /// @param deviceContext  not used in the omp kernel
301     ///
302     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
303     static bool EvalStencils(
304         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
305         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
306         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
307         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
308         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
309         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
310         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
311         STENCIL_TABLE const *stencilTable,
312         const OmpEvaluator *instance = NULL,
313         void * deviceContext = NULL) {
314 
315         (void)instance;       // unused
316         (void)deviceContext;  // unused
317 
318         return EvalStencils(srcBuffer->BindCpuBuffer(), srcDesc,
319                             dstBuffer->BindCpuBuffer(), dstDesc,
320                             duBuffer->BindCpuBuffer(),  duDesc,
321                             dvBuffer->BindCpuBuffer(),  dvDesc,
322                             duuBuffer->BindCpuBuffer(), duuDesc,
323                             duvBuffer->BindCpuBuffer(), duvDesc,
324                             dvvBuffer->BindCpuBuffer(), dvvDesc,
325                             &stencilTable->GetSizes()[0],
326                             &stencilTable->GetOffsets()[0],
327                             &stencilTable->GetControlIndices()[0],
328                             &stencilTable->GetWeights()[0],
329                             &stencilTable->GetDuWeights()[0],
330                             &stencilTable->GetDvWeights()[0],
331                             &stencilTable->GetDuuWeights()[0],
332                             &stencilTable->GetDuvWeights()[0],
333                             &stencilTable->GetDvvWeights()[0],
334                             /*start = */ 0,
335                             /*end   = */ stencilTable->GetNumStencils());
336     }
337 
338     /// \brief Static eval stencils function with derivatives, which takes
339     ///        raw CPU pointers for input and output.
340     ///
341     /// @param src            Input primvar pointer. An offset of srcDesc
342     ///                       will be applied internally (i.e. the pointer
343     ///                       should not include the offset)
344     ///
345     /// @param srcDesc        vertex buffer descriptor for the input buffer
346     ///
347     /// @param dst            Output primvar pointer. An offset of dstDesc
348     ///                       will be applied internally.
349     ///
350     /// @param dstDesc        vertex buffer descriptor for the output buffer
351     ///
352     /// @param du             Output pointer derivative wrt u. An offset of
353     ///                       duDesc will be applied internally.
354     ///
355     /// @param duDesc         vertex buffer descriptor for the duBuffer
356     ///
357     /// @param dv             Output pointer derivative wrt v. An offset of
358     ///                       dvDesc will be applied internally.
359     ///
360     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
361     ///
362     /// @param duu            Output pointer 2nd derivative wrt u. An offset of
363     ///                       duuDesc will be applied internally.
364     ///
365     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
366     ///
367     /// @param duv            Output pointer 2nd derivative wrt u and v. An offset of
368     ///                       duvDesc will be applied internally.
369     ///
370     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
371     ///
372     /// @param dvv            Output pointer 2nd derivative wrt v. An offset of
373     ///                       dvvDesc will be applied internally.
374     ///
375     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
376     ///
377     /// @param sizes          pointer to the sizes buffer of the stencil table
378     ///
379     /// @param offsets        pointer to the offsets buffer of the stencil table
380     ///
381     /// @param indices        pointer to the indices buffer of the stencil table
382     ///
383     /// @param weights        pointer to the weights buffer of the stencil table
384     ///
385     /// @param duWeights      pointer to the du-weights buffer of the stencil table
386     ///
387     /// @param dvWeights      pointer to the dv-weights buffer of the stencil table
388     ///
389     /// @param duuWeights     pointer to the duu-weights buffer of the stencil table
390     ///
391     /// @param duvWeights     pointer to the duv-weights buffer of the stencil table
392     ///
393     /// @param dvvWeights     pointer to the dvv-weights buffer of the stencil table
394     ///
395     /// @param start          start index of stencil table
396     ///
397     /// @param end            end index of stencil table
398     ///
399     static bool EvalStencils(
400         const float *src, BufferDescriptor const &srcDesc,
401         float *dst,       BufferDescriptor const &dstDesc,
402         float *du,        BufferDescriptor const &duDesc,
403         float *dv,        BufferDescriptor const &dvDesc,
404         float *duu,       BufferDescriptor const &duuDesc,
405         float *duv,       BufferDescriptor const &duvDesc,
406         float *dvv,       BufferDescriptor const &dvvDesc,
407         const int * sizes,
408         const int * offsets,
409         const int * indices,
410         const float * weights,
411         const float * duWeights,
412         const float * dvWeights,
413         const float * duuWeights,
414         const float * duvWeights,
415         const float * dvvWeights,
416         int start, int end);
417 
418     /// ----------------------------------------------------------------------
419     ///
420     ///   Limit evaluations with PatchTable
421     ///
422     /// ----------------------------------------------------------------------
423 
424     /// \brief Generic limit eval function. This function has a same
425     ///        signature as other device kernels have so that it can be called
426     ///        in the same way.
427     ///
428     /// @param srcBuffer        Input primvar buffer.
429     ///                         must have BindCpuBuffer() method returning a
430     ///                         const float pointer for read
431     ///
432     /// @param srcDesc          vertex buffer descriptor for the input buffer
433     ///
434     /// @param dstBuffer        Output primvar buffer
435     ///                         must have BindCpuBuffer() method returning a
436     ///                         float pointer for write
437     ///
438     /// @param dstDesc          vertex buffer descriptor for the output buffer
439     ///
440     /// @param numPatchCoords   number of patchCoords.
441     ///
442     /// @param patchCoords      array of locations to be evaluated.
443     ///
444     /// @param patchTable       CpuPatchTable or equivalent
445     ///                         XXX: currently Far::PatchTable can't be used
446     ///                              due to interface mismatch
447     ///
448     /// @param instance         not used in the omp evaluator
449     ///
450     /// @param deviceContext    not used in the omp evaluator
451     ///
452     template <typename SRC_BUFFER, typename DST_BUFFER,
453               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
454     static bool EvalPatches(
455         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
456         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
457         int numPatchCoords,
458         PATCHCOORD_BUFFER *patchCoords,
459         PATCH_TABLE *patchTable,
460         OmpEvaluator const *instance = NULL,
461         void * deviceContext = NULL) {
462 
463         (void)instance;       // unused
464         (void)deviceContext;  // unused
465 
466         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
467                            dstBuffer->BindCpuBuffer(), dstDesc,
468                            numPatchCoords,
469                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
470                            patchTable->GetPatchArrayBuffer(),
471                            patchTable->GetPatchIndexBuffer(),
472                            patchTable->GetPatchParamBuffer());
473     }
474 
475     /// \brief Generic limit eval function with derivatives. This function has
476     ///        a same signature as other device kernels have so that it can be
477     ///        called in the same way.
478     ///
479     /// @param srcBuffer        Input primvar buffer.
480     ///                         must have BindCpuBuffer() method returning a
481     ///                         const float pointer for read
482     ///
483     /// @param srcDesc          vertex buffer descriptor for the input buffer
484     ///
485     /// @param dstBuffer        Output primvar buffer
486     ///                         must have BindCpuBuffer() method returning a
487     ///                         float pointer for write
488     ///
489     /// @param dstDesc          vertex buffer descriptor for the output buffer
490     ///
491     /// @param duBuffer         Output buffer derivative wrt u
492     ///                         must have BindCpuBuffer() method returning a
493     ///                         float pointer for write
494     ///
495     /// @param duDesc           vertex buffer descriptor for the duBuffer
496     ///
497     /// @param dvBuffer         Output buffer derivative wrt v
498     ///                         must have BindCpuBuffer() method returning a
499     ///                         float pointer for write
500     ///
501     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
502     ///
503     /// @param numPatchCoords   number of patchCoords.
504     ///
505     /// @param patchCoords      array of locations to be evaluated.
506     ///
507     /// @param patchTable       CpuPatchTable or equivalent
508     ///                         XXX: currently Far::PatchTable can't be used
509     ///                              due to interface mismatch
510     ///
511     /// @param instance         not used in the omp evaluator
512     ///
513     /// @param deviceContext    not used in the omp evaluator
514     ///
515     template <typename SRC_BUFFER, typename DST_BUFFER,
516               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
517     static bool EvalPatches(
518         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
519         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
520         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
521         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
522         int numPatchCoords,
523         PATCHCOORD_BUFFER *patchCoords,
524         PATCH_TABLE *patchTable,
525         OmpEvaluator const *instance = NULL,
526         void * deviceContext = NULL) {
527 
528         (void)instance;       // unused
529         (void)deviceContext;  // unused
530 
531         // XXX: PatchCoords is somewhat abusing vertex primvar buffer interop.
532         //      ideally all buffer classes should have templated by datatype
533         //      so that downcast isn't needed there.
534         //      (e.g. Osd::CpuBuffer<PatchCoord> )
535         //
536         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
537                            dstBuffer->BindCpuBuffer(), dstDesc,
538                            duBuffer->BindCpuBuffer(),  duDesc,
539                            dvBuffer->BindCpuBuffer(),  dvDesc,
540                            numPatchCoords,
541                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
542                            patchTable->GetPatchArrayBuffer(),
543                            patchTable->GetPatchIndexBuffer(),
544                            patchTable->GetPatchParamBuffer());
545     }
546 
547     /// \brief Generic limit eval function with derivatives. This function has
548     ///        a same signature as other device kernels have so that it can be
549     ///        called in the same way.
550     ///
551     /// @param srcBuffer        Input primvar buffer.
552     ///                         must have BindCpuBuffer() method returning a
553     ///                         const float pointer for read
554     ///
555     /// @param srcDesc          vertex buffer descriptor for the input buffer
556     ///
557     /// @param dstBuffer        Output primvar buffer
558     ///                         must have BindCpuBuffer() method returning a
559     ///                         float pointer for write
560     ///
561     /// @param dstDesc          vertex buffer descriptor for the output buffer
562     ///
563     /// @param duBuffer         Output buffer derivative wrt u
564     ///                         must have BindCpuBuffer() method returning a
565     ///                         float pointer for write
566     ///
567     /// @param duDesc           vertex buffer descriptor for the duBuffer
568     ///
569     /// @param dvBuffer         Output buffer derivative wrt v
570     ///                         must have BindCpuBuffer() method returning a
571     ///                         float pointer for write
572     ///
573     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
574     ///
575     /// @param duuBuffer        Output buffer 2nd derivative wrt u
576     ///                         must have BindCpuBuffer() method returning a
577     ///                         float pointer for write
578     ///
579     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
580     ///
581     /// @param duvBuffer        Output buffer 2nd derivative wrt u and v
582     ///                         must have BindCpuBuffer() method returning a
583     ///                         float pointer for write
584     ///
585     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
586     ///
587     /// @param dvvBuffer        Output buffer 2nd derivative wrt v
588     ///                         must have BindCpuBuffer() method returning a
589     ///                         float pointer for write
590     ///
591     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
592     ///
593     /// @param numPatchCoords   number of patchCoords.
594     ///
595     /// @param patchCoords      array of locations to be evaluated.
596     ///
597     /// @param patchTable       CpuPatchTable or equivalent
598     ///                         XXX: currently Far::PatchTable can't be used
599     ///                              due to interface mismatch
600     ///
601     /// @param instance         not used in the omp evaluator
602     ///
603     /// @param deviceContext    not used in the omp evaluator
604     ///
605     template <typename SRC_BUFFER, typename DST_BUFFER,
606               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
607     static bool EvalPatches(
608         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
609         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
610         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
611         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
612         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
613         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
614         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
615         int numPatchCoords,
616         PATCHCOORD_BUFFER *patchCoords,
617         PATCH_TABLE *patchTable,
618         OmpEvaluator const *instance = NULL,
619         void * deviceContext = NULL) {
620 
621         (void)instance;       // unused
622         (void)deviceContext;  // unused
623 
624         // XXX: PatchCoords is somewhat abusing vertex primvar buffer interop.
625         //      ideally all buffer classes should have templated by datatype
626         //      so that downcast isn't needed there.
627         //      (e.g. Osd::CpuBuffer<PatchCoord> )
628         //
629         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
630                            dstBuffer->BindCpuBuffer(), dstDesc,
631                            duBuffer->BindCpuBuffer(),  duDesc,
632                            dvBuffer->BindCpuBuffer(),  dvDesc,
633                            duuBuffer->BindCpuBuffer(), duuDesc,
634                            duvBuffer->BindCpuBuffer(), duvDesc,
635                            dvvBuffer->BindCpuBuffer(), dvvDesc,
636                            numPatchCoords,
637                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
638                            patchTable->GetPatchArrayBuffer(),
639                            patchTable->GetPatchIndexBuffer(),
640                            patchTable->GetPatchParamBuffer());
641     }
642 
643     /// \brief Static limit eval function. It takes an array of PatchCoord
644     ///        and evaluate limit values on given PatchTable.
645     ///
646     /// @param src              Input primvar pointer. An offset of srcDesc
647     ///                         will be applied internally (i.e. the pointer
648     ///                         should not include the offset)
649     ///
650     /// @param srcDesc          vertex buffer descriptor for the input buffer
651     ///
652     /// @param dst              Output primvar pointer. An offset of dstDesc
653     ///                         will be applied internally.
654     ///
655     /// @param dstDesc          vertex buffer descriptor for the output buffer
656     ///
657     /// @param numPatchCoords   number of patchCoords.
658     ///
659     /// @param patchCoords      array of locations to be evaluated.
660     ///
661     /// @param patchArrays      an array of Osd::PatchArray struct
662     ///                         indexed by PatchCoord::arrayIndex
663     ///
664     /// @param patchIndexBuffer an array of patch indices
665     ///                         indexed by PatchCoord::vertIndex
666     ///
667     /// @param patchParamBuffer an array of Osd::PatchParam struct
668     ///                         indexed by PatchCoord::patchIndex
669     ///
670     static bool EvalPatches(
671         const float *src, BufferDescriptor const &srcDesc,
672         float *dst,       BufferDescriptor const &dstDesc,
673         int numPatchCoords,
674         const PatchCoord *patchCoords,
675         const PatchArray *patchArrays,
676         const int *patchIndexBuffer,
677         const PatchParam *patchParamBuffer);
678 
679     /// \brief Static limit eval function. It takes an array of PatchCoord
680     ///        and evaluate limit values on given PatchTable.
681     ///
682     /// @param src              Input primvar pointer. An offset of srcDesc
683     ///                         will be applied internally (i.e. the pointer
684     ///                         should not include the offset)
685     ///
686     /// @param srcDesc          vertex buffer descriptor for the input buffer
687     ///
688     /// @param dst              Output primvar pointer. An offset of dstDesc
689     ///                         will be applied internally.
690     ///
691     /// @param dstDesc          vertex buffer descriptor for the output buffer
692     ///
693     /// @param du               Output pointer derivative wrt u. An offset of
694     ///                         duDesc will be applied internally.
695     ///
696     /// @param duDesc           vertex buffer descriptor for the duBuffer
697     ///
698     /// @param dv               Output pointer derivative wrt v. An offset of
699     ///                         dvDesc will be applied internally.
700     ///
701     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
702     ///
703     /// @param numPatchCoords   number of patchCoords.
704     ///
705     /// @param patchCoords      array of locations to be evaluated.
706     ///
707     /// @param patchArrays      an array of Osd::PatchArray struct
708     ///                         indexed by PatchCoord::arrayIndex
709     ///
710     /// @param patchIndexBuffer an array of patch indices
711     ///                         indexed by PatchCoord::vertIndex
712     ///
713     /// @param patchParamBuffer an array of Osd::PatchParam struct
714     ///                         indexed by PatchCoord::patchIndex
715     ///
716     static bool EvalPatches(
717         const float *src, BufferDescriptor const &srcDesc,
718         float *dst,       BufferDescriptor const &dstDesc,
719         float *du,        BufferDescriptor const &duDesc,
720         float *dv,        BufferDescriptor const &dvDesc,
721         int numPatchCoords,
722         PatchCoord const *patchCoords,
723         PatchArray const *patchArrays,
724         const int *patchIndexBuffer,
725         PatchParam const *patchParamBuffer);
726 
727     /// \brief Static limit eval function. It takes an array of PatchCoord
728     ///        and evaluate limit values on given PatchTable.
729     ///
730     /// @param src              Input primvar pointer. An offset of srcDesc
731     ///                         will be applied internally (i.e. the pointer
732     ///                         should not include the offset)
733     ///
734     /// @param srcDesc          vertex buffer descriptor for the input buffer
735     ///
736     /// @param dst              Output primvar pointer. An offset of dstDesc
737     ///                         will be applied internally.
738     ///
739     /// @param dstDesc          vertex buffer descriptor for the output buffer
740     ///
741     /// @param du               Output pointer derivative wrt u. An offset of
742     ///                         duDesc will be applied internally.
743     ///
744     /// @param duDesc           vertex buffer descriptor for the duBuffer
745     ///
746     /// @param dv               Output pointer derivative wrt v. An offset of
747     ///                         dvDesc will be applied internally.
748     ///
749     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
750     ///
751     /// @param duu              Output pointer 2nd derivative wrt u. An offset of
752     ///                         duuDesc will be applied internally.
753     ///
754     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
755     ///
756     /// @param duv              Output pointer 2nd derivative wrt u and v. An offset of
757     ///                         duvDesc will be applied internally.
758     ///
759     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
760     ///
761     /// @param dvv              Output pointer 2nd derivative wrt v. An offset of
762     ///                         dvvDesc will be applied internally.
763     ///
764     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
765     ///
766     /// @param numPatchCoords   number of patchCoords.
767     ///
768     /// @param patchCoords      array of locations to be evaluated.
769     ///
770     /// @param patchArrays      an array of Osd::PatchArray struct
771     ///                         indexed by PatchCoord::arrayIndex
772     ///
773     /// @param patchIndexBuffer an array of patch indices
774     ///                         indexed by PatchCoord::vertIndex
775     ///
776     /// @param patchParamBuffer an array of Osd::PatchParam struct
777     ///                         indexed by PatchCoord::patchIndex
778     ///
779     static bool EvalPatches(
780         const float *src, BufferDescriptor const &srcDesc,
781         float *dst,       BufferDescriptor const &dstDesc,
782         float *du,        BufferDescriptor const &duDesc,
783         float *dv,        BufferDescriptor const &dvDesc,
784         float *duu,       BufferDescriptor const &duuDesc,
785         float *duv,       BufferDescriptor const &duvDesc,
786         float *dvv,       BufferDescriptor const &dvvDesc,
787         int numPatchCoords,
788         PatchCoord const *patchCoords,
789         PatchArray const *patchArrays,
790         const int *patchIndexBuffer,
791         PatchParam const *patchParamBuffer);
792 
793     /// \brief Generic limit eval function. This function has a same
794     ///        signature as other device kernels have so that it can be called
795     ///        in the same way.
796     ///
797     /// @param srcBuffer        Input primvar buffer.
798     ///                         must have BindCpuBuffer() method returning a
799     ///                         const float pointer for read
800     ///
801     /// @param srcDesc          vertex buffer descriptor for the input buffer
802     ///
803     /// @param dstBuffer        Output primvar buffer
804     ///                         must have BindCpuBuffer() method returning a
805     ///                         float pointer for write
806     ///
807     /// @param dstDesc          vertex buffer descriptor for the output buffer
808     ///
809     /// @param numPatchCoords   number of patchCoords.
810     ///
811     /// @param patchCoords      array of locations to be evaluated.
812     ///
813     /// @param patchTable       CpuPatchTable or equivalent
814     ///                         XXX: currently Far::PatchTable can't be used
815     ///                              due to interface mismatch
816     ///
817     /// @param instance         not used in the omp evaluator
818     ///
819     /// @param deviceContext    not used in the omp evaluator
820     ///
821     template <typename SRC_BUFFER, typename DST_BUFFER,
822               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
823     static bool EvalPatchesVarying(
824         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
825         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
826         int numPatchCoords,
827         PATCHCOORD_BUFFER *patchCoords,
828         PATCH_TABLE *patchTable,
829         OmpEvaluator const *instance = NULL,
830         void * deviceContext = NULL) {
831 
832         (void)instance;       // unused
833         (void)deviceContext;  // unused
834 
835         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
836                            dstBuffer->BindCpuBuffer(), dstDesc,
837                            numPatchCoords,
838                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
839                            patchTable->GetVaryingPatchArrayBuffer(),
840                            patchTable->GetVaryingPatchIndexBuffer(),
841                            patchTable->GetPatchParamBuffer());
842     }
843 
844     /// \brief Generic limit eval function. This function has a same
845     ///        signature as other device kernels have so that it can be called
846     ///        in the same way.
847     ///
848     /// @param srcBuffer        Input primvar buffer.
849     ///                         must have BindCpuBuffer() method returning a
850     ///                         const float pointer for read
851     ///
852     /// @param srcDesc          vertex buffer descriptor for the input buffer
853     ///
854     /// @param dstBuffer        Output primvar buffer
855     ///                         must have BindCpuBuffer() method returning a
856     ///                         float pointer for write
857     ///
858     /// @param dstDesc          vertex buffer descriptor for the output buffer
859     ///
860     /// @param duBuffer         Output buffer derivative wrt u
861     ///                         must have BindCpuBuffer() method returning a
862     ///                         float pointer for write
863     ///
864     /// @param duDesc           vertex buffer descriptor for the duBuffer
865     ///
866     /// @param dvBuffer         Output buffer derivative wrt v
867     ///                         must have BindCpuBuffer() method returning a
868     ///                         float pointer for write
869     ///
870     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
871     ///
872     /// @param numPatchCoords   number of patchCoords.
873     ///
874     /// @param patchCoords      array of locations to be evaluated.
875     ///
876     /// @param patchTable       CpuPatchTable or equivalent
877     ///                         XXX: currently Far::PatchTable can't be used
878     ///                              due to interface mismatch
879     ///
880     /// @param instance         not used in the omp evaluator
881     ///
882     /// @param deviceContext    not used in the omp evaluator
883     ///
884     template <typename SRC_BUFFER, typename DST_BUFFER,
885               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
886     static bool EvalPatchesVarying(
887         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
888         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
889         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
890         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
891         int numPatchCoords,
892         PATCHCOORD_BUFFER *patchCoords,
893         PATCH_TABLE *patchTable,
894         OmpEvaluator const *instance = NULL,
895         void * deviceContext = NULL) {
896 
897         (void)instance;       // unused
898         (void)deviceContext;  // unused
899 
900         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
901                            dstBuffer->BindCpuBuffer(), dstDesc,
902                            duBuffer->BindCpuBuffer(),  duDesc,
903                            dvBuffer->BindCpuBuffer(),  dvDesc,
904                            numPatchCoords,
905                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
906                            patchTable->GetVaryingPatchArrayBuffer(),
907                            patchTable->GetVaryingPatchIndexBuffer(),
908                            patchTable->GetPatchParamBuffer());
909     }
910 
911     /// \brief Generic limit eval function. This function has a same
912     ///        signature as other device kernels have so that it can be called
913     ///        in the same way.
914     ///
915     /// @param srcBuffer        Input primvar buffer.
916     ///                         must have BindCpuBuffer() method returning a
917     ///                         const float pointer for read
918     ///
919     /// @param srcDesc          vertex buffer descriptor for the input buffer
920     ///
921     /// @param dstBuffer        Output primvar buffer
922     ///                         must have BindCpuBuffer() method returning a
923     ///                         float pointer for write
924     ///
925     /// @param dstDesc          vertex buffer descriptor for the output buffer
926     ///
927     /// @param duBuffer         Output buffer derivative wrt u
928     ///                         must have BindCpuBuffer() method returning a
929     ///                         float pointer for write
930     ///
931     /// @param duDesc           vertex buffer descriptor for the duBuffer
932     ///
933     /// @param dvBuffer         Output buffer derivative wrt v
934     ///                         must have BindCpuBuffer() method returning a
935     ///                         float pointer for write
936     ///
937     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
938     ///
939     /// @param duuBuffer        Output buffer 2nd derivative wrt u
940     ///                         must have BindCpuBuffer() method returning a
941     ///                         float pointer for write
942     ///
943     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
944     ///
945     /// @param duvBuffer        Output buffer 2nd derivative wrt u and v
946     ///                         must have BindCpuBuffer() method returning a
947     ///                         float pointer for write
948     ///
949     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
950     ///
951     /// @param dvvBuffer        Output buffer 2nd derivative wrt v
952     ///                         must have BindCpuBuffer() method returning a
953     ///                         float pointer for write
954     ///
955     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
956     ///
957     /// @param numPatchCoords   number of patchCoords.
958     ///
959     /// @param patchCoords      array of locations to be evaluated.
960     ///
961     /// @param patchTable       CpuPatchTable or equivalent
962     ///                         XXX: currently Far::PatchTable can't be used
963     ///                              due to interface mismatch
964     ///
965     /// @param instance         not used in the omp evaluator
966     ///
967     /// @param deviceContext    not used in the omp evaluator
968     ///
969     template <typename SRC_BUFFER, typename DST_BUFFER,
970               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
971     static bool EvalPatchesVarying(
972         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
973         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
974         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
975         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
976         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
977         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
978         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
979         int numPatchCoords,
980         PATCHCOORD_BUFFER *patchCoords,
981         PATCH_TABLE *patchTable,
982         OmpEvaluator const *instance = NULL,
983         void * deviceContext = NULL) {
984 
985         (void)instance;       // unused
986         (void)deviceContext;  // unused
987 
988         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
989                            dstBuffer->BindCpuBuffer(), dstDesc,
990                            duBuffer->BindCpuBuffer(),  duDesc,
991                            dvBuffer->BindCpuBuffer(),  dvDesc,
992                            duuBuffer->BindCpuBuffer(), duuDesc,
993                            duvBuffer->BindCpuBuffer(), duvDesc,
994                            dvvBuffer->BindCpuBuffer(), dvvDesc,
995                            numPatchCoords,
996                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
997                            patchTable->GetVaryingPatchArrayBuffer(),
998                            patchTable->GetVaryingPatchIndexBuffer(),
999                            patchTable->GetPatchParamBuffer());
1000     }
1001 
1002     /// \brief Generic limit eval function. This function has a same
1003     ///        signature as other device kernels have so that it can be called
1004     ///        in the same way.
1005     ///
1006     /// @param srcBuffer        Input primvar buffer.
1007     ///                         must have BindCpuBuffer() method returning a
1008     ///                         const float pointer for read
1009     ///
1010     /// @param srcDesc          vertex buffer descriptor for the input buffer
1011     ///
1012     /// @param dstBuffer        Output primvar buffer
1013     ///                         must have BindCpuBuffer() method returning a
1014     ///                         float pointer for write
1015     ///
1016     /// @param dstDesc          vertex buffer descriptor for the output buffer
1017     ///
1018     /// @param numPatchCoords   number of patchCoords.
1019     ///
1020     /// @param patchCoords      array of locations to be evaluated.
1021     ///
1022     /// @param patchTable       CpuPatchTable or equivalent
1023     ///                         XXX: currently Far::PatchTable can't be used
1024     ///                              due to interface mismatch
1025     ///
1026     /// @param fvarChannel      face-varying channel
1027     ///
1028     /// @param instance         not used in the omp evaluator
1029     ///
1030     /// @param deviceContext    not used in the omp evaluator
1031     ///
1032     template <typename SRC_BUFFER, typename DST_BUFFER,
1033               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1034     static bool EvalPatchesFaceVarying(
1035         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1036         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1037         int numPatchCoords,
1038         PATCHCOORD_BUFFER *patchCoords,
1039         PATCH_TABLE *patchTable,
1040         int fvarChannel,
1041         OmpEvaluator const *instance = NULL,
1042         void * deviceContext = NULL) {
1043 
1044         (void)instance;       // unused
1045         (void)deviceContext;  // unused
1046 
1047         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
1048                            dstBuffer->BindCpuBuffer(), dstDesc,
1049                            numPatchCoords,
1050                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
1051                            patchTable->GetFVarPatchArrayBuffer(fvarChannel),
1052                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1053                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
1054     }
1055 
1056     /// \brief Generic limit eval function. This function has a same
1057     ///        signature as other device kernels have so that it can be called
1058     ///        in the same way.
1059     ///
1060     /// @param srcBuffer        Input primvar buffer.
1061     ///                         must have BindCpuBuffer() method returning a
1062     ///                         const float pointer for read
1063     ///
1064     /// @param srcDesc          vertex buffer descriptor for the input buffer
1065     ///
1066     /// @param dstBuffer        Output primvar buffer
1067     ///                         must have BindCpuBuffer() method returning a
1068     ///                         float pointer for write
1069     ///
1070     /// @param dstDesc          vertex buffer descriptor for the output buffer
1071     ///
1072     /// @param duBuffer         Output buffer derivative wrt u
1073     ///                         must have BindCpuBuffer() method returning a
1074     ///                         float pointer for write
1075     ///
1076     /// @param duDesc           vertex buffer descriptor for the duBuffer
1077     ///
1078     /// @param dvBuffer         Output buffer derivative wrt v
1079     ///                         must have BindCpuBuffer() method returning a
1080     ///                         float pointer for write
1081     ///
1082     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
1083     ///
1084     /// @param numPatchCoords   number of patchCoords.
1085     ///
1086     /// @param patchCoords      array of locations to be evaluated.
1087     ///
1088     /// @param patchTable       CpuPatchTable or equivalent
1089     ///                         XXX: currently Far::PatchTable can't be used
1090     ///                              due to interface mismatch
1091     ///
1092     /// @param fvarChannel      face-varying channel
1093     ///
1094     /// @param instance         not used in the omp evaluator
1095     ///
1096     /// @param deviceContext    not used in the omp evaluator
1097     ///
1098     template <typename SRC_BUFFER, typename DST_BUFFER,
1099               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1100     static bool EvalPatchesFaceVarying(
1101         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1102         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1103         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1104         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1105         int numPatchCoords,
1106         PATCHCOORD_BUFFER *patchCoords,
1107         PATCH_TABLE *patchTable,
1108         int fvarChannel,
1109         OmpEvaluator const *instance = NULL,
1110         void * deviceContext = NULL) {
1111 
1112         (void)instance;       // unused
1113         (void)deviceContext;  // unused
1114 
1115         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
1116                            dstBuffer->BindCpuBuffer(), dstDesc,
1117                            duBuffer->BindCpuBuffer(),  duDesc,
1118                            dvBuffer->BindCpuBuffer(),  dvDesc,
1119                            numPatchCoords,
1120                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
1121                            patchTable->GetFVarPatchArrayBuffer(fvarChannel),
1122                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1123                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
1124     }
1125 
1126     /// \brief Generic limit eval function. This function has a same
1127     ///        signature as other device kernels have so that it can be called
1128     ///        in the same way.
1129     ///
1130     /// @param srcBuffer        Input primvar buffer.
1131     ///                         must have BindCpuBuffer() method returning a
1132     ///                         const float pointer for read
1133     ///
1134     /// @param srcDesc          vertex buffer descriptor for the input buffer
1135     ///
1136     /// @param dstBuffer        Output primvar buffer
1137     ///                         must have BindCpuBuffer() method returning a
1138     ///                         float pointer for write
1139     ///
1140     /// @param dstDesc          vertex buffer descriptor for the output buffer
1141     ///
1142     /// @param duBuffer         Output buffer derivative wrt u
1143     ///                         must have BindCpuBuffer() method returning a
1144     ///                         float pointer for write
1145     ///
1146     /// @param duDesc           vertex buffer descriptor for the duBuffer
1147     ///
1148     /// @param dvBuffer         Output buffer derivative wrt v
1149     ///                         must have BindCpuBuffer() method returning a
1150     ///                         float pointer for write
1151     ///
1152     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
1153     ///
1154     /// @param duuBuffer        Output buffer 2nd derivative wrt u
1155     ///                         must have BindCpuBuffer() method returning a
1156     ///                         float pointer for write
1157     ///
1158     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
1159     ///
1160     /// @param duvBuffer        Output buffer 2nd derivative wrt u and v
1161     ///                         must have BindCpuBuffer() method returning a
1162     ///                         float pointer for write
1163     ///
1164     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
1165     ///
1166     /// @param dvvBuffer        Output buffer 2nd derivative wrt v
1167     ///                         must have BindCpuBuffer() method returning a
1168     ///                         float pointer for write
1169     ///
1170     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
1171     ///
1172     /// @param numPatchCoords   number of patchCoords.
1173     ///
1174     /// @param patchCoords      array of locations to be evaluated.
1175     ///
1176     /// @param patchTable       CpuPatchTable or equivalent
1177     ///                         XXX: currently Far::PatchTable can't be used
1178     ///                              due to interface mismatch
1179     ///
1180     /// @param fvarChannel      face-varying channel
1181     ///
1182     /// @param instance         not used in the omp evaluator
1183     ///
1184     /// @param deviceContext    not used in the omp evaluator
1185     ///
1186     template <typename SRC_BUFFER, typename DST_BUFFER,
1187               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1188     static bool EvalPatchesFaceVarying(
1189         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1190         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1191         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1192         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1193         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
1194         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
1195         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
1196         int numPatchCoords,
1197         PATCHCOORD_BUFFER *patchCoords,
1198         PATCH_TABLE *patchTable,
1199         int fvarChannel,
1200         OmpEvaluator const *instance = NULL,
1201         void * deviceContext = NULL) {
1202 
1203         (void)instance;       // unused
1204         (void)deviceContext;  // unused
1205 
1206         return EvalPatches(srcBuffer->BindCpuBuffer(), srcDesc,
1207                            dstBuffer->BindCpuBuffer(), dstDesc,
1208                            duBuffer->BindCpuBuffer(),  duDesc,
1209                            dvBuffer->BindCpuBuffer(),  dvDesc,
1210                            duuBuffer->BindCpuBuffer(), duuDesc,
1211                            duvBuffer->BindCpuBuffer(), duvDesc,
1212                            dvvBuffer->BindCpuBuffer(), dvvDesc,
1213                            numPatchCoords,
1214                            (const PatchCoord*)patchCoords->BindCpuBuffer(),
1215                            patchTable->GetFVarPatchArrayBuffer(fvarChannel),
1216                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1217                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
1218     }
1219 
1220     /// ----------------------------------------------------------------------
1221     ///
1222     ///   Other methods
1223     ///
1224     /// ----------------------------------------------------------------------
1225 
1226     static void Synchronize(void *deviceContext = NULL);
1227 
1228     static void SetNumThreads(int numThreads);
1229 };
1230 
1231 
1232 }  // end namespace Osd
1233 
1234 }  // end namespace OPENSUBDIV_VERSION
1235 using namespace OPENSUBDIV_VERSION;
1236 
1237 }  // end namespace OpenSubdiv
1238 
1239 
1240 #endif  // OPENSUBDIV3_OSD_OMP_EVALUATOR_H
1241