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