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