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_GL_COMPUTE_EVALUATOR_H
26 #define OPENSUBDIV3_OSD_GL_COMPUTE_EVALUATOR_H
27 
28 #include "../version.h"
29 
30 #include "../osd/opengl.h"
31 #include "../osd/types.h"
32 #include "../osd/bufferDescriptor.h"
33 
34 namespace OpenSubdiv {
35 namespace OPENSUBDIV_VERSION {
36 
37 namespace Far {
38     class PatchTable;
39     class StencilTable;
40     class LimitStencilTable;
41 }
42 
43 namespace Osd {
44 
45 /// \brief GL stencil table (Shader Storage buffer)
46 ///
47 /// This class is a GLSL SSBO representation of Far::StencilTable.
48 ///
49 /// GLSLComputeKernel consumes this table to apply stencils
50 ///
51 class GLStencilTableSSBO {
52 public:
53     static GLStencilTableSSBO *Create(Far::StencilTable const *stencilTable,
54                                        void *deviceContext = NULL) {
55         (void)deviceContext;  // unused
56         return new GLStencilTableSSBO(stencilTable);
57     }
58     static GLStencilTableSSBO *Create(
59         Far::LimitStencilTable const *limitStencilTable,
60         void *deviceContext = NULL) {
61         (void)deviceContext;  // unused
62         return new GLStencilTableSSBO(limitStencilTable);
63     }
64 
65     explicit GLStencilTableSSBO(Far::StencilTable const *stencilTable);
66     explicit GLStencilTableSSBO(Far::LimitStencilTable const *limitStencilTable);
67     ~GLStencilTableSSBO();
68 
69     // interfaces needed for GLSLComputeKernel
GetSizesBuffer()70     GLuint GetSizesBuffer() const { return _sizes; }
GetOffsetsBuffer()71     GLuint GetOffsetsBuffer() const { return _offsets; }
GetIndicesBuffer()72     GLuint GetIndicesBuffer() const { return _indices; }
GetWeightsBuffer()73     GLuint GetWeightsBuffer() const { return _weights; }
GetDuWeightsBuffer()74     GLuint GetDuWeightsBuffer() const { return _duWeights; }
GetDvWeightsBuffer()75     GLuint GetDvWeightsBuffer() const { return _dvWeights; }
GetDuuWeightsBuffer()76     GLuint GetDuuWeightsBuffer() const { return _duuWeights; }
GetDuvWeightsBuffer()77     GLuint GetDuvWeightsBuffer() const { return _duvWeights; }
GetDvvWeightsBuffer()78     GLuint GetDvvWeightsBuffer() const { return _dvvWeights; }
GetNumStencils()79     int GetNumStencils() const { return _numStencils; }
80 
81 private:
82     GLuint _sizes;
83     GLuint _offsets;
84     GLuint _indices;
85     GLuint _weights;
86     GLuint _duWeights;
87     GLuint _dvWeights;
88     GLuint _duuWeights;
89     GLuint _duvWeights;
90     GLuint _dvvWeights;
91     int _numStencils;
92 };
93 
94 // ---------------------------------------------------------------------------
95 
96 class GLComputeEvaluator {
97 public:
98     typedef bool Instantiatable;
99     static GLComputeEvaluator * Create(BufferDescriptor const &srcDesc,
100                                        BufferDescriptor const &dstDesc,
101                                        BufferDescriptor const &duDesc,
102                                        BufferDescriptor const &dvDesc,
103                                        void * deviceContext = NULL) {
104         return Create(srcDesc, dstDesc, duDesc, dvDesc,
105                       BufferDescriptor(),
106                       BufferDescriptor(),
107                       BufferDescriptor(),
108                       deviceContext);
109     }
110 
111     static GLComputeEvaluator * Create(BufferDescriptor const &srcDesc,
112                                        BufferDescriptor const &dstDesc,
113                                        BufferDescriptor const &duDesc,
114                                        BufferDescriptor const &dvDesc,
115                                        BufferDescriptor const &duuDesc,
116                                        BufferDescriptor const &duvDesc,
117                                        BufferDescriptor const &dvvDesc,
118                                        void * deviceContext = NULL) {
119         (void)deviceContext;  // not used
120         GLComputeEvaluator *instance = new GLComputeEvaluator();
121         if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
122                               duuDesc, duvDesc, dvvDesc))
123             return instance;
124         delete instance;
125         return NULL;
126     }
127 
128     /// Constructor.
129     GLComputeEvaluator();
130 
131     /// Destructor. note that the GL context must be made current.
132     ~GLComputeEvaluator();
133 
134     /// ----------------------------------------------------------------------
135     ///
136     ///   Stencil evaluations with StencilTable
137     ///
138     /// ----------------------------------------------------------------------
139 
140     /// \brief Generic static stencil function. This function has a same
141     ///        signature as other device kernels have so that it can be called
142     ///        transparently from OsdMesh template interface.
143     ///
144     /// @param srcBuffer      Input primvar buffer.
145     ///                       must have BindVBO() method returning a GL
146     ///                       buffer object of source data
147     ///
148     /// @param srcDesc        vertex buffer descriptor for the input buffer
149     ///
150     /// @param dstBuffer      Output primvar buffer
151     ///                       must have BindVBO() method returning a GL
152     ///                       buffer object of destination data
153     ///
154     /// @param dstDesc        vertex buffer descriptor for the output buffer
155     ///
156     /// @param stencilTable   stencil table to be applied. The table must have
157     ///                       SSBO interfaces.
158     ///
159     /// @param instance       cached compiled instance. Clients are supposed to
160     ///                       pre-compile an instance of this class and provide
161     ///                       to this function. If it's null the kernel still
162     ///                       compute by instantiating on-demand kernel although
163     ///                       it may cause a performance problem.
164     ///
165     /// @param deviceContext  not used in the GLSL 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         STENCIL_TABLE const *stencilTable,
172         GLComputeEvaluator const *instance,
173         void * deviceContext = NULL) {
174 
175         if (instance) {
176             return instance->EvalStencils(srcBuffer, srcDesc,
177                                           dstBuffer, dstDesc,
178                                           stencilTable);
179         } else {
180             // Create an instance on demand (slow)
181             (void)deviceContext;  // unused
182             instance = Create(srcDesc, dstDesc,
183                               BufferDescriptor(),
184                               BufferDescriptor());
185             if (instance) {
186                 bool r = instance->EvalStencils(srcBuffer, srcDesc,
187                                                 dstBuffer, dstDesc,
188                                                 stencilTable);
189                 delete instance;
190                 return r;
191             }
192             return false;
193         }
194     }
195 
196     /// \brief Generic static stencil function. This function has a same
197     ///        signature as other device kernels have so that it can be called
198     ///        transparently from OsdMesh template interface.
199     ///
200     /// @param srcBuffer      Input primvar buffer.
201     ///                       must have BindVBO() method returning a GL
202     ///                       buffer object of source data
203     ///
204     /// @param srcDesc        vertex buffer descriptor for the input buffer
205     ///
206     /// @param dstBuffer      Output primvar buffer
207     ///                       must have BindVBO() method returning a GL
208     ///                       buffer object of destination data
209     ///
210     /// @param dstDesc        vertex buffer descriptor for the dstBuffer
211     ///
212     /// @param duBuffer       Output buffer derivative wrt u
213     ///                       must have BindVBO() method returning a GL
214     ///                       buffer object of destination data
215     ///
216     /// @param duDesc         vertex buffer descriptor for the duBuffer
217     ///
218     /// @param dvBuffer       Output buffer derivative wrt v
219     ///                       must have BindVBO() method returning a GL
220     ///                       buffer object of destination data
221     ///
222     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
223     ///
224     /// @param stencilTable   stencil table to be applied. The table must have
225     ///                       SSBO interfaces.
226     ///
227     /// @param instance       cached compiled instance. Clients are supposed to
228     ///                       pre-compile an instance of this class and provide
229     ///                       to this function. If it's null the kernel still
230     ///                       compute by instantiating on-demand kernel although
231     ///                       it may cause a performance problem.
232     ///
233     /// @param deviceContext  not used in the GLSL kernel
234     ///
235     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
236     static bool EvalStencils(
237         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
238         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
239         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
240         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
241         STENCIL_TABLE const *stencilTable,
242         GLComputeEvaluator const *instance,
243         void * deviceContext = NULL) {
244 
245         if (instance) {
246             return instance->EvalStencils(srcBuffer, srcDesc,
247                                           dstBuffer, dstDesc,
248                                           duBuffer,  duDesc,
249                                           dvBuffer,  dvDesc,
250                                           stencilTable);
251         } else {
252             // Create an instance on demand (slow)
253             (void)deviceContext;  // unused
254             instance = Create(srcDesc, dstDesc, duDesc, dvDesc);
255             if (instance) {
256                 bool r = instance->EvalStencils(srcBuffer, srcDesc,
257                                                 dstBuffer, dstDesc,
258                                                 duBuffer,  duDesc,
259                                                 dvBuffer,  dvDesc,
260                                                 stencilTable);
261                 delete instance;
262                 return r;
263             }
264             return false;
265         }
266     }
267 
268     /// \brief Generic static stencil function. This function has a same
269     ///        signature as other device kernels have so that it can be called
270     ///        transparently from OsdMesh template interface.
271     ///
272     /// @param srcBuffer      Input primvar buffer.
273     ///                       must have BindVBO() method returning a GL
274     ///                       buffer object of source data
275     ///
276     /// @param srcDesc        vertex buffer descriptor for the input buffer
277     ///
278     /// @param dstBuffer      Output primvar buffer
279     ///                       must have BindVBO() method returning a GL
280     ///                       buffer object of destination data
281     ///
282     /// @param dstDesc        vertex buffer descriptor for the dstBuffer
283     ///
284     /// @param duBuffer       Output buffer derivative wrt u
285     ///                       must have BindVBO() method returning a GL
286     ///                       buffer object of destination data
287     ///
288     /// @param duDesc         vertex buffer descriptor for the duBuffer
289     ///
290     /// @param dvBuffer       Output buffer derivative wrt v
291     ///                       must have BindVBO() method returning a GL
292     ///                       buffer object of destination data
293     ///
294     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
295     ///
296     /// @param duuBuffer      Output buffer 2nd derivative wrt u
297     ///                       must have BindVBO() method returning a GL
298     ///                       buffer object of destination data
299     ///
300     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
301     ///
302     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
303     ///                       must have BindVBO() method returning a GL
304     ///                       buffer object of destination data
305     ///
306     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
307     ///
308     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
309     ///                       must have BindVBO() method returning a GL
310     ///                       buffer object of destination data
311     ///
312     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
313     ///
314     /// @param stencilTable   stencil table to be applied. The table must have
315     ///                       SSBO interfaces.
316     ///
317     /// @param instance       cached compiled instance. Clients are supposed to
318     ///                       pre-compile an instance of this class and provide
319     ///                       to this function. If it's null the kernel still
320     ///                       compute by instantiating on-demand kernel although
321     ///                       it may cause a performance problem.
322     ///
323     /// @param deviceContext  not used in the GLSL kernel
324     ///
325     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
326     static bool EvalStencils(
327         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
328         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
329         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
330         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
331         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
332         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
333         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
334         STENCIL_TABLE const *stencilTable,
335         GLComputeEvaluator const *instance,
336         void * deviceContext = NULL) {
337 
338         if (instance) {
339             return instance->EvalStencils(srcBuffer, srcDesc,
340                                           dstBuffer, dstDesc,
341                                           duBuffer,  duDesc,
342                                           dvBuffer,  dvDesc,
343                                           duuBuffer, duuDesc,
344                                           duvBuffer, duvDesc,
345                                           dvvBuffer, dvvDesc,
346                                           stencilTable);
347         } else {
348             // Create an instance on demand (slow)
349             (void)deviceContext;  // unused
350             instance = Create(srcDesc, dstDesc, duDesc, dvDesc,
351                               duuDesc, duvDesc, dvvDesc);
352             if (instance) {
353                 bool r = instance->EvalStencils(srcBuffer, srcDesc,
354                                                 dstBuffer, dstDesc,
355                                                 duBuffer,  duDesc,
356                                                 dvBuffer,  dvDesc,
357                                                 duuBuffer, duuDesc,
358                                                 duvBuffer, duvDesc,
359                                                 dvvBuffer, dvvDesc,
360                                                 stencilTable);
361                 delete instance;
362                 return r;
363             }
364             return false;
365         }
366     }
367 
368     /// \brief Generic stencil function.
369     ///
370     /// @param srcBuffer      Input primvar buffer.
371     ///                       must have BindVBO() method returning a GL
372     ///                       buffer object of source data
373     ///
374     /// @param srcDesc        vertex buffer descriptor for the input buffer
375     ///
376     /// @param dstBuffer      Output primvar buffer
377     ///                       must have BindVBO() method returning a GL
378     ///                       buffer object of destination data
379     ///
380     /// @param dstDesc        vertex buffer descriptor for the output buffer
381     ///
382     /// @param stencilTable   stencil table to be applied. The table must have
383     ///                       SSBO interfaces.
384     ///
385     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
EvalStencils(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,STENCIL_TABLE const * stencilTable)386     bool EvalStencils(
387         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
388         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
389         STENCIL_TABLE const *stencilTable) const {
390         return EvalStencils(srcBuffer->BindVBO(), srcDesc,
391                             dstBuffer->BindVBO(), dstDesc,
392                             0, BufferDescriptor(),
393                             0, BufferDescriptor(),
394                             stencilTable->GetSizesBuffer(),
395                             stencilTable->GetOffsetsBuffer(),
396                             stencilTable->GetIndicesBuffer(),
397                             stencilTable->GetWeightsBuffer(),
398                             0,
399                             0,
400                             /* start = */ 0,
401                             /* end   = */ stencilTable->GetNumStencils());
402     }
403 
404     /// \brief Generic stencil function.
405     ///
406     /// @param srcBuffer      Input primvar buffer.
407     ///                       must have BindVBO() method returning a GL
408     ///                       buffer object of source data
409     ///
410     /// @param srcDesc        vertex buffer descriptor for the input buffer
411     ///
412     /// @param dstBuffer      Output primvar buffer
413     ///                       must have BindVBO() method returning a GL
414     ///                       buffer object of destination data
415     ///
416     /// @param dstDesc        vertex buffer descriptor for the dstBuffer
417     ///
418     /// @param duBuffer       Output buffer derivative wrt u
419     ///                       must have BindVBO() method returning a GL
420     ///                       buffer object of destination data
421     ///
422     /// @param duDesc         vertex buffer descriptor for the duBuffer
423     ///
424     /// @param dvBuffer       Output buffer derivative wrt v
425     ///                       must have BindVBO() method returning a GL
426     ///                       buffer object of destination data
427     ///
428     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
429     ///
430     /// @param stencilTable   stencil table to be applied. The table must have
431     ///                       SSBO interfaces.
432     ///
433     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
EvalStencils(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,STENCIL_TABLE const * stencilTable)434     bool EvalStencils(
435         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
436         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
437         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
438         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
439         STENCIL_TABLE const *stencilTable) const {
440         return EvalStencils(srcBuffer->BindVBO(), srcDesc,
441                             dstBuffer->BindVBO(), dstDesc,
442                             duBuffer->BindVBO(),  duDesc,
443                             dvBuffer->BindVBO(),  dvDesc,
444                             stencilTable->GetSizesBuffer(),
445                             stencilTable->GetOffsetsBuffer(),
446                             stencilTable->GetIndicesBuffer(),
447                             stencilTable->GetWeightsBuffer(),
448                             stencilTable->GetDuWeightsBuffer(),
449                             stencilTable->GetDvWeightsBuffer(),
450                             /* start = */ 0,
451                             /* end   = */ stencilTable->GetNumStencils());
452     }
453 
454     /// \brief Generic stencil function.
455     ///
456     /// @param srcBuffer      Input primvar buffer.
457     ///                       must have BindVBO() method returning a GL
458     ///                       buffer object of source data
459     ///
460     /// @param srcDesc        vertex buffer descriptor for the input buffer
461     ///
462     /// @param dstBuffer      Output primvar buffer
463     ///                       must have BindVBO() method returning a GL
464     ///                       buffer object of destination data
465     ///
466     /// @param dstDesc        vertex buffer descriptor for the dstBuffer
467     ///
468     /// @param duBuffer       Output buffer derivative wrt u
469     ///                       must have BindVBO() method returning a GL
470     ///                       buffer object of destination data
471     ///
472     /// @param duDesc         vertex buffer descriptor for the duBuffer
473     ///
474     /// @param dvBuffer       Output buffer derivative wrt v
475     ///                       must have BindVBO() method returning a GL
476     ///                       buffer object of destination data
477     ///
478     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
479     ///
480     /// @param duuBuffer      Output buffer 2nd derivative wrt u
481     ///                       must have BindVBO() method returning a GL
482     ///                       buffer object of destination data
483     ///
484     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
485     ///
486     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
487     ///                       must have BindVBO() method returning a GL
488     ///                       buffer object of destination data
489     ///
490     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
491     ///
492     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
493     ///                       must have BindVBO() method returning a GL
494     ///                       buffer object of destination data
495     ///
496     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
497     ///
498     /// @param stencilTable   stencil table to be applied. The table must have
499     ///                       SSBO interfaces.
500     ///
501     template <typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
EvalStencils(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,DST_BUFFER * duuBuffer,BufferDescriptor const & duuDesc,DST_BUFFER * duvBuffer,BufferDescriptor const & duvDesc,DST_BUFFER * dvvBuffer,BufferDescriptor const & dvvDesc,STENCIL_TABLE const * stencilTable)502     bool EvalStencils(
503         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
504         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
505         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
506         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
507         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
508         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
509         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
510         STENCIL_TABLE const *stencilTable) const {
511         return EvalStencils(srcBuffer->BindVBO(), srcDesc,
512                             dstBuffer->BindVBO(), dstDesc,
513                             duBuffer->BindVBO(),  duDesc,
514                             dvBuffer->BindVBO(),  dvDesc,
515                             duuBuffer->BindVBO(), duuDesc,
516                             duvBuffer->BindVBO(), duvDesc,
517                             dvvBuffer->BindVBO(), dvvDesc,
518                             stencilTable->GetSizesBuffer(),
519                             stencilTable->GetOffsetsBuffer(),
520                             stencilTable->GetIndicesBuffer(),
521                             stencilTable->GetWeightsBuffer(),
522                             stencilTable->GetDuWeightsBuffer(),
523                             stencilTable->GetDvWeightsBuffer(),
524                             stencilTable->GetDuuWeightsBuffer(),
525                             stencilTable->GetDuvWeightsBuffer(),
526                             stencilTable->GetDvvWeightsBuffer(),
527                             /* start = */ 0,
528                             /* end   = */ stencilTable->GetNumStencils());
529     }
530 
531     /// \brief Dispatch the GLSL compute kernel on GPU asynchronously
532     /// returns false if the kernel hasn't been compiled yet.
533     ///
534     /// @param srcBuffer        GL buffer of input primvar source data
535     ///
536     /// @param srcDesc          vertex buffer descriptor for the srcBuffer
537     ///
538     /// @param dstBuffer        GL buffer of output primvar destination data
539     ///
540     /// @param dstDesc          vertex buffer descriptor for the dstBuffer
541     ///
542     /// @param duBuffer         GL buffer of output derivative wrt u
543     ///
544     /// @param duDesc           vertex buffer descriptor for the duBuffer
545     ///
546     /// @param dvBuffer         GL buffer of output derivative wrt v
547     ///
548     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
549     ///
550     /// @param sizesBuffer      GL buffer of the sizes in the stencil table
551     ///
552     /// @param offsetsBuffer    GL buffer of the offsets in the stencil table
553     ///
554     /// @param indicesBuffer    GL buffer of the indices in the stencil table
555     ///
556     /// @param weightsBuffer    GL buffer of the weights in the stencil table
557     ///
558     /// @param duWeightsBuffer  GL buffer of the du weights in the stencil table
559     ///
560     /// @param dvWeightsBuffer  GL buffer of the dv weights in the stencil table
561     ///
562     /// @param start            start index of stencil table
563     ///
564     /// @param end              end index of stencil table
565     ///
566     bool EvalStencils(GLuint srcBuffer, BufferDescriptor const &srcDesc,
567                       GLuint dstBuffer, BufferDescriptor const &dstDesc,
568                       GLuint duBuffer,  BufferDescriptor const &duDesc,
569                       GLuint dvBuffer,  BufferDescriptor const &dvDesc,
570                       GLuint sizesBuffer,
571                       GLuint offsetsBuffer,
572                       GLuint indicesBuffer,
573                       GLuint weightsBuffer,
574                       GLuint duWeightsBuffer,
575                       GLuint dvWeightsBuffer,
576                       int start,
577                       int end) const;
578 
579     /// \brief Dispatch the GLSL compute kernel on GPU asynchronously
580     /// returns false if the kernel hasn't been compiled yet.
581     ///
582     /// @param srcBuffer        GL buffer of input primvar source data
583     ///
584     /// @param srcDesc          vertex buffer descriptor for the srcBuffer
585     ///
586     /// @param dstBuffer        GL buffer of output primvar destination data
587     ///
588     /// @param dstDesc          vertex buffer descriptor for the dstBuffer
589     ///
590     /// @param duBuffer         GL buffer of output derivative wrt u
591     ///
592     /// @param duDesc           vertex buffer descriptor for the duBuffer
593     ///
594     /// @param dvBuffer         GL buffer of output derivative wrt v
595     ///
596     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
597     ///
598     /// @param duuBuffer        GL buffer of output 2nd derivative wrt u
599     ///
600     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
601     ///
602     /// @param duvBuffer        GL buffer of output 2nd derivative wrt u and v
603     ///
604     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
605     ///
606     /// @param dvvBuffer        GL buffer of output 2nd derivative wrt v
607     ///
608     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
609     ///
610     /// @param sizesBuffer      GL buffer of the sizes in the stencil table
611     ///
612     /// @param offsetsBuffer    GL buffer of the offsets in the stencil table
613     ///
614     /// @param indicesBuffer    GL buffer of the indices in the stencil table
615     ///
616     /// @param weightsBuffer    GL buffer of the weights in the stencil table
617     ///
618     /// @param duWeightsBuffer  GL buffer of the du weights in the stencil table
619     ///
620     /// @param dvWeightsBuffer  GL buffer of the dv weights in the stencil table
621     ///
622     /// @param duuWeightsBuffer GL buffer of the duu weights in the stencil table
623     ///
624     /// @param duvWeightsBuffer GL buffer of the duv weights in the stencil table
625     ///
626     /// @param dvvWeightsBuffer GL buffer of the dvv weights in the stencil table
627     ///
628     /// @param start            start index of stencil table
629     ///
630     /// @param end              end index of stencil table
631     ///
632     bool EvalStencils(GLuint srcBuffer, BufferDescriptor const &srcDesc,
633                       GLuint dstBuffer, BufferDescriptor const &dstDesc,
634                       GLuint duBuffer,  BufferDescriptor const &duDesc,
635                       GLuint dvBuffer,  BufferDescriptor const &dvDesc,
636                       GLuint duuBuffer, BufferDescriptor const &duuDesc,
637                       GLuint duvBuffer, BufferDescriptor const &duvDesc,
638                       GLuint dvvBuffer, BufferDescriptor const &dvvDesc,
639                       GLuint sizesBuffer,
640                       GLuint offsetsBuffer,
641                       GLuint indicesBuffer,
642                       GLuint weightsBuffer,
643                       GLuint duWeightsBuffer,
644                       GLuint dvWeightsBuffer,
645                       GLuint duuWeightsBuffer,
646                       GLuint duvWeightsBuffer,
647                       GLuint dvvWeightsBuffer,
648                       int start,
649                       int end) const;
650 
651     /// ----------------------------------------------------------------------
652     ///
653     ///   Limit evaluations with PatchTable
654     ///
655     /// ----------------------------------------------------------------------
656 
657     /// \brief Generic limit eval function. This function has a same
658     ///        signature as other device kernels have so that it can be called
659     ///        in the same way.
660     ///
661     /// @param srcBuffer      Input primvar buffer.
662     ///                       must have BindVBO() method returning a GL
663     ///                       buffer object of source data
664     ///
665     /// @param srcDesc        vertex buffer descriptor for the input buffer
666     ///
667     /// @param dstBuffer      Output primvar buffer
668     ///                       must have BindVBO() method returning a GL
669     ///                       buffer object of destination data
670     ///
671     /// @param dstDesc        vertex buffer descriptor for the output buffer
672     ///
673     /// @param numPatchCoords number of patchCoords.
674     ///
675     /// @param patchCoords    array of locations to be evaluated.
676     ///                       must have BindVBO() method returning an
677     ///                       array of PatchCoord struct in VBO.
678     ///
679     /// @param patchTable     GLPatchTable or equivalent
680     ///
681     /// @param instance       cached compiled instance. Clients are supposed to
682     ///                       pre-compile an instance of this class and provide
683     ///                       to this function. If it's null the kernel still
684     ///                       compute by instantiating on-demand kernel although
685     ///                       it may cause a performance problem.
686     ///
687     /// @param deviceContext  not used in the GLXFB evaluator
688     ///
689     template <typename SRC_BUFFER, typename DST_BUFFER,
690               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
691     static bool EvalPatches(
692         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
693         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
694         int numPatchCoords,
695         PATCHCOORD_BUFFER *patchCoords,
696         PATCH_TABLE *patchTable,
697         GLComputeEvaluator const *instance,
698         void * deviceContext = NULL) {
699 
700         if (instance) {
701             return instance->EvalPatches(srcBuffer, srcDesc,
702                                          dstBuffer, dstDesc,
703                                          numPatchCoords, patchCoords,
704                                          patchTable);
705         } else {
706             // Create an instance on demand (slow)
707             (void)deviceContext;  // unused
708             instance = Create(srcDesc, dstDesc,
709                               BufferDescriptor(),
710                               BufferDescriptor());
711             if (instance) {
712                 bool r = instance->EvalPatches(srcBuffer, srcDesc,
713                                                dstBuffer, dstDesc,
714                                                numPatchCoords, patchCoords,
715                                                patchTable);
716                 delete instance;
717                 return r;
718             }
719             return false;
720         }
721     }
722 
723     /// \brief Generic limit eval function. This function has a same
724     ///        signature as other device kernels have so that it can be called
725     ///        in the same way.
726     ///
727     /// @param srcBuffer      Input primvar buffer.
728     ///                       must have BindVBO() method returning a GL
729     ///                       buffer object of source data
730     ///
731     /// @param srcDesc        vertex buffer descriptor for the input buffer
732     ///
733     /// @param dstBuffer      Output primvar buffer
734     ///                       must have BindVBO() method returning a GL
735     ///                       buffer object of destination data
736     ///
737     /// @param dstDesc        vertex buffer descriptor for the output buffer
738     ///
739     /// @param duBuffer       Output buffer derivative wrt u
740     ///                       must have BindVBO() method returning a GL
741     ///                       buffer object of destination data
742     ///
743     /// @param duDesc         vertex buffer descriptor for the duBuffer
744     ///
745     /// @param dvBuffer       Output buffer derivative wrt v
746     ///                       must have BindVBO() method returning a GL
747     ///                       buffer object of destination data
748     ///
749     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
750     ///
751     /// @param numPatchCoords number of patchCoords.
752     ///
753     /// @param patchCoords    array of locations to be evaluated.
754     ///                       must have BindVBO() method returning an
755     ///                       array of PatchCoord struct in VBO.
756     ///
757     /// @param patchTable     GLPatchTable or equivalent
758     ///
759     /// @param instance       cached compiled instance. Clients are supposed to
760     ///                       pre-compile an instance of this class and provide
761     ///                       to this function. If it's null the kernel still
762     ///                       compute by instantiating on-demand kernel although
763     ///                       it may cause a performance problem.
764     ///
765     /// @param deviceContext  not used in the GLXFB evaluator
766     ///
767     template <typename SRC_BUFFER, typename DST_BUFFER,
768               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
769     static bool EvalPatches(
770         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
771         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
772         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
773         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
774         int numPatchCoords,
775         PATCHCOORD_BUFFER *patchCoords,
776         PATCH_TABLE *patchTable,
777         GLComputeEvaluator const *instance,
778         void * deviceContext = NULL) {
779 
780         if (instance) {
781             return instance->EvalPatches(srcBuffer, srcDesc,
782                                          dstBuffer, dstDesc,
783                                          duBuffer, duDesc,
784                                          dvBuffer, dvDesc,
785                                          numPatchCoords, patchCoords,
786                                          patchTable);
787         } else {
788             // Create an instance on demand (slow)
789             (void)deviceContext;  // unused
790             instance = Create(srcDesc, dstDesc,
791                               duDesc, dvDesc);
792             if (instance) {
793                 bool r = instance->EvalPatches(srcBuffer, srcDesc,
794                                                dstBuffer, dstDesc,
795                                                duBuffer, duDesc,
796                                                dvBuffer, dvDesc,
797                                                numPatchCoords, patchCoords,
798                                                patchTable);
799                 delete instance;
800                 return r;
801             }
802             return false;
803         }
804     }
805 
806     /// \brief Generic limit eval function. This function has a same
807     ///        signature as other device kernels have so that it can be called
808     ///        in the same way.
809     ///
810     /// @param srcBuffer      Input primvar buffer.
811     ///                       must have BindVBO() method returning a GL
812     ///                       buffer object of source data
813     ///
814     /// @param srcDesc        vertex buffer descriptor for the input buffer
815     ///
816     /// @param dstBuffer      Output primvar buffer
817     ///                       must have BindVBO() method returning a GL
818     ///                       buffer object of destination data
819     ///
820     /// @param dstDesc        vertex buffer descriptor for the output buffer
821     ///
822     /// @param duBuffer       Output buffer derivative wrt u
823     ///                       must have BindVBO() method returning a GL
824     ///                       buffer object of destination data
825     ///
826     /// @param duDesc         vertex buffer descriptor for the duBuffer
827     ///
828     /// @param dvBuffer       Output buffer derivative wrt v
829     ///                       must have BindVBO() method returning a GL
830     ///                       buffer object of destination data
831     ///
832     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
833     ///
834     /// @param duuBuffer      Output buffer 2nd derivative wrt u
835     ///                       must have BindVBO() method returning a GL
836     ///                       buffer object of destination data
837     ///
838     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
839     ///
840     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
841     ///                       must have BindVBO() method returning a GL
842     ///                       buffer object of destination data
843     ///
844     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
845     ///
846     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
847     ///                       must have BindVBO() method returning a GL
848     ///                       buffer object of destination data
849     ///
850     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
851     ///
852     /// @param numPatchCoords number of patchCoords.
853     ///
854     /// @param patchCoords    array of locations to be evaluated.
855     ///                       must have BindVBO() method returning an
856     ///                       array of PatchCoord struct in VBO.
857     ///
858     /// @param patchTable     GLPatchTable or equivalent
859     ///
860     /// @param instance       cached compiled instance. Clients are supposed to
861     ///                       pre-compile an instance of this class and provide
862     ///                       to this function. If it's null the kernel still
863     ///                       compute by instantiating on-demand kernel although
864     ///                       it may cause a performance problem.
865     ///
866     /// @param deviceContext  not used in the GLXFB evaluator
867     ///
868     template <typename SRC_BUFFER, typename DST_BUFFER,
869               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
870     static bool EvalPatches(
871         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
872         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
873         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
874         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
875         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
876         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
877         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
878         int numPatchCoords,
879         PATCHCOORD_BUFFER *patchCoords,
880         PATCH_TABLE *patchTable,
881         GLComputeEvaluator const *instance,
882         void * deviceContext = NULL) {
883 
884         if (instance) {
885             return instance->EvalPatches(srcBuffer, srcDesc,
886                                          dstBuffer, dstDesc,
887                                          duBuffer, duDesc,
888                                          dvBuffer, dvDesc,
889                                          duuBuffer, duuDesc,
890                                          duvBuffer, duvDesc,
891                                          dvvBuffer, dvvDesc,
892                                          numPatchCoords, patchCoords,
893                                          patchTable);
894         } else {
895             // Create an instance on demand (slow)
896             (void)deviceContext;  // unused
897             instance = Create(srcDesc, dstDesc,
898                               duDesc, dvDesc,
899                               duuDesc, duvDesc, dvvDesc);
900             if (instance) {
901                 bool r = instance->EvalPatches(srcBuffer, srcDesc,
902                                                dstBuffer, dstDesc,
903                                                duBuffer, duDesc,
904                                                dvBuffer, dvDesc,
905                                                duuBuffer, duuDesc,
906                                                duvBuffer, duvDesc,
907                                                dvvBuffer, dvvDesc,
908                                                numPatchCoords, patchCoords,
909                                                patchTable);
910                 delete instance;
911                 return r;
912             }
913             return false;
914         }
915     }
916 
917     /// \brief Generic limit eval function. This function has a same
918     ///        signature as other device kernels have so that it can be called
919     ///        in the same way.
920     ///
921     /// @param srcBuffer      Input primvar buffer.
922     ///                       must have BindVBO() method returning a GL
923     ///                       buffer object of source data
924     ///
925     /// @param srcDesc        vertex buffer descriptor for the input buffer
926     ///
927     /// @param dstBuffer      Output primvar buffer
928     ///                       must have BindVBO() method returning a GL
929     ///                       buffer object of destination data
930     ///
931     /// @param dstDesc        vertex buffer descriptor for the output buffer
932     ///
933     /// @param numPatchCoords number of patchCoords.
934     ///
935     /// @param patchCoords    array of locations to be evaluated.
936     ///                       must have BindVBO() method returning an
937     ///                       array of PatchCoord struct in VBO.
938     ///
939     /// @param patchTable     GLPatchTable or equivalent
940     ///
941     template <typename SRC_BUFFER, typename DST_BUFFER,
942               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatches(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)943     bool EvalPatches(
944         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
945         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
946         int numPatchCoords,
947         PATCHCOORD_BUFFER *patchCoords,
948         PATCH_TABLE *patchTable) const {
949 
950         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
951                            dstBuffer->BindVBO(), dstDesc,
952                            0, BufferDescriptor(),
953                            0, BufferDescriptor(),
954                            numPatchCoords,
955                            patchCoords->BindVBO(),
956                            patchTable->GetPatchArrays(),
957                            patchTable->GetPatchIndexBuffer(),
958                            patchTable->GetPatchParamBuffer());
959     }
960 
961     /// \brief Generic limit eval function with derivatives. This function has
962     ///        a same signature as other device kernels have so that it can be
963     ///        called in the same way.
964     ///
965     /// @param srcBuffer        Input primvar buffer.
966     ///                         must have BindVBO() method returning a GL
967     ///                         buffer object of source data
968     ///
969     /// @param srcDesc          vertex buffer descriptor for the input buffer
970     ///
971     /// @param dstBuffer        Output primvar buffer
972     ///                         must have BindVBO() method returning a GL
973     ///                         buffer object of destination data
974     ///
975     /// @param dstDesc          vertex buffer descriptor for the output buffer
976     ///
977     /// @param duBuffer         Output buffer derivative wrt u
978     ///                         must have BindVBO() method returning a GL
979     ///                         buffer object of destination data
980     ///
981     /// @param duDesc           vertex buffer descriptor for the duBuffer
982     ///
983     /// @param dvBuffer         Output buffer derivative wrt v
984     ///                         must have BindVBO() method returning a GL
985     ///                         buffer object of destination data
986     ///
987     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
988     ///
989     /// @param numPatchCoords   number of patchCoords.
990     ///
991     /// @param patchCoords      array of locations to be evaluated.
992     ///
993     /// @param patchTable       GLPatchTable or equivalent
994     ///
995     template <typename SRC_BUFFER, typename DST_BUFFER,
996               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatches(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)997     bool EvalPatches(
998         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
999         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1000         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1001         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1002         int numPatchCoords,
1003         PATCHCOORD_BUFFER *patchCoords,
1004         PATCH_TABLE *patchTable) const {
1005 
1006         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1007                            dstBuffer->BindVBO(), dstDesc,
1008                            duBuffer->BindVBO(),  duDesc,
1009                            dvBuffer->BindVBO(),  dvDesc,
1010                            numPatchCoords,
1011                            patchCoords->BindVBO(),
1012                            patchTable->GetPatchArrays(),
1013                            patchTable->GetPatchIndexBuffer(),
1014                            patchTable->GetPatchParamBuffer());
1015     }
1016 
1017     /// \brief Generic limit eval function with derivatives. This function has
1018     ///        a same signature as other device kernels have so that it can be
1019     ///        called in the same way.
1020     ///
1021     /// @param srcBuffer        Input primvar buffer.
1022     ///                         must have BindVBO() method returning a GL
1023     ///                         buffer object of source data
1024     ///
1025     /// @param srcDesc          vertex buffer descriptor for the input buffer
1026     ///
1027     /// @param dstBuffer        Output primvar buffer
1028     ///                         must have BindVBO() method returning a GL
1029     ///                         buffer object of destination data
1030     ///
1031     /// @param dstDesc          vertex buffer descriptor for the output buffer
1032     ///
1033     /// @param duBuffer         Output buffer derivative wrt u
1034     ///                         must have BindVBO() method returning a GL
1035     ///                         buffer object of destination data
1036     ///
1037     /// @param duDesc           vertex buffer descriptor for the duBuffer
1038     ///
1039     /// @param dvBuffer         Output buffer derivative wrt v
1040     ///                         must have BindVBO() method returning a GL
1041     ///                         buffer object of destination data
1042     ///
1043     /// @param dvDesc           vertex buffer descriptor for the dvBuffer
1044     ///
1045     /// @param duuBuffer        Output buffer 2nd derivative wrt u
1046     ///                         must have BindVBO() method returning a GL
1047     ///                         buffer object of destination data
1048     ///
1049     /// @param duuDesc          vertex buffer descriptor for the duuBuffer
1050     ///
1051     /// @param duvBuffer        Output buffer 2nd derivative wrt u and v
1052     ///                         must have BindVBO() method returning a GL
1053     ///                         buffer object of destination data
1054     ///
1055     /// @param duvDesc          vertex buffer descriptor for the duvBuffer
1056     ///
1057     /// @param dvvBuffer        Output buffer 2nd derivative wrt v
1058     ///                         must have BindVBO() method returning a GL
1059     ///                         buffer object of destination data
1060     ///
1061     /// @param dvvDesc          vertex buffer descriptor for the dvvBuffer
1062     ///
1063     /// @param numPatchCoords   number of patchCoords.
1064     ///
1065     /// @param patchCoords      array of locations to be evaluated.
1066     ///
1067     /// @param patchTable       GLPatchTable or equivalent
1068     ///
1069     template <typename SRC_BUFFER, typename DST_BUFFER,
1070               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatches(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,DST_BUFFER * duuBuffer,BufferDescriptor const & duuDesc,DST_BUFFER * duvBuffer,BufferDescriptor const & duvDesc,DST_BUFFER * dvvBuffer,BufferDescriptor const & dvvDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)1071     bool EvalPatches(
1072         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1073         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1074         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1075         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1076         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
1077         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
1078         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
1079         int numPatchCoords,
1080         PATCHCOORD_BUFFER *patchCoords,
1081         PATCH_TABLE *patchTable) const {
1082 
1083         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1084                            dstBuffer->BindVBO(), dstDesc,
1085                            duBuffer->BindVBO(),  duDesc,
1086                            dvBuffer->BindVBO(),  dvDesc,
1087                            duuBuffer->BindVBO(), duuDesc,
1088                            duvBuffer->BindVBO(), duvDesc,
1089                            dvvBuffer->BindVBO(), dvvDesc,
1090                            numPatchCoords,
1091                            patchCoords->BindVBO(),
1092                            patchTable->GetPatchArrays(),
1093                            patchTable->GetPatchIndexBuffer(),
1094                            patchTable->GetPatchParamBuffer());
1095     }
1096 
1097     bool EvalPatches(GLuint srcBuffer, BufferDescriptor const &srcDesc,
1098                      GLuint dstBuffer, BufferDescriptor const &dstDesc,
1099                      GLuint duBuffer,  BufferDescriptor const &duDesc,
1100                      GLuint dvBuffer,  BufferDescriptor const &dvDesc,
1101                      int numPatchCoords,
1102                      GLuint patchCoordsBuffer,
1103                      const PatchArrayVector &patchArrays,
1104                      GLuint patchIndexBuffer,
1105                      GLuint patchParamsBuffer) const;
1106 
1107     bool EvalPatches(GLuint srcBuffer, BufferDescriptor const &srcDesc,
1108                      GLuint dstBuffer, BufferDescriptor const &dstDesc,
1109                      GLuint duBuffer,  BufferDescriptor const &duDesc,
1110                      GLuint dvBuffer,  BufferDescriptor const &dvDesc,
1111                      GLuint duuBuffer, BufferDescriptor const &duuDesc,
1112                      GLuint duvBuffer, BufferDescriptor const &duvDesc,
1113                      GLuint dvvBuffer, BufferDescriptor const &dvvDesc,
1114                      int numPatchCoords,
1115                      GLuint patchCoordsBuffer,
1116                      const PatchArrayVector &patchArrays,
1117                      GLuint patchIndexBuffer,
1118                      GLuint patchParamsBuffer) const;
1119 
1120     /// \brief Generic limit eval function. This function has a same
1121     ///        signature as other device kernels have so that it can be called
1122     ///        in the same way.
1123     ///
1124     /// @param srcBuffer      Input primvar buffer.
1125     ///                       must have BindVBO() method returning a GL
1126     ///                       buffer object of source data
1127     ///
1128     /// @param srcDesc        vertex buffer descriptor for the input buffer
1129     ///
1130     /// @param dstBuffer      Output primvar buffer
1131     ///                       must have BindVBO() method returning a GL
1132     ///                       buffer object of destination data
1133     ///
1134     /// @param dstDesc        vertex buffer descriptor for the output buffer
1135     ///
1136     /// @param numPatchCoords number of patchCoords.
1137     ///
1138     /// @param patchCoords    array of locations to be evaluated.
1139     ///                       must have BindVBO() method returning an
1140     ///                       array of PatchCoord struct in VBO.
1141     ///
1142     /// @param patchTable     GLPatchTable or equivalent
1143     ///
1144     /// @param instance       cached compiled instance. Clients are supposed to
1145     ///                       pre-compile an instance of this class and provide
1146     ///                       to this function. If it's null the kernel still
1147     ///                       compute by instantiating on-demand kernel although
1148     ///                       it may cause a performance problem.
1149     ///
1150     /// @param deviceContext  not used in the GLXFB evaluator
1151     ///
1152     template <typename SRC_BUFFER, typename DST_BUFFER,
1153               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1154     static bool EvalPatchesVarying(
1155         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1156         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1157         int numPatchCoords,
1158         PATCHCOORD_BUFFER *patchCoords,
1159         PATCH_TABLE *patchTable,
1160         GLComputeEvaluator const *instance,
1161         void * deviceContext = NULL) {
1162 
1163         if (instance) {
1164             return instance->EvalPatchesVarying(
1165                                          srcBuffer, srcDesc,
1166                                          dstBuffer, dstDesc,
1167                                          numPatchCoords, patchCoords,
1168                                          patchTable);
1169         } else {
1170             // Create an instance on demand (slow)
1171             (void)deviceContext;  // unused
1172             instance = Create(srcDesc, dstDesc,
1173                               BufferDescriptor(),
1174                               BufferDescriptor());
1175             if (instance) {
1176                 bool r = instance->EvalPatchesVarying(
1177                                                srcBuffer, srcDesc,
1178                                                dstBuffer, dstDesc,
1179                                                numPatchCoords, patchCoords,
1180                                                patchTable);
1181                 delete instance;
1182                 return r;
1183             }
1184             return false;
1185         }
1186     }
1187 
1188     /// \brief Generic limit eval function. This function has a same
1189     ///        signature as other device kernels have so that it can be called
1190     ///        in the same way.
1191     ///
1192     /// @param srcBuffer      Input primvar buffer.
1193     ///                       must have BindVBO() method returning a GL
1194     ///                       buffer object of source data
1195     ///
1196     /// @param srcDesc        vertex buffer descriptor for the input buffer
1197     ///
1198     /// @param dstBuffer      Output primvar buffer
1199     ///                       must have BindVBO() method returning a GL
1200     ///                       buffer object of destination data
1201     ///
1202     /// @param dstDesc        vertex buffer descriptor for the output buffer
1203     ///
1204     /// @param numPatchCoords number of patchCoords.
1205     ///
1206     /// @param patchCoords    array of locations to be evaluated.
1207     ///                       must have BindVBO() method returning an
1208     ///                       array of PatchCoord struct in VBO.
1209     ///
1210     /// @param patchTable     GLPatchTable or equivalent
1211     ///
1212     template <typename SRC_BUFFER, typename DST_BUFFER,
1213               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatchesVarying(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)1214     bool EvalPatchesVarying(
1215         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1216         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1217         int numPatchCoords,
1218         PATCHCOORD_BUFFER *patchCoords,
1219         PATCH_TABLE *patchTable) const {
1220 
1221         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1222                            dstBuffer->BindVBO(), dstDesc,
1223                            0, BufferDescriptor(),
1224                            0, BufferDescriptor(),
1225                            numPatchCoords,
1226                            patchCoords->BindVBO(),
1227                            patchTable->GetVaryingPatchArrays(),
1228                            patchTable->GetVaryingPatchIndexBuffer(),
1229                            patchTable->GetPatchParamBuffer());
1230     }
1231 
1232     /// \brief Generic limit eval function. This function has a same
1233     ///        signature as other device kernels have so that it can be called
1234     ///        in the same way.
1235     ///
1236     /// @param srcBuffer      Input primvar buffer.
1237     ///                       must have BindVBO() method returning a GL
1238     ///                       buffer object of source data
1239     ///
1240     /// @param srcDesc        vertex buffer descriptor for the input buffer
1241     ///
1242     /// @param dstBuffer      Output primvar buffer
1243     ///                       must have BindVBO() method returning a GL
1244     ///                       buffer object of destination data
1245     ///
1246     /// @param dstDesc        vertex buffer descriptor for the output buffer
1247     ///
1248     /// @param duBuffer       Output buffer derivative wrt u
1249     ///                       must have BindVBO() method returning a GL
1250     ///                       buffer object of destination data
1251     ///
1252     /// @param duDesc         vertex buffer descriptor for the duBuffer
1253     ///
1254     /// @param dvBuffer       Output buffer derivative wrt v
1255     ///                       must have BindVBO() method returning a GL
1256     ///                       buffer object of destination data
1257     ///
1258     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1259     ///
1260     /// @param numPatchCoords number of patchCoords.
1261     ///
1262     /// @param patchCoords    array of locations to be evaluated.
1263     ///                       must have BindVBO() method returning an
1264     ///                       array of PatchCoord struct in VBO.
1265     ///
1266     /// @param patchTable     GLPatchTable or equivalent
1267     ///
1268     /// @param instance       cached compiled instance. Clients are supposed to
1269     ///                       pre-compile an instance of this class and provide
1270     ///                       to this function. If it's null the kernel still
1271     ///                       compute by instantiating on-demand kernel although
1272     ///                       it may cause a performance problem.
1273     ///
1274     /// @param deviceContext  not used in the GLXFB evaluator
1275     ///
1276     template <typename SRC_BUFFER, typename DST_BUFFER,
1277               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1278     static bool EvalPatchesVarying(
1279         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1280         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1281         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1282         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1283         int numPatchCoords,
1284         PATCHCOORD_BUFFER *patchCoords,
1285         PATCH_TABLE *patchTable,
1286         GLComputeEvaluator const *instance,
1287         void * deviceContext = NULL) {
1288 
1289         if (instance) {
1290             return instance->EvalPatchesVarying(
1291                                          srcBuffer, srcDesc,
1292                                          dstBuffer, dstDesc,
1293                                          duBuffer, duDesc,
1294                                          dvBuffer, dvDesc,
1295                                          numPatchCoords, patchCoords,
1296                                          patchTable);
1297         } else {
1298             // Create an instance on demand (slow)
1299             (void)deviceContext;  // unused
1300             instance = Create(srcDesc, dstDesc,
1301                               duDesc, dvDesc);
1302             if (instance) {
1303                 bool r = instance->EvalPatchesVarying(
1304                                                srcBuffer, srcDesc,
1305                                                dstBuffer, dstDesc,
1306                                                duBuffer, duDesc,
1307                                                dvBuffer, dvDesc,
1308                                                numPatchCoords, patchCoords,
1309                                                patchTable);
1310                 delete instance;
1311                 return r;
1312             }
1313             return false;
1314         }
1315     }
1316 
1317     /// \brief Generic limit eval function. This function has a same
1318     ///        signature as other device kernels have so that it can be called
1319     ///        in the same way.
1320     ///
1321     /// @param srcBuffer      Input primvar buffer.
1322     ///                       must have BindVBO() method returning a GL
1323     ///                       buffer object of source data
1324     ///
1325     /// @param srcDesc        vertex buffer descriptor for the input buffer
1326     ///
1327     /// @param dstBuffer      Output primvar buffer
1328     ///                       must have BindVBO() method returning a GL
1329     ///                       buffer object of destination data
1330     ///
1331     /// @param dstDesc        vertex buffer descriptor for the output buffer
1332     ///
1333     /// @param duBuffer       Output buffer derivative wrt u
1334     ///                       must have BindVBO() method returning a GL
1335     ///                       buffer object of destination data
1336     ///
1337     /// @param duDesc         vertex buffer descriptor for the duBuffer
1338     ///
1339     /// @param dvBuffer       Output buffer derivative wrt v
1340     ///                       must have BindVBO() method returning a GL
1341     ///                       buffer object of destination data
1342     ///
1343     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1344     ///
1345     /// @param numPatchCoords number of patchCoords.
1346     ///
1347     /// @param patchCoords    array of locations to be evaluated.
1348     ///                       must have BindVBO() method returning an
1349     ///                       array of PatchCoord struct in VBO.
1350     ///
1351     /// @param patchTable     GLPatchTable or equivalent
1352     ///
1353     template <typename SRC_BUFFER, typename DST_BUFFER,
1354               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatchesVarying(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)1355     bool EvalPatchesVarying(
1356         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1357         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1358         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1359         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1360         int numPatchCoords,
1361         PATCHCOORD_BUFFER *patchCoords,
1362         PATCH_TABLE *patchTable) const {
1363 
1364         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1365                            dstBuffer->BindVBO(), dstDesc,
1366                            duBuffer->BindVBO(),  duDesc,
1367                            dvBuffer->BindVBO(),  dvDesc,
1368                            numPatchCoords,
1369                            patchCoords->BindVBO(),
1370                            patchTable->GetVaryingPatchArrays(),
1371                            patchTable->GetVaryingPatchIndexBuffer(),
1372                            patchTable->GetPatchParamBuffer());
1373     }
1374 
1375     /// \brief Generic limit eval function. This function has a same
1376     ///        signature as other device kernels have so that it can be called
1377     ///        in the same way.
1378     ///
1379     /// @param srcBuffer      Input primvar buffer.
1380     ///                       must have BindVBO() method returning a GL
1381     ///                       buffer object of source data
1382     ///
1383     /// @param srcDesc        vertex buffer descriptor for the input buffer
1384     ///
1385     /// @param dstBuffer      Output primvar buffer
1386     ///                       must have BindVBO() method returning a GL
1387     ///                       buffer object of destination data
1388     ///
1389     /// @param dstDesc        vertex buffer descriptor for the output buffer
1390     ///
1391     /// @param duBuffer       Output buffer derivative wrt u
1392     ///                       must have BindVBO() method returning a GL
1393     ///                       buffer object of destination data
1394     ///
1395     /// @param duDesc         vertex buffer descriptor for the duBuffer
1396     ///
1397     /// @param dvBuffer       Output buffer derivative wrt v
1398     ///                       must have BindVBO() method returning a GL
1399     ///                       buffer object of destination data
1400     ///
1401     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1402     ///
1403     /// @param duuBuffer      Output buffer 2nd derivative wrt u
1404     ///                       must have BindVBO() method returning a GL
1405     ///                       buffer object of destination data
1406     ///
1407     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
1408     ///
1409     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
1410     ///                       must have BindVBO() method returning a GL
1411     ///                       buffer object of destination data
1412     ///
1413     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
1414     ///
1415     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
1416     ///                       must have BindVBO() method returning a GL
1417     ///                       buffer object of destination data
1418     ///
1419     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
1420     ///
1421     /// @param numPatchCoords number of patchCoords.
1422     ///
1423     /// @param patchCoords    array of locations to be evaluated.
1424     ///                       must have BindVBO() method returning an
1425     ///                       array of PatchCoord struct in VBO.
1426     ///
1427     /// @param patchTable     GLPatchTable or equivalent
1428     ///
1429     /// @param instance       cached compiled instance. Clients are supposed to
1430     ///                       pre-compile an instance of this class and provide
1431     ///                       to this function. If it's null the kernel still
1432     ///                       compute by instantiating on-demand kernel although
1433     ///                       it may cause a performance problem.
1434     ///
1435     /// @param deviceContext  not used in the GLXFB evaluator
1436     ///
1437     template <typename SRC_BUFFER, typename DST_BUFFER,
1438               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1439     static bool EvalPatchesVarying(
1440         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1441         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1442         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1443         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1444         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
1445         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
1446         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
1447         int numPatchCoords,
1448         PATCHCOORD_BUFFER *patchCoords,
1449         PATCH_TABLE *patchTable,
1450         GLComputeEvaluator const *instance,
1451         void * deviceContext = NULL) {
1452 
1453         if (instance) {
1454             return instance->EvalPatchesVarying(
1455                                          srcBuffer, srcDesc,
1456                                          dstBuffer, dstDesc,
1457                                          duBuffer, duDesc,
1458                                          dvBuffer, dvDesc,
1459                                          duuBuffer, duuDesc,
1460                                          duvBuffer, duvDesc,
1461                                          dvvBuffer, dvvDesc,
1462                                          numPatchCoords, patchCoords,
1463                                          patchTable);
1464         } else {
1465             // Create an instance on demand (slow)
1466             (void)deviceContext;  // unused
1467             instance = Create(srcDesc, dstDesc,
1468                               duDesc, dvDesc,
1469                               duuDesc, duvDesc, dvvDesc);
1470             if (instance) {
1471                 bool r = instance->EvalPatchesVarying(
1472                                                srcBuffer, srcDesc,
1473                                                dstBuffer, dstDesc,
1474                                                duBuffer, duDesc,
1475                                                dvBuffer, dvDesc,
1476                                                duuBuffer, duuDesc,
1477                                                duvBuffer, duvDesc,
1478                                                dvvBuffer, dvvDesc,
1479                                                numPatchCoords, patchCoords,
1480                                                patchTable);
1481                 delete instance;
1482                 return r;
1483             }
1484             return false;
1485         }
1486     }
1487 
1488     /// \brief Generic limit eval function. This function has a same
1489     ///        signature as other device kernels have so that it can be called
1490     ///        in the same way.
1491     ///
1492     /// @param srcBuffer      Input primvar buffer.
1493     ///                       must have BindVBO() method returning a GL
1494     ///                       buffer object of source data
1495     ///
1496     /// @param srcDesc        vertex buffer descriptor for the input buffer
1497     ///
1498     /// @param dstBuffer      Output primvar buffer
1499     ///                       must have BindVBO() method returning a GL
1500     ///                       buffer object of destination data
1501     ///
1502     /// @param dstDesc        vertex buffer descriptor for the output buffer
1503     ///
1504     /// @param duBuffer       Output buffer derivative wrt u
1505     ///                       must have BindVBO() method returning a GL
1506     ///                       buffer object of destination data
1507     ///
1508     /// @param duDesc         vertex buffer descriptor for the duBuffer
1509     ///
1510     /// @param dvBuffer       Output buffer derivative wrt v
1511     ///                       must have BindVBO() method returning a GL
1512     ///                       buffer object of destination data
1513     ///
1514     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1515     ///
1516     /// @param duuBuffer      Output buffer 2nd derivative wrt u
1517     ///                       must have BindVBO() method returning a GL
1518     ///                       buffer object of destination data
1519     ///
1520     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
1521     ///
1522     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
1523     ///                       must have BindVBO() method returning a GL
1524     ///                       buffer object of destination data
1525     ///
1526     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
1527     ///
1528     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
1529     ///                       must have BindVBO() method returning a GL
1530     ///                       buffer object of destination data
1531     ///
1532     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
1533     ///
1534     /// @param numPatchCoords number of patchCoords.
1535     ///
1536     /// @param patchCoords    array of locations to be evaluated.
1537     ///                       must have BindVBO() method returning an
1538     ///                       array of PatchCoord struct in VBO.
1539     ///
1540     /// @param patchTable     GLPatchTable or equivalent
1541     ///
1542     template <typename SRC_BUFFER, typename DST_BUFFER,
1543               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
EvalPatchesVarying(SRC_BUFFER * srcBuffer,BufferDescriptor const & srcDesc,DST_BUFFER * dstBuffer,BufferDescriptor const & dstDesc,DST_BUFFER * duBuffer,BufferDescriptor const & duDesc,DST_BUFFER * dvBuffer,BufferDescriptor const & dvDesc,DST_BUFFER * duuBuffer,BufferDescriptor const & duuDesc,DST_BUFFER * duvBuffer,BufferDescriptor const & duvDesc,DST_BUFFER * dvvBuffer,BufferDescriptor const & dvvDesc,int numPatchCoords,PATCHCOORD_BUFFER * patchCoords,PATCH_TABLE * patchTable)1544     bool EvalPatchesVarying(
1545         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1546         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1547         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1548         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1549         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
1550         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
1551         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
1552         int numPatchCoords,
1553         PATCHCOORD_BUFFER *patchCoords,
1554         PATCH_TABLE *patchTable) const {
1555 
1556         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1557                            dstBuffer->BindVBO(), dstDesc,
1558                            duBuffer->BindVBO(), duDesc,
1559                            dvBuffer->BindVBO(), dvDesc,
1560                            duuBuffer->BindVBO(), duuDesc,
1561                            duvBuffer->BindVBO(), duvDesc,
1562                            dvvBuffer->BindVBO(), dvvDesc,
1563                            numPatchCoords,
1564                            patchCoords->BindVBO(),
1565                            patchTable->GetVaryingPatchArrays(),
1566                            patchTable->GetVaryingPatchIndexBuffer(),
1567                            patchTable->GetPatchParamBuffer());
1568     }
1569 
1570     /// \brief Generic limit eval function. This function has a same
1571     ///        signature as other device kernels have so that it can be called
1572     ///        in the same way.
1573     ///
1574     /// @param srcBuffer      Input primvar buffer.
1575     ///                       must have BindVBO() method returning a GL
1576     ///                       buffer object of source data
1577     ///
1578     /// @param srcDesc        vertex buffer descriptor for the input buffer
1579     ///
1580     /// @param dstBuffer      Output primvar buffer
1581     ///                       must have BindVBO() method returning a GL
1582     ///                       buffer object of destination data
1583     ///
1584     /// @param dstDesc        vertex buffer descriptor for the output buffer
1585     ///
1586     /// @param numPatchCoords number of patchCoords.
1587     ///
1588     /// @param patchCoords    array of locations to be evaluated.
1589     ///                       must have BindVBO() method returning an
1590     ///                       array of PatchCoord struct in VBO.
1591     ///
1592     /// @param patchTable     GLPatchTable or equivalent
1593     ///
1594     /// @param fvarChannel    face-varying channel
1595     ///
1596     /// @param instance       cached compiled instance. Clients are supposed to
1597     ///                       pre-compile an instance of this class and provide
1598     ///                       to this function. If it's null the kernel still
1599     ///                       compute by instantiating on-demand kernel although
1600     ///                       it may cause a performance problem.
1601     ///
1602     /// @param deviceContext  not used in the GLXFB evaluator
1603     ///
1604     template <typename SRC_BUFFER, typename DST_BUFFER,
1605               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1606     static bool EvalPatchesFaceVarying(
1607         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1608         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1609         int numPatchCoords,
1610         PATCHCOORD_BUFFER *patchCoords,
1611         PATCH_TABLE *patchTable,
1612         int fvarChannel,
1613         GLComputeEvaluator const *instance,
1614         void * deviceContext = NULL) {
1615 
1616         if (instance) {
1617             return instance->EvalPatchesFaceVarying(
1618                                          srcBuffer, srcDesc,
1619                                          dstBuffer, dstDesc,
1620                                          numPatchCoords, patchCoords,
1621                                          patchTable, fvarChannel);
1622         } else {
1623             // Create an instance on demand (slow)
1624             (void)deviceContext;  // unused
1625             instance = Create(srcDesc, dstDesc,
1626                               BufferDescriptor(),
1627                               BufferDescriptor());
1628             if (instance) {
1629                 bool r = instance->EvalPatchesFaceVarying(
1630                                                srcBuffer, srcDesc,
1631                                                dstBuffer, dstDesc,
1632                                                numPatchCoords, patchCoords,
1633                                                patchTable, fvarChannel);
1634                 delete instance;
1635                 return r;
1636             }
1637             return false;
1638         }
1639     }
1640 
1641     /// \brief Generic limit eval function. This function has a same
1642     ///        signature as other device kernels have so that it can be called
1643     ///        in the same way.
1644     ///
1645     /// @param srcBuffer      Input primvar buffer.
1646     ///                       must have BindVBO() method returning a GL
1647     ///                       buffer object of source data
1648     ///
1649     /// @param srcDesc        vertex buffer descriptor for the input buffer
1650     ///
1651     /// @param dstBuffer      Output primvar buffer
1652     ///                       must have BindVBO() method returning a GL
1653     ///                       buffer object of destination data
1654     ///
1655     /// @param dstDesc        vertex buffer descriptor for the output buffer
1656     ///
1657     /// @param numPatchCoords number of patchCoords.
1658     ///
1659     /// @param patchCoords    array of locations to be evaluated.
1660     ///                       must have BindVBO() method returning an
1661     ///                       array of PatchCoord struct in VBO.
1662     ///
1663     /// @param patchTable     GLPatchTable or equivalent
1664     ///
1665     /// @param fvarChannel    face-varying channel
1666     ///
1667     template <typename SRC_BUFFER, typename DST_BUFFER,
1668               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1669     bool EvalPatchesFaceVarying(
1670         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1671         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1672         int numPatchCoords,
1673         PATCHCOORD_BUFFER *patchCoords,
1674         PATCH_TABLE *patchTable,
1675         int fvarChannel = 0) const {
1676 
1677         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1678                            dstBuffer->BindVBO(), dstDesc,
1679                            0, BufferDescriptor(),
1680                            0, BufferDescriptor(),
1681                            numPatchCoords,
1682                            patchCoords->BindVBO(),
1683                            patchTable->GetFVarPatchArrays(fvarChannel),
1684                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1685                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
1686     }
1687 
1688     /// \brief Generic limit eval function. This function has a same
1689     ///        signature as other device kernels have so that it can be called
1690     ///        in the same way.
1691     ///
1692     /// @param srcBuffer      Input primvar buffer.
1693     ///                       must have BindVBO() method returning a GL
1694     ///                       buffer object of source data
1695     ///
1696     /// @param srcDesc        vertex buffer descriptor for the input buffer
1697     ///
1698     /// @param dstBuffer      Output primvar buffer
1699     ///                       must have BindVBO() method returning a GL
1700     ///                       buffer object of destination data
1701     ///
1702     /// @param dstDesc        vertex buffer descriptor for the output buffer
1703     ///
1704     /// @param duBuffer       Output buffer derivative wrt u
1705     ///                       must have BindVBO() method returning a GL
1706     ///                       buffer object of destination data
1707     ///
1708     /// @param duDesc         vertex buffer descriptor for the duBuffer
1709     ///
1710     /// @param dvBuffer       Output buffer derivative wrt v
1711     ///                       must have BindVBO() method returning a GL
1712     ///                       buffer object of destination data
1713     ///
1714     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1715     ///
1716     /// @param numPatchCoords number of patchCoords.
1717     ///
1718     /// @param patchCoords    array of locations to be evaluated.
1719     ///                       must have BindVBO() method returning an
1720     ///                       array of PatchCoord struct in VBO.
1721     ///
1722     /// @param patchTable     GLPatchTable or equivalent
1723     ///
1724     /// @param fvarChannel    face-varying channel
1725     ///
1726     /// @param instance       cached compiled instance. Clients are supposed to
1727     ///                       pre-compile an instance of this class and provide
1728     ///                       to this function. If it's null the kernel still
1729     ///                       compute by instantiating on-demand kernel although
1730     ///                       it may cause a performance problem.
1731     ///
1732     /// @param deviceContext  not used in the GLXFB evaluator
1733     ///
1734     template <typename SRC_BUFFER, typename DST_BUFFER,
1735               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1736     static bool EvalPatchesFaceVarying(
1737         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1738         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1739         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1740         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1741         int numPatchCoords,
1742         PATCHCOORD_BUFFER *patchCoords,
1743         PATCH_TABLE *patchTable,
1744         int fvarChannel,
1745         GLComputeEvaluator const *instance,
1746         void * deviceContext = NULL) {
1747 
1748         if (instance) {
1749             return instance->EvalPatchesFaceVarying(
1750                                          srcBuffer, srcDesc,
1751                                          dstBuffer, dstDesc,
1752                                          duBuffer, duDesc,
1753                                          dvBuffer, dvDesc,
1754                                          numPatchCoords, patchCoords,
1755                                          patchTable, fvarChannel);
1756         } else {
1757             // Create an instance on demand (slow)
1758             (void)deviceContext;  // unused
1759             instance = Create(srcDesc, dstDesc,
1760                               duDesc, dvDesc);
1761             if (instance) {
1762                 bool r = instance->EvalPatchesFaceVarying(
1763                                                srcBuffer, srcDesc,
1764                                                dstBuffer, dstDesc,
1765                                                duBuffer, duDesc,
1766                                                dvBuffer, dvDesc,
1767                                                numPatchCoords, patchCoords,
1768                                                patchTable, fvarChannel);
1769                 delete instance;
1770                 return r;
1771             }
1772             return false;
1773         }
1774     }
1775 
1776     /// \brief Generic limit eval function. This function has a same
1777     ///        signature as other device kernels have so that it can be called
1778     ///        in the same way.
1779     ///
1780     /// @param srcBuffer      Input primvar buffer.
1781     ///                       must have BindVBO() method returning a GL
1782     ///                       buffer object of source data
1783     ///
1784     /// @param srcDesc        vertex buffer descriptor for the input buffer
1785     ///
1786     /// @param dstBuffer      Output primvar buffer
1787     ///                       must have BindVBO() method returning a GL
1788     ///                       buffer object of destination data
1789     ///
1790     /// @param dstDesc        vertex buffer descriptor for the output buffer
1791     ///
1792     /// @param duBuffer       Output buffer derivative wrt u
1793     ///                       must have BindVBO() method returning a GL
1794     ///                       object of destination data
1795     ///
1796     /// @param duDesc         vertex buffer descriptor for the duBuffer
1797     ///
1798     /// @param dvBuffer       Output buffer derivative wrt v
1799     ///                       must have BindVBO() method returning a GL
1800     ///                       buffer object of destination data
1801     ///
1802     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1803     ///
1804     /// @param numPatchCoords number of patchCoords.
1805     ///
1806     /// @param patchCoords    array of locations to be evaluated.
1807     ///                       must have BindVBO() method returning an
1808     ///                       array of PatchCoord struct in VBO.
1809     ///
1810     /// @param patchTable     GLPatchTable or equivalent
1811     ///
1812     /// @param fvarChannel    face-varying channel
1813     ///
1814     template <typename SRC_BUFFER, typename DST_BUFFER,
1815               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1816     bool EvalPatchesFaceVarying(
1817         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1818         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1819         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1820         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1821         int numPatchCoords,
1822         PATCHCOORD_BUFFER *patchCoords,
1823         PATCH_TABLE *patchTable,
1824         int fvarChannel = 0) const {
1825 
1826         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
1827                            dstBuffer->BindVBO(), dstDesc,
1828                            duBuffer->BindVBO(), duDesc,
1829                            dvBuffer->BindVBO(), dvDesc,
1830                            numPatchCoords,
1831                            patchCoords->BindVBO(),
1832                            patchTable->GetFVarPatchArrays(fvarChannel),
1833                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1834                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
1835     }
1836 
1837     /// \brief Generic limit eval function. This function has a same
1838     ///        signature as other device kernels have so that it can be called
1839     ///        in the same way.
1840     ///
1841     /// @param srcBuffer      Input primvar buffer.
1842     ///                       must have BindVBO() method returning a GL
1843     ///                       buffer object of source data
1844     ///
1845     /// @param srcDesc        vertex buffer descriptor for the input buffer
1846     ///
1847     /// @param dstBuffer      Output primvar buffer
1848     ///                       must have BindVBO() method returning a GL
1849     ///                       buffer object of destination data
1850     ///
1851     /// @param dstDesc        vertex buffer descriptor for the output buffer
1852     ///
1853     /// @param duBuffer       Output buffer derivative wrt u
1854     ///                       must have BindVBO() method returning a GL
1855     ///                       buffer object of destination data
1856     ///
1857     /// @param duDesc         vertex buffer descriptor for the duBuffer
1858     ///
1859     /// @param dvBuffer       Output buffer derivative wrt v
1860     ///                       must have BindVBO() method returning a GL
1861     ///                       buffer object of destination data
1862     ///
1863     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1864     ///
1865     /// @param duuBuffer      Output buffer 2nd derivative wrt u
1866     ///                       must have BindVBO() method returning a GL
1867     ///                       buffer object of destination data
1868     ///
1869     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
1870     ///
1871     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
1872     ///                       must have BindVBO() method returning a GL
1873     ///                       buffer object of destination data
1874     ///
1875     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
1876     ///
1877     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
1878     ///                       must have BindVBO() method returning a GL
1879     ///                       buffer object of destination data
1880     ///
1881     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
1882     ///
1883     /// @param numPatchCoords number of patchCoords.
1884     ///
1885     /// @param patchCoords    array of locations to be evaluated.
1886     ///                       must have BindVBO() method returning an
1887     ///                       array of PatchCoord struct in VBO.
1888     ///
1889     /// @param patchTable     GLPatchTable or equivalent
1890     ///
1891     /// @param fvarChannel    face-varying channel
1892     ///
1893     /// @param instance       cached compiled instance. Clients are supposed to
1894     ///                       pre-compile an instance of this class and provide
1895     ///                       to this function. If it's null the kernel still
1896     ///                       compute by instantiating on-demand kernel although
1897     ///                       it may cause a performance problem.
1898     ///
1899     /// @param deviceContext  not used in the GLXFB evaluator
1900     ///
1901     template <typename SRC_BUFFER, typename DST_BUFFER,
1902               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
1903     static bool EvalPatchesFaceVarying(
1904         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
1905         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
1906         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
1907         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
1908         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
1909         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
1910         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
1911         int numPatchCoords,
1912         PATCHCOORD_BUFFER *patchCoords,
1913         PATCH_TABLE *patchTable,
1914         int fvarChannel,
1915         GLComputeEvaluator const *instance,
1916         void * deviceContext = NULL) {
1917 
1918         if (instance) {
1919             return instance->EvalPatchesFaceVarying(
1920                                          srcBuffer, srcDesc,
1921                                          dstBuffer, dstDesc,
1922                                          duBuffer, duDesc,
1923                                          dvBuffer, dvDesc,
1924                                          duuBuffer, duuDesc,
1925                                          duvBuffer, duvDesc,
1926                                          dvvBuffer, dvvDesc,
1927                                          numPatchCoords, patchCoords,
1928                                          patchTable, fvarChannel);
1929         } else {
1930             // Create an instance on demand (slow)
1931             (void)deviceContext;  // unused
1932             instance = Create(srcDesc, dstDesc,
1933                               duDesc, dvDesc,
1934                               duuDesc, duvDesc, dvvDesc);
1935             if (instance) {
1936                 bool r = instance->EvalPatchesFaceVarying(
1937                                                srcBuffer, srcDesc,
1938                                                dstBuffer, dstDesc,
1939                                                duBuffer, duDesc,
1940                                                dvBuffer, dvDesc,
1941                                                duuBuffer, duuDesc,
1942                                                duvBuffer, duvDesc,
1943                                                dvvBuffer, dvvDesc,
1944                                                numPatchCoords, patchCoords,
1945                                                patchTable, fvarChannel);
1946                 delete instance;
1947                 return r;
1948             }
1949             return false;
1950         }
1951     }
1952 
1953     /// \brief Generic limit eval function. This function has a same
1954     ///        signature as other device kernels have so that it can be called
1955     ///        in the same way.
1956     ///
1957     /// @param srcBuffer      Input primvar buffer.
1958     ///                       must have BindVBO() method returning a GL
1959     ///                       buffer object of source data
1960     ///
1961     /// @param srcDesc        vertex buffer descriptor for the input buffer
1962     ///
1963     /// @param dstBuffer      Output primvar buffer
1964     ///                       must have BindVBO() method returning a GL
1965     ///                       buffer object of destination data
1966     ///
1967     /// @param dstDesc        vertex buffer descriptor for the output buffer
1968     ///
1969     /// @param duBuffer       Output buffer derivative wrt u
1970     ///                       must have BindVBO() method returning a GL
1971     ///                       buffer object of destination data
1972     ///
1973     /// @param duDesc         vertex buffer descriptor for the duBuffer
1974     ///
1975     /// @param dvBuffer       Output buffer derivative wrt v
1976     ///                       must have BindVBO() method returning a GL
1977     ///                       buffer object of destination data
1978     ///
1979     /// @param dvDesc         vertex buffer descriptor for the dvBuffer
1980     ///
1981     /// @param duuBuffer      Output buffer 2nd derivative wrt u
1982     ///                       must have BindVBO() method returning a GL
1983     ///                       buffer object of destination data
1984     ///
1985     /// @param duuDesc        vertex buffer descriptor for the duuBuffer
1986     ///
1987     /// @param duvBuffer      Output buffer 2nd derivative wrt u and v
1988     ///                       must have BindVBO() method returning a GL
1989     ///                       buffer object of destination data
1990     ///
1991     /// @param duvDesc        vertex buffer descriptor for the duvBuffer
1992     ///
1993     /// @param dvvBuffer      Output buffer 2nd derivative wrt v
1994     ///                       must have BindVBO() method returning a GL
1995     ///                       buffer object of destination data
1996     ///
1997     /// @param dvvDesc        vertex buffer descriptor for the dvvBuffer
1998     ///
1999     /// @param numPatchCoords number of patchCoords.
2000     ///
2001     /// @param patchCoords    array of locations to be evaluated.
2002     ///                       must have BindVBO() method returning an
2003     ///                       array of PatchCoord struct in VBO.
2004     ///
2005     /// @param patchTable     GLPatchTable or equivalent
2006     ///
2007     /// @param fvarChannel    face-varying channel
2008     ///
2009     template <typename SRC_BUFFER, typename DST_BUFFER,
2010               typename PATCHCOORD_BUFFER, typename PATCH_TABLE>
2011     bool EvalPatchesFaceVarying(
2012         SRC_BUFFER *srcBuffer, BufferDescriptor const &srcDesc,
2013         DST_BUFFER *dstBuffer, BufferDescriptor const &dstDesc,
2014         DST_BUFFER *duBuffer,  BufferDescriptor const &duDesc,
2015         DST_BUFFER *dvBuffer,  BufferDescriptor const &dvDesc,
2016         DST_BUFFER *duuBuffer, BufferDescriptor const &duuDesc,
2017         DST_BUFFER *duvBuffer, BufferDescriptor const &duvDesc,
2018         DST_BUFFER *dvvBuffer, BufferDescriptor const &dvvDesc,
2019         int numPatchCoords,
2020         PATCHCOORD_BUFFER *patchCoords,
2021         PATCH_TABLE *patchTable,
2022         int fvarChannel = 0) const {
2023 
2024         return EvalPatches(srcBuffer->BindVBO(), srcDesc,
2025                            dstBuffer->BindVBO(), dstDesc,
2026                            duBuffer->BindVBO(), duDesc,
2027                            dvBuffer->BindVBO(), dvDesc,
2028                            duuBuffer->BindVBO(), duuDesc,
2029                            duvBuffer->BindVBO(), duvDesc,
2030                            dvvBuffer->BindVBO(), dvvDesc,
2031                            numPatchCoords,
2032                            patchCoords->BindVBO(),
2033                            patchTable->GetFVarPatchArrays(fvarChannel),
2034                            patchTable->GetFVarPatchIndexBuffer(fvarChannel),
2035                            patchTable->GetFVarPatchParamBuffer(fvarChannel));
2036     }
2037 
2038     /// ----------------------------------------------------------------------
2039     ///
2040     ///   Other methods
2041     ///
2042     /// ----------------------------------------------------------------------
2043 
2044     /// Configure GLSL kernel. A valid GL context must be made current before
2045     /// calling this function. Returns false if it fails to compile the kernel.
2046     bool Compile(BufferDescriptor const &srcDesc,
2047                  BufferDescriptor const &dstDesc,
2048                  BufferDescriptor const &duDesc = BufferDescriptor(),
2049                  BufferDescriptor const &dvDesc = BufferDescriptor(),
2050                  BufferDescriptor const &duuDesc = BufferDescriptor(),
2051                  BufferDescriptor const &duvDesc = BufferDescriptor(),
2052                  BufferDescriptor const &dvvDesc = BufferDescriptor());
2053 
2054     /// Wait the dispatched kernel finishes.
2055     static void Synchronize(void *deviceContext);
2056 
2057 private:
2058     struct _StencilKernel {
2059         _StencilKernel();
2060         ~_StencilKernel();
2061         bool Compile(BufferDescriptor const &srcDesc,
2062                      BufferDescriptor const &dstDesc,
2063                      BufferDescriptor const &duDesc,
2064                      BufferDescriptor const &dvDesc,
2065                      BufferDescriptor const &duuDesc,
2066                      BufferDescriptor const &duvDesc,
2067                      BufferDescriptor const &dvvDesc,
2068                      int workGroupSize);
2069         GLuint program;
2070         GLuint uniformStart;
2071         GLuint uniformEnd;
2072         GLuint uniformSrcOffset;
2073         GLuint uniformDstOffset;
2074         GLuint uniformDuDesc;
2075         GLuint uniformDvDesc;
2076         GLuint uniformDuuDesc;
2077         GLuint uniformDuvDesc;
2078         GLuint uniformDvvDesc;
2079     } _stencilKernel;
2080 
2081     struct _PatchKernel {
2082         _PatchKernel();
2083         ~_PatchKernel();
2084         bool Compile(BufferDescriptor const &srcDesc,
2085                      BufferDescriptor const &dstDesc,
2086                      BufferDescriptor const &duDesc,
2087                      BufferDescriptor const &dvDesc,
2088                      BufferDescriptor const &duuDesc,
2089                      BufferDescriptor const &duvDesc,
2090                      BufferDescriptor const &dvvDesc,
2091                      int workGroupSize);
2092         GLuint program;
2093         GLuint uniformSrcOffset;
2094         GLuint uniformDstOffset;
2095         GLuint uniformPatchArray;
2096         GLuint uniformDuDesc;
2097         GLuint uniformDvDesc;
2098         GLuint uniformDuuDesc;
2099         GLuint uniformDuvDesc;
2100         GLuint uniformDvvDesc;
2101     } _patchKernel;
2102 
2103     int _workGroupSize;
2104     GLuint _patchArraysSSBO;
2105 };
2106 
2107 }  // end namespace Osd
2108 
2109 }  // end namespace OPENSUBDIV_VERSION
2110 using namespace OPENSUBDIV_VERSION;
2111 
2112 }  // end namespace OpenSubdiv
2113 
2114 
2115 #endif  // OPENSUBDIV3_OSD_GL_COMPUTE_EVALUATOR_H
2116