Blender  V3.3
eval_output.h
Go to the documentation of this file.
1 // Copyright 2021 Blender Foundation. All rights reserved.
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software Foundation,
15 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 //
17 // Author: Sergey Sharybin
18 
19 #ifndef OPENSUBDIV_EVAL_OUTPUT_H_
20 #define OPENSUBDIV_EVAL_OUTPUT_H_
21 
22 #include <opensubdiv/osd/cpuPatchTable.h>
23 #include <opensubdiv/osd/glPatchTable.h>
24 #include <opensubdiv/osd/mesh.h>
25 #include <opensubdiv/osd/types.h>
26 
27 #include "internal/base/type.h"
29 
31 
32 using OpenSubdiv::Far::PatchTable;
33 using OpenSubdiv::Far::StencilTable;
34 using OpenSubdiv::Osd::BufferDescriptor;
35 using OpenSubdiv::Osd::CpuPatchTable;
36 using OpenSubdiv::Osd::GLPatchTable;
37 using OpenSubdiv::Osd::PatchCoord;
38 
39 namespace blender {
40 namespace opensubdiv {
41 
42 // Base class for the implementation of the evaluators.
44  public:
45  virtual ~EvalOutput() = default;
46 
47  virtual void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) = 0;
48 
49  virtual void updateData(const float *src, int start_vertex, int num_vertices) = 0;
50 
51  virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
52 
53  virtual void updateVertexData(const float *src, int start_vertex, int num_vertices) = 0;
54 
55  virtual void updateFaceVaryingData(const int face_varying_channel,
56  const float *src,
57  int start_vertex,
58  int num_vertices) = 0;
59 
60  virtual void refine() = 0;
61 
62  // NOTE: P must point to a memory of at least float[3]*num_patch_coords.
63  virtual void evalPatches(const PatchCoord *patch_coord,
64  const int num_patch_coords,
65  float *P) = 0;
66 
67  // NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
68  virtual void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
69  const int num_patch_coords,
70  float *P,
71  float *dPdu,
72  float *dPdv) = 0;
73 
74  // NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
75  virtual void evalPatchesVarying(const PatchCoord *patch_coord,
76  const int num_patch_coords,
77  float *varying) = 0;
78 
79  // NOTE: vertex_data must point to a memory of at least float*num_vertex_data.
80  virtual void evalPatchesVertexData(const PatchCoord *patch_coord,
81  const int num_patch_coords,
82  float *vertex_data) = 0;
83 
84  virtual void evalPatchesFaceVarying(const int face_varying_channel,
85  const PatchCoord *patch_coord,
86  const int num_patch_coords,
87  float face_varying[2]) = 0;
88 
89  // The following interfaces are dependant on the actual evaluator type (CPU, OpenGL, etc.) which
90  // have slightly different APIs to access patch arrays, as well as different types for their
91  // data structure. They need to be overridden in the specific instances of the EvalOutput derived
92  // classes if needed, while the interfaces above are overriden through VolatileEvalOutput.
93 
94  virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
95  {
96  }
97 
98  virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer * /*patch_index_buffer*/)
99  {
100  }
101 
102  virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer * /*patch_param_buffer*/)
103  {
104  }
105 
106  virtual void wrapSrcBuffer(OpenSubdiv_Buffer * /*src_buffer*/)
107  {
108  }
109 
110  virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer * /*src_buffer*/)
111  {
112  }
113 
114  virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/,
115  OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
116  {
117  }
118 
119  virtual void wrapFVarPatchIndexBuffer(const int /*face_varying_channel*/,
120  OpenSubdiv_Buffer * /*patch_index_buffer*/)
121  {
122  }
123 
124  virtual void wrapFVarPatchParamBuffer(const int /*face_varying_channel*/,
125  OpenSubdiv_Buffer * /*patch_param_buffer*/)
126  {
127  }
128 
129  virtual void wrapFVarSrcBuffer(const int /*face_varying_channel*/,
130  OpenSubdiv_Buffer * /*src_buffer*/)
131  {
132  }
133 
134  virtual bool hasVertexData() const
135  {
136  return false;
137  }
138 };
139 
140 namespace {
141 
142 // Buffer which implements API required by OpenSubdiv and uses an existing memory as an underlying
143 // storage.
144 template<typename T> class RawDataWrapperBuffer {
145  public:
146  RawDataWrapperBuffer(T *data) : data_(data)
147  {
148  }
149 
150  T *BindCpuBuffer()
151  {
152  return data_;
153  }
154 
155  int BindVBO()
156  {
157  return 0;
158  }
159 
160  // TODO(sergey): Support UpdateData().
161 
162  protected:
164 };
165 
166 template<typename T> class RawDataWrapperVertexBuffer : public RawDataWrapperBuffer<T> {
167  public:
168  RawDataWrapperVertexBuffer(T *data, int num_vertices)
169  : RawDataWrapperBuffer<T>(data), num_vertices_(num_vertices)
170  {
171  }
172 
173  int GetNumVertices()
174  {
175  return num_vertices_;
176  }
177 
178  protected:
180 };
181 
182 class ConstPatchCoordWrapperBuffer : public RawDataWrapperVertexBuffer<const PatchCoord> {
183  public:
184  ConstPatchCoordWrapperBuffer(const PatchCoord *data, int num_vertices)
185  : RawDataWrapperVertexBuffer(data, num_vertices)
186  {
187  }
188 };
189 } // namespace
190 
191 // Discriminators used in FaceVaryingVolatileEval in order to detect whether we are using adaptive
192 // patches as the CPU and OpenGL PatchTable have different APIs.
193 bool is_adaptive(CpuPatchTable *patch_table);
194 bool is_adaptive(GLPatchTable *patch_table);
195 
196 template<typename EVAL_VERTEX_BUFFER,
197  typename STENCIL_TABLE,
198  typename PATCH_TABLE,
199  typename EVALUATOR,
200  typename DEVICE_CONTEXT = void>
202  public:
203  typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
204 
205  FaceVaryingVolatileEval(int face_varying_channel,
206  const StencilTable *face_varying_stencils,
207  int face_varying_width,
208  PATCH_TABLE *patch_table,
209  EvaluatorCache *evaluator_cache = NULL,
210  DEVICE_CONTEXT *device_context = NULL)
211  : face_varying_channel_(face_varying_channel),
212  src_face_varying_desc_(0, face_varying_width, face_varying_width),
213  patch_table_(patch_table),
214  evaluator_cache_(evaluator_cache),
215  device_context_(device_context)
216  {
217  using OpenSubdiv::Osd::convertToCompatibleStencilTable;
218  num_coarse_face_varying_vertices_ = face_varying_stencils->GetNumControlVertices();
219  const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
220  face_varying_stencils->GetNumStencils();
221  src_face_varying_data_ = EVAL_VERTEX_BUFFER::Create(
222  2, num_total_face_varying_vertices, device_context);
223  face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(face_varying_stencils,
225  }
226 
228  {
229  delete src_face_varying_data_;
230  delete face_varying_stencils_;
231  }
232 
233  void updateData(const float *src, int start_vertex, int num_vertices)
234  {
235  src_face_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
236  }
237 
238  void refine()
239  {
240  BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
241  dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
242  src_face_varying_desc_.stride;
243  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
244  evaluator_cache_, src_face_varying_desc_, dst_face_varying_desc, device_context_);
245  // in and out points to same buffer so output is put directly after coarse vertices, needed in
246  // adaptive mode
247  EVALUATOR::EvalStencils(src_face_varying_data_,
250  dst_face_varying_desc,
252  eval_instance,
254  }
255 
256  // NOTE: face_varying must point to a memory of at least float[2]*num_patch_coords.
257  void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
258  {
259  RawDataWrapperBuffer<float> face_varying_data(face_varying);
260  BufferDescriptor face_varying_desc(0, 2, 2);
261  ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
262  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
264 
265  BufferDescriptor src_desc = get_src_varying_desc();
266 
267  EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_,
268  src_desc,
269  &face_varying_data,
270  face_varying_desc,
271  patch_coord_buffer.GetNumVertices(),
272  &patch_coord_buffer,
273  patch_table_,
275  eval_instance,
277  }
278 
279  EVAL_VERTEX_BUFFER *getSrcBuffer() const
280  {
281  return src_face_varying_data_;
282  }
283 
285  {
286  BufferDescriptor src_desc = get_src_varying_desc();
287  return src_desc.offset;
288  }
289 
290  PATCH_TABLE *getPatchTable() const
291  {
292  return patch_table_;
293  }
294 
295  private:
296  BufferDescriptor get_src_varying_desc() const
297  {
298  // src_face_varying_data_ always contains coarse vertices at the beginning.
299  // In adaptive mode they are followed by number of blocks for intermediate
300  // subdivision levels, and this is what OSD expects in this mode.
301  // In non-adaptive mode (generateIntermediateLevels == false),
302  // they are followed by max subdivision level, but they break interpolation as OSD
303  // expects only one subd level in this buffer.
304  // So in non-adaptive mode we put offset into buffer descriptor to skip over coarse vertices.
305  BufferDescriptor src_desc = src_face_varying_desc_;
306  if (!is_adaptive(patch_table_)) {
307  src_desc.offset += num_coarse_face_varying_vertices_ * src_face_varying_desc_.stride;
308  }
309  return src_desc;
310  }
311 
312  protected:
314 
315  BufferDescriptor src_face_varying_desc_;
316 
318  EVAL_VERTEX_BUFFER *src_face_varying_data_;
319  const STENCIL_TABLE *face_varying_stencils_;
320 
321  // NOTE: We reference this, do not own it.
322  PATCH_TABLE *patch_table_;
323 
325  DEVICE_CONTEXT *device_context_;
326 };
327 
328 // Volatile evaluator which can be used from threads.
329 //
330 // TODO(sergey): Make it possible to evaluate coordinates in chunks.
331 // TODO(sergey): Make it possible to evaluate multiple face varying layers.
332 // (or maybe, it's cheap to create new evaluator for existing
333 // topology to evaluate all needed face varying layers?)
334 template<typename SRC_VERTEX_BUFFER,
335  typename EVAL_VERTEX_BUFFER,
336  typename STENCIL_TABLE,
337  typename PATCH_TABLE,
338  typename EVALUATOR,
339  typename DEVICE_CONTEXT = void>
341  public:
342  typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
343  typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
344  STENCIL_TABLE,
345  PATCH_TABLE,
346  EVALUATOR,
347  DEVICE_CONTEXT>
349 
350  VolatileEvalOutput(const StencilTable *vertex_stencils,
351  const StencilTable *varying_stencils,
352  const vector<const StencilTable *> &all_face_varying_stencils,
353  const int face_varying_width,
354  const PatchTable *patch_table,
355  EvaluatorCache *evaluator_cache = NULL,
356  DEVICE_CONTEXT *device_context = NULL)
357  : src_vertex_data_(NULL),
358  src_desc_(0, 3, 3),
359  src_varying_desc_(0, 3, 3),
360  src_vertex_data_desc_(0, 0, 0),
361  face_varying_width_(face_varying_width),
362  evaluator_cache_(evaluator_cache),
363  device_context_(device_context)
364  {
365  // Total number of vertices = coarse points + refined points + local points.
366  int num_total_vertices = vertex_stencils->GetNumControlVertices() +
367  vertex_stencils->GetNumStencils();
368  num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
369  using OpenSubdiv::Osd::convertToCompatibleStencilTable;
370  src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
371  src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
372  patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
373  vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
374  device_context_);
375  varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
376  device_context_);
377 
378  // Create evaluators for every face varying channel.
379  face_varying_evaluators_.reserve(all_face_varying_stencils.size());
380  int face_varying_channel = 0;
381  for (const StencilTable *face_varying_stencils : all_face_varying_stencils) {
382  face_varying_evaluators_.push_back(new FaceVaryingEval(face_varying_channel,
383  face_varying_stencils,
384  face_varying_width,
385  patch_table_,
386  evaluator_cache_,
387  device_context_));
388  ++face_varying_channel;
389  }
390  }
391 
393  {
394  delete src_data_;
395  delete src_varying_data_;
396  delete src_vertex_data_;
397  delete patch_table_;
398  delete vertex_stencils_;
399  delete varying_stencils_;
400  for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
401  delete face_varying_evaluator;
402  }
403  }
404 
405  void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) override
406  {
407  // Optionally allocate additional data to be subdivided like vertex coordinates.
408  if (settings->num_vertex_data != src_vertex_data_desc_.length) {
409  delete src_vertex_data_;
410  if (settings->num_vertex_data > 0) {
411  src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
412  settings->num_vertex_data, src_data_->GetNumVertices(), device_context_);
413  }
414  else {
415  src_vertex_data_ = NULL;
416  }
417  src_vertex_data_desc_ = BufferDescriptor(
418  0, settings->num_vertex_data, settings->num_vertex_data);
419  }
420  }
421 
422  // TODO(sergey): Implement binding API.
423 
424  void updateData(const float *src, int start_vertex, int num_vertices) override
425  {
426  src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
427  }
428 
429  void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
430  {
431  src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
432  }
433 
434  void updateVertexData(const float *src, int start_vertex, int num_vertices) override
435  {
436  src_vertex_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
437  }
438 
439  void updateFaceVaryingData(const int face_varying_channel,
440  const float *src,
441  int start_vertex,
442  int num_vertices) override
443  {
444  assert(face_varying_channel >= 0);
445  assert(face_varying_channel < face_varying_evaluators_.size());
446  face_varying_evaluators_[face_varying_channel]->updateData(src, start_vertex, num_vertices);
447  }
448 
449  bool hasVaryingData() const
450  {
451  // return varying_stencils_ != NULL;
452  // TODO(sergey): Check this based on actual topology.
453  return false;
454  }
455 
456  bool hasFaceVaryingData() const
457  {
458  return face_varying_evaluators_.size() != 0;
459  }
460 
461  bool hasVertexData() const override
462  {
463  return src_vertex_data_ != nullptr;
464  }
465 
466  void refine() override
467  {
468  // Evaluate vertex positions.
469  BufferDescriptor dst_desc = src_desc_;
470  dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
471  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
472  evaluator_cache_, src_desc_, dst_desc, device_context_);
473  EVALUATOR::EvalStencils(src_data_,
474  src_desc_,
475  src_data_,
476  dst_desc,
477  vertex_stencils_,
478  eval_instance,
479  device_context_);
480 
481  // Evaluate smoothly interpolated vertex data.
482  if (src_vertex_data_) {
483  BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_;
484  dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride;
485  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
486  evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_);
487  EVALUATOR::EvalStencils(src_vertex_data_,
488  src_vertex_data_desc_,
489  src_vertex_data_,
490  dst_vertex_data_desc,
491  vertex_stencils_,
492  eval_instance,
493  device_context_);
494  }
495 
496  // Evaluate varying data.
497  if (hasVaryingData()) {
498  BufferDescriptor dst_varying_desc = src_varying_desc_;
499  dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
500  eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
501  evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
502  EVALUATOR::EvalStencils(src_varying_data_,
503  src_varying_desc_,
504  src_varying_data_,
505  dst_varying_desc,
506  varying_stencils_,
507  eval_instance,
508  device_context_);
509  }
510  // Evaluate face-varying data.
511  if (hasFaceVaryingData()) {
512  for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
513  face_varying_evaluator->refine();
514  }
515  }
516  }
517 
518  // NOTE: P must point to a memory of at least float[3]*num_patch_coords.
519  void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P) override
520  {
521  RawDataWrapperBuffer<float> P_data(P);
522  // TODO(sergey): Support interleaved vertex-varying data.
523  BufferDescriptor P_desc(0, 3, 3);
524  ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
525  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
526  evaluator_cache_, src_desc_, P_desc, device_context_);
527  EVALUATOR::EvalPatches(src_data_,
528  src_desc_,
529  &P_data,
530  P_desc,
531  patch_coord_buffer.GetNumVertices(),
532  &patch_coord_buffer,
533  patch_table_,
534  eval_instance,
535  device_context_);
536  }
537 
538  // NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
539  void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
540  const int num_patch_coords,
541  float *P,
542  float *dPdu,
543  float *dPdv) override
544  {
545  assert(dPdu);
546  assert(dPdv);
547  RawDataWrapperBuffer<float> P_data(P);
548  RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
549  // TODO(sergey): Support interleaved vertex-varying data.
550  BufferDescriptor P_desc(0, 3, 3);
551  BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
552  ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
553  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
554  evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_);
555  EVALUATOR::EvalPatches(src_data_,
556  src_desc_,
557  &P_data,
558  P_desc,
559  &dPdu_data,
560  dpDu_desc,
561  &dPdv_data,
562  pPdv_desc,
563  patch_coord_buffer.GetNumVertices(),
564  &patch_coord_buffer,
565  patch_table_,
566  eval_instance,
567  device_context_);
568  }
569 
570  // NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
571  void evalPatchesVarying(const PatchCoord *patch_coord,
572  const int num_patch_coords,
573  float *varying) override
574  {
575  RawDataWrapperBuffer<float> varying_data(varying);
576  BufferDescriptor varying_desc(3, 3, 6);
577  ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
578  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
579  evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
580  EVALUATOR::EvalPatchesVarying(src_varying_data_,
581  src_varying_desc_,
582  &varying_data,
583  varying_desc,
584  patch_coord_buffer.GetNumVertices(),
585  &patch_coord_buffer,
586  patch_table_,
587  eval_instance,
588  device_context_);
589  }
590 
591  // NOTE: data must point to a memory of at least float*num_vertex_data.
592  void evalPatchesVertexData(const PatchCoord *patch_coord,
593  const int num_patch_coords,
594  float *data) override
595  {
596  RawDataWrapperBuffer<float> vertex_data(data);
597  BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length);
598  ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
599  const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
600  evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_);
601  EVALUATOR::EvalPatches(src_vertex_data_,
602  src_vertex_data_desc_,
603  &vertex_data,
604  vertex_desc,
605  patch_coord_buffer.GetNumVertices(),
606  &patch_coord_buffer,
607  patch_table_,
608  eval_instance,
609  device_context_);
610  }
611 
612  void evalPatchesFaceVarying(const int face_varying_channel,
613  const PatchCoord *patch_coord,
614  const int num_patch_coords,
615  float face_varying[2]) override
616  {
617  assert(face_varying_channel >= 0);
618  assert(face_varying_channel < face_varying_evaluators_.size());
619  face_varying_evaluators_[face_varying_channel]->evalPatches(
620  patch_coord, num_patch_coords, face_varying);
621  }
622 
623  SRC_VERTEX_BUFFER *getSrcBuffer() const
624  {
625  return src_data_;
626  }
627 
628  SRC_VERTEX_BUFFER *getSrcVertexDataBuffer() const
629  {
630  return src_vertex_data_;
631  }
632 
633  PATCH_TABLE *getPatchTable() const
634  {
635  return patch_table_;
636  }
637 
638  SRC_VERTEX_BUFFER *getFVarSrcBuffer(const int face_varying_channel) const
639  {
640  return face_varying_evaluators_[face_varying_channel]->getSrcBuffer();
641  }
642 
643  int getFVarSrcBufferOffset(const int face_varying_channel) const
644  {
645  return face_varying_evaluators_[face_varying_channel]->getFVarSrcBufferOffset();
646  }
647 
648  PATCH_TABLE *getFVarPatchTable(const int face_varying_channel) const
649  {
650  return face_varying_evaluators_[face_varying_channel]->getPatchTable();
651  }
652 
653  private:
654  SRC_VERTEX_BUFFER *src_data_;
655  SRC_VERTEX_BUFFER *src_varying_data_;
656  SRC_VERTEX_BUFFER *src_vertex_data_;
657  PATCH_TABLE *patch_table_;
658  BufferDescriptor src_desc_;
659  BufferDescriptor src_varying_desc_;
660  BufferDescriptor src_vertex_data_desc_;
661 
662  int num_coarse_vertices_;
663 
664  const STENCIL_TABLE *vertex_stencils_;
665  const STENCIL_TABLE *varying_stencils_;
666 
667  int face_varying_width_;
668  vector<FaceVaryingEval *> face_varying_evaluators_;
669 
670  EvaluatorCache *evaluator_cache_;
671  DEVICE_CONTEXT *device_context_;
672 };
673 
674 } // namespace opensubdiv
675 } // namespace blender
676 
677 #endif // OPENSUBDIV_EVAL_OUTPUT_H_
virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:98
virtual void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P)=0
virtual void fillFVarPatchArraysBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:114
virtual void evalPatchesVertexData(const PatchCoord *patch_coord, const int num_patch_coords, float *vertex_data)=0
virtual void evalPatchesWithDerivatives(const PatchCoord *patch_coord, const int num_patch_coords, float *P, float *dPdu, float *dPdv)=0
virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:102
virtual void wrapFVarPatchParamBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:124
virtual void wrapFVarPatchIndexBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:119
virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:110
virtual void updateVertexData(const float *src, int start_vertex, int num_vertices)=0
virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:94
virtual void updateData(const float *src, int start_vertex, int num_vertices)=0
virtual void evalPatchesVarying(const PatchCoord *patch_coord, const int num_patch_coords, float *varying)=0
virtual void updateSettings(const OpenSubdiv_EvaluatorSettings *settings)=0
virtual void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, int num_vertices)=0
virtual void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, float face_varying[2])=0
virtual void wrapFVarSrcBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:129
virtual void wrapSrcBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:106
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices)=0
void updateData(const float *src, int start_vertex, int num_vertices)
Definition: eval_output.h:233
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
Definition: eval_output.h:203
FaceVaryingVolatileEval(int face_varying_channel, const StencilTable *face_varying_stencils, int face_varying_width, PATCH_TABLE *patch_table, EvaluatorCache *evaluator_cache=NULL, DEVICE_CONTEXT *device_context=NULL)
Definition: eval_output.h:205
EVAL_VERTEX_BUFFER * getSrcBuffer() const
Definition: eval_output.h:279
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
Definition: eval_output.h:257
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
Definition: eval_output.h:342
PATCH_TABLE * getFVarPatchTable(const int face_varying_channel) const
Definition: eval_output.h:648
SRC_VERTEX_BUFFER * getSrcVertexDataBuffer() const
Definition: eval_output.h:628
void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
Definition: eval_output.h:429
SRC_VERTEX_BUFFER * getFVarSrcBuffer(const int face_varying_channel) const
Definition: eval_output.h:638
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P) override
Definition: eval_output.h:519
FaceVaryingVolatileEval< EVAL_VERTEX_BUFFER, STENCIL_TABLE, PATCH_TABLE, EVALUATOR, DEVICE_CONTEXT > FaceVaryingEval
Definition: eval_output.h:348
void updateVertexData(const float *src, int start_vertex, int num_vertices) override
Definition: eval_output.h:434
VolatileEvalOutput(const StencilTable *vertex_stencils, const StencilTable *varying_stencils, const vector< const StencilTable * > &all_face_varying_stencils, const int face_varying_width, const PatchTable *patch_table, EvaluatorCache *evaluator_cache=NULL, DEVICE_CONTEXT *device_context=NULL)
Definition: eval_output.h:350
int getFVarSrcBufferOffset(const int face_varying_channel) const
Definition: eval_output.h:643
void evalPatchesVarying(const PatchCoord *patch_coord, const int num_patch_coords, float *varying) override
Definition: eval_output.h:571
void evalPatchesVertexData(const PatchCoord *patch_coord, const int num_patch_coords, float *data) override
Definition: eval_output.h:592
SRC_VERTEX_BUFFER * getSrcBuffer() const
Definition: eval_output.h:623
void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, int num_vertices) override
Definition: eval_output.h:439
void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) override
Definition: eval_output.h:405
void evalPatchesWithDerivatives(const PatchCoord *patch_coord, const int num_patch_coords, float *P, float *dPdu, float *dPdv) override
Definition: eval_output.h:539
void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, float face_varying[2]) override
Definition: eval_output.h:612
void updateData(const float *src, int start_vertex, int num_vertices) override
Definition: eval_output.h:424
SyclQueue void void * src
int num_vertices_
Definition: eval_output.h:179
T * data_
Definition: eval_output.h:163
static float P(float k)
Definition: math_interp.c:25
#define T
bool is_adaptive(CpuPatchTable *patch_table)
Definition: eval_output.cc:24