Blender V5.0
gpu_compute_evaluator.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2015 Pixar
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#ifndef OPENSUBDIV_GPU_COMPUTE_EVALUATOR_H_
6#define OPENSUBDIV_GPU_COMPUTE_EVALUATOR_H_
7
8#include <opensubdiv/osd/bufferDescriptor.h>
9#include <opensubdiv/osd/types.h>
10#include <opensubdiv/version.h>
11
12#include "GPU_storage_buffer.hh"
13
15class LimitStencilTable;
16class StencilTable;
17} // namespace OpenSubdiv::OPENSUBDIV_VERSION::Far
18 // namespace OPENSUBDIV_VERSION
19
20namespace blender::opensubdiv {
21
29 public:
30 static GPUStencilTableSSBO *Create(OpenSubdiv::Far::StencilTable const *stencilTable,
31 void *deviceContext = nullptr)
32 {
33 (void)deviceContext; // unused
34 return new GPUStencilTableSSBO(stencilTable);
35 }
36 static GPUStencilTableSSBO *Create(OpenSubdiv::Far::LimitStencilTable const *limitStencilTable,
37 void *deviceContext = nullptr)
38 {
39 (void)deviceContext; // unused
40 return new GPUStencilTableSSBO(limitStencilTable);
41 }
42
43 explicit GPUStencilTableSSBO(OpenSubdiv::Far::StencilTable const *stencilTable);
44 explicit GPUStencilTableSSBO(OpenSubdiv::Far::LimitStencilTable const *limitStencilTable);
46
47 // interfaces needed for GLSLComputeKernel
49 {
50 return sizes_buf;
51 }
53 {
54 return offsets_buf;
55 }
57 {
58 return indices_buf;
59 }
61 {
62 return weights_buf;
63 }
65 {
66 return du_weights_buf;
67 }
69 {
70 return dv_weights_buf;
71 }
73 {
74 return duu_weights_buf;
75 }
77 {
78 return duv_weights_buf;
79 }
81 {
82 return dvv_weights_buf;
83 }
84 int GetNumStencils() const
85 {
86 return _numStencils;
87 }
88
89 private:
90 gpu::StorageBuf *sizes_buf = nullptr;
91 gpu::StorageBuf *offsets_buf = nullptr;
92 gpu::StorageBuf *indices_buf = nullptr;
93 gpu::StorageBuf *weights_buf = nullptr;
94 gpu::StorageBuf *du_weights_buf = nullptr;
95 gpu::StorageBuf *dv_weights_buf = nullptr;
96 gpu::StorageBuf *duu_weights_buf = nullptr;
97 gpu::StorageBuf *duv_weights_buf = nullptr;
98 gpu::StorageBuf *dvv_weights_buf = nullptr;
99 int _numStencils;
100};
101
102// ---------------------------------------------------------------------------
103
105 public:
106 using Instantiatable = bool;
111 static GPUComputeEvaluator *Create(OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
112 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
113 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
114 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
115 OpenSubdiv::Osd::BufferDescriptor const & /*duuDesc*/,
116 OpenSubdiv::Osd::BufferDescriptor const & /*duvDesc*/,
117 OpenSubdiv::Osd::BufferDescriptor const & /*dvvDesc*/,
118 void *deviceContext = nullptr)
119 {
120 return Create(srcDesc, dstDesc, duDesc, dvDesc, deviceContext);
121 }
122
123 static GPUComputeEvaluator *Create(OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
124 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
125 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
126 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
127 void * /*deviceContext*/ = nullptr)
128 {
130 if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc)) {
131 return instance;
132 }
133 delete instance;
134 return nullptr;
135 }
136
139
142
148
176 template<typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
177 static bool EvalStencils(SRC_BUFFER *srcBuffer,
178 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
179 DST_BUFFER *dstBuffer,
180 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
181 STENCIL_TABLE const *stencilTable,
182 GPUComputeEvaluator *instance,
183 void *deviceContext = nullptr)
184 {
185
186 if (instance) {
187 return instance->EvalStencils(srcBuffer, srcDesc, dstBuffer, dstDesc, stencilTable);
188 }
189
190 // Create an instance on demand (slow)
191 (void)deviceContext; // unused
192 instance = Create(srcDesc,
193 dstDesc,
194 OpenSubdiv::Osd::BufferDescriptor(),
195 OpenSubdiv::Osd::BufferDescriptor());
196 if (instance) {
197 bool r = instance->EvalStencils(srcBuffer, srcDesc, dstBuffer, dstDesc, stencilTable);
198 delete instance;
199 return r;
200 }
201 return false;
202 }
203
243 template<typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
244 static bool EvalStencils(SRC_BUFFER *srcBuffer,
245 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
246 DST_BUFFER *dstBuffer,
247 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
248 DST_BUFFER *duBuffer,
249 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
250 DST_BUFFER *dvBuffer,
251 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
252 STENCIL_TABLE const *stencilTable,
253 GPUComputeEvaluator *instance,
254 void *deviceContext = nullptr)
255 {
256
257 if (instance) {
258 return instance->EvalStencils(srcBuffer,
259 srcDesc,
260 dstBuffer,
261 dstDesc,
262 duBuffer,
263 duDesc,
264 dvBuffer,
265 dvDesc,
266 stencilTable);
267 }
268
269 // Create an instance on demand (slow)
270 (void)deviceContext; // unused
271 instance = Create(srcDesc, dstDesc, duDesc, dvDesc);
272 if (instance) {
273 bool r = instance->EvalStencils(srcBuffer,
274 srcDesc,
275 dstBuffer,
276 dstDesc,
277 duBuffer,
278 duDesc,
279 dvBuffer,
280 dvDesc,
281 stencilTable);
282 delete instance;
283 return r;
284 }
285 return false;
286 }
287
305 template<typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
306 bool EvalStencils(SRC_BUFFER *srcBuffer,
307 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
308 DST_BUFFER *dstBuffer,
309 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
310 STENCIL_TABLE const *stencilTable) const
311 {
312 return EvalStencils(srcBuffer->get_vertex_buffer(),
313 srcDesc,
314 dstBuffer->get_vertex_buffer(),
315 dstDesc,
316 nullptr,
317 OpenSubdiv::Osd::BufferDescriptor(),
318 nullptr,
319 OpenSubdiv::Osd::BufferDescriptor(),
320 stencilTable->GetSizesBuffer(),
321 stencilTable->GetOffsetsBuffer(),
322 stencilTable->GetIndicesBuffer(),
323 stencilTable->GetWeightsBuffer(),
324 0,
325 0,
326 /* start = */ 0,
327 /* end = */ stencilTable->GetNumStencils());
328 }
329
359 template<typename SRC_BUFFER, typename DST_BUFFER, typename STENCIL_TABLE>
360 bool EvalStencils(SRC_BUFFER *srcBuffer,
361 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
362 DST_BUFFER *dstBuffer,
363 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
364 DST_BUFFER *duBuffer,
365 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
366 DST_BUFFER *dvBuffer,
367 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
368 STENCIL_TABLE const *stencilTable) const
369 {
370 return EvalStencils(srcBuffer->get_vertex_buffer(),
371 srcDesc,
372 dstBuffer->get_vertex_buffer(),
373 dstDesc,
374 duBuffer->get_vertex_buffer(),
375 duDesc,
376 dvBuffer->get_vertex_buffer(),
377 dvDesc,
378 stencilTable->GetSizesBuffer(),
379 stencilTable->GetOffsetsBuffer(),
380 stencilTable->GetIndicesBuffer(),
381 stencilTable->GetWeightsBuffer(),
382 stencilTable->GetDuWeightsBuffer(),
383 stencilTable->GetDvWeightsBuffer(),
384 /* start = */ 0,
385 /* end = */ stencilTable->GetNumStencils());
386 }
387
423 bool EvalStencils(gpu::VertBuf *srcBuffer,
424 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
425 gpu::VertBuf *dstBuffer,
426 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
427 gpu::VertBuf *duBuffer,
428 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
429 gpu::VertBuf *dvBuffer,
430 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
431 gpu::StorageBuf *sizesBuffer,
432 gpu::StorageBuf *offsetsBuffer,
433 gpu::StorageBuf *indicesBuffer,
434 gpu::StorageBuf *weightsBuffer,
435 gpu::StorageBuf *duWeightsBuffer,
436 gpu::StorageBuf *dvWeightsBuffer,
437 int start,
438 int end) const;
439
445
478 template<typename SRC_BUFFER,
479 typename DST_BUFFER,
480 typename PATCHCOORD_BUFFER,
481 typename PATCH_TABLE>
482 static bool EvalPatches(SRC_BUFFER *srcBuffer,
483 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
484 DST_BUFFER *dstBuffer,
485 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
486 int numPatchCoords,
487 PATCHCOORD_BUFFER *patchCoords,
488 PATCH_TABLE *patchTable,
489 GPUComputeEvaluator *instance,
490 void *deviceContext = nullptr)
491 {
492
493 if (instance) {
494 return instance->EvalPatches(
495 srcBuffer, srcDesc, dstBuffer, dstDesc, numPatchCoords, patchCoords, patchTable);
496 }
497 // Create an instance on demand (slow)
498 (void)deviceContext; // unused
499 instance = Create(srcDesc,
500 dstDesc,
501 OpenSubdiv::Osd::BufferDescriptor(),
502 OpenSubdiv::Osd::BufferDescriptor());
503 if (instance) {
504 bool r = instance->EvalPatches(
505 srcBuffer, srcDesc, dstBuffer, dstDesc, numPatchCoords, patchCoords, patchTable);
506 delete instance;
507 return r;
508 }
509 return false;
510 }
511
556 template<typename SRC_BUFFER,
557 typename DST_BUFFER,
558 typename PATCHCOORD_BUFFER,
559 typename PATCH_TABLE>
560 static bool EvalPatches(SRC_BUFFER *srcBuffer,
561 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
562 DST_BUFFER *dstBuffer,
563 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
564 DST_BUFFER *duBuffer,
565 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
566 DST_BUFFER *dvBuffer,
567 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
568 int numPatchCoords,
569 PATCHCOORD_BUFFER *patchCoords,
570 PATCH_TABLE *patchTable,
571 GPUComputeEvaluator *instance,
572 void *deviceContext = nullptr)
573 {
574 if (instance) {
575 return instance->EvalPatches(srcBuffer,
576 srcDesc,
577 dstBuffer,
578 dstDesc,
579 duBuffer,
580 duDesc,
581 dvBuffer,
582 dvDesc,
583 numPatchCoords,
584 patchCoords,
585 patchTable);
586 }
587
588 // Create an instance on demand (slow)
589 (void)deviceContext; // unused
590 instance = Create(srcDesc, dstDesc, duDesc, dvDesc);
591 if (instance) {
592 bool r = instance->EvalPatches(srcBuffer,
593 srcDesc,
594 dstBuffer,
595 dstDesc,
596 duBuffer,
597 duDesc,
598 dvBuffer,
599 dvDesc,
600 numPatchCoords,
601 patchCoords,
602 patchTable);
603 delete instance;
604 return r;
605 }
606 return false;
607 }
608
633 template<typename SRC_BUFFER,
634 typename DST_BUFFER,
635 typename PATCHCOORD_BUFFER,
636 typename PATCH_TABLE>
637 bool EvalPatches(SRC_BUFFER *srcBuffer,
638 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
639 DST_BUFFER *dstBuffer,
640 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
641 int numPatchCoords,
642 PATCHCOORD_BUFFER *patchCoords,
643 PATCH_TABLE *patchTable)
644 {
645
646 return EvalPatches(srcBuffer->get_vertex_buffer(),
647 srcDesc,
648 dstBuffer->get_vertex_buffer(),
649 dstDesc,
650 nullptr,
651 OpenSubdiv::Osd::BufferDescriptor(),
652 nullptr,
653 OpenSubdiv::Osd::BufferDescriptor(),
654 numPatchCoords,
655 patchCoords->get_vertex_buffer(),
656 patchTable->GetPatchArrays(),
657 patchTable->GetPatchIndexBuffer(),
658 patchTable->GetPatchParamBuffer());
659 }
660
695 template<typename SRC_BUFFER,
696 typename DST_BUFFER,
697 typename PATCHCOORD_BUFFER,
698 typename PATCH_TABLE>
699 bool EvalPatches(SRC_BUFFER *srcBuffer,
700 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
701 DST_BUFFER *dstBuffer,
702 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
703 DST_BUFFER *duBuffer,
704 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
705 DST_BUFFER *dvBuffer,
706 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
707 int numPatchCoords,
708 PATCHCOORD_BUFFER *patchCoords,
709 PATCH_TABLE *patchTable)
710 {
711
712 return EvalPatches(srcBuffer->get_vertex_buffer(),
713 srcDesc,
714 dstBuffer->get_vertex_buffer(),
715 dstDesc,
716 duBuffer->get_vertex_buffer(),
717 duDesc,
718 dvBuffer->get_vertex_buffer(),
719 dvDesc,
720 numPatchCoords,
721 patchCoords->get_vertex_buffer(),
722 patchTable->GetPatchArrays(),
723 patchTable->GetPatchIndexBuffer(),
724 patchTable->GetPatchParamBuffer());
725 }
726
727 bool EvalPatches(gpu::VertBuf *srcBuffer,
728 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
729 gpu::VertBuf *dstBuffer,
730 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
731 gpu::VertBuf *duBuffer,
732 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
733 gpu::VertBuf *dvBuffer,
734 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
735 int numPatchCoords,
736 gpu::VertBuf *patchCoordsBuffer,
737 const OpenSubdiv::Osd::PatchArrayVector &patchArrays,
738 gpu::StorageBuf *patchIndexBuffer,
739 gpu::StorageBuf *patchParamsBuffer);
740
773 template<typename SRC_BUFFER,
774 typename DST_BUFFER,
775 typename PATCHCOORD_BUFFER,
776 typename PATCH_TABLE>
777 static bool EvalPatchesVarying(SRC_BUFFER *srcBuffer,
778 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
779 DST_BUFFER *dstBuffer,
780 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
781 int numPatchCoords,
782 PATCHCOORD_BUFFER *patchCoords,
783 PATCH_TABLE *patchTable,
784 GPUComputeEvaluator *instance,
785 void *deviceContext = nullptr)
786 {
787 if (instance) {
788 return instance->EvalPatchesVarying(
789 srcBuffer, srcDesc, dstBuffer, dstDesc, numPatchCoords, patchCoords, patchTable);
790 }
791
792 // Create an instance on demand (slow)
793 (void)deviceContext; // unused
794 instance = Create(srcDesc,
795 dstDesc,
796 OpenSubdiv::Osd::BufferDescriptor(),
797 OpenSubdiv::Osd::BufferDescriptor());
798 if (instance) {
799 bool r = instance->EvalPatchesVarying(
800 srcBuffer, srcDesc, dstBuffer, dstDesc, numPatchCoords, patchCoords, patchTable);
801 delete instance;
802 return r;
803 }
804 return false;
805 }
806
831 template<typename SRC_BUFFER,
832 typename DST_BUFFER,
833 typename PATCHCOORD_BUFFER,
834 typename PATCH_TABLE>
835 bool EvalPatchesVarying(SRC_BUFFER *srcBuffer,
836 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
837 DST_BUFFER *dstBuffer,
838 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
839 int numPatchCoords,
840 PATCHCOORD_BUFFER *patchCoords,
841 PATCH_TABLE *patchTable)
842 {
843
844 return EvalPatches(srcBuffer->get_vertex_buffer(),
845 srcDesc,
846 dstBuffer->get_vertex_buffer(),
847 dstDesc,
848 nullptr,
849 OpenSubdiv::Osd::BufferDescriptor(),
850 nullptr,
851 OpenSubdiv::Osd::BufferDescriptor(),
852 numPatchCoords,
853 patchCoords->get_vertex_buffer(),
854 patchTable->GetVaryingPatchArrays(),
855 patchTable->GetVaryingPatchIndexBuffer(),
856 patchTable->GetPatchParamBuffer());
857 }
858
903 template<typename SRC_BUFFER,
904 typename DST_BUFFER,
905 typename PATCHCOORD_BUFFER,
906 typename PATCH_TABLE>
907 static bool EvalPatchesVarying(SRC_BUFFER *srcBuffer,
908 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
909 DST_BUFFER *dstBuffer,
910 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
911 DST_BUFFER *duBuffer,
912 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
913 DST_BUFFER *dvBuffer,
914 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
915 int numPatchCoords,
916 PATCHCOORD_BUFFER *patchCoords,
917 PATCH_TABLE *patchTable,
918 GPUComputeEvaluator *instance,
919 void *deviceContext = nullptr)
920 {
921 if (instance) {
922 return instance->EvalPatchesVarying(srcBuffer,
923 srcDesc,
924 dstBuffer,
925 dstDesc,
926 duBuffer,
927 duDesc,
928 dvBuffer,
929 dvDesc,
930 numPatchCoords,
931 patchCoords,
932 patchTable);
933 }
934
935 // Create an instance on demand (slow)
936 (void)deviceContext; // unused
937 instance = Create(srcDesc, dstDesc, duDesc, dvDesc);
938 if (instance) {
939 bool r = instance->EvalPatchesVarying(srcBuffer,
940 srcDesc,
941 dstBuffer,
942 dstDesc,
943 duBuffer,
944 duDesc,
945 dvBuffer,
946 dvDesc,
947 numPatchCoords,
948 patchCoords,
949 patchTable);
950 delete instance;
951 return r;
952 }
953 return false;
954 }
955
992 template<typename SRC_BUFFER,
993 typename DST_BUFFER,
994 typename PATCHCOORD_BUFFER,
995 typename PATCH_TABLE>
996 bool EvalPatchesVarying(SRC_BUFFER *srcBuffer,
997 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
998 DST_BUFFER *dstBuffer,
999 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1000 DST_BUFFER *duBuffer,
1001 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
1002 DST_BUFFER *dvBuffer,
1003 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
1004 int numPatchCoords,
1005 PATCHCOORD_BUFFER *patchCoords,
1006 PATCH_TABLE *patchTable)
1007 {
1008
1009 return EvalPatches(srcBuffer->get_vertex_buffer(),
1010 srcDesc,
1011 dstBuffer->get_vertex_buffer(),
1012 dstDesc,
1013 duBuffer->get_vertex_buffer(),
1014 duDesc,
1015 dvBuffer->get_vertex_buffer(),
1016 dvDesc,
1017 numPatchCoords,
1018 patchCoords->get_vertex_buffer(),
1019 patchTable->GetVaryingPatchArrays(),
1020 patchTable->GetVaryingPatchIndexBuffer(),
1021 patchTable->GetPatchParamBuffer());
1022 }
1023
1058 template<typename SRC_BUFFER,
1059 typename DST_BUFFER,
1060 typename PATCHCOORD_BUFFER,
1061 typename PATCH_TABLE>
1062 static bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer,
1063 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1064 DST_BUFFER *dstBuffer,
1065 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1066 int numPatchCoords,
1067 PATCHCOORD_BUFFER *patchCoords,
1068 PATCH_TABLE *patchTable,
1069 int fvarChannel,
1070 GPUComputeEvaluator *instance,
1071 void *deviceContext = nullptr)
1072 {
1073 if (instance) {
1074 return instance->EvalPatchesFaceVarying(srcBuffer,
1075 srcDesc,
1076 dstBuffer,
1077 dstDesc,
1078 numPatchCoords,
1079 patchCoords,
1080 patchTable,
1081 fvarChannel);
1082 }
1083
1084 // Create an instance on demand (slow)
1085 (void)deviceContext; // unused
1086 instance = Create(srcDesc,
1087 dstDesc,
1088 OpenSubdiv::Osd::BufferDescriptor(),
1089 OpenSubdiv::Osd::BufferDescriptor());
1090 if (instance) {
1091 bool r = instance->EvalPatchesFaceVarying(srcBuffer,
1092 srcDesc,
1093 dstBuffer,
1094 dstDesc,
1095 numPatchCoords,
1096 patchCoords,
1097 patchTable,
1098 fvarChannel);
1099 delete instance;
1100 return r;
1101 }
1102 return false;
1103 }
1104
1131 template<typename SRC_BUFFER,
1132 typename DST_BUFFER,
1133 typename PATCHCOORD_BUFFER,
1134 typename PATCH_TABLE>
1135 bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer,
1136 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1137 DST_BUFFER *dstBuffer,
1138 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1139 int numPatchCoords,
1140 PATCHCOORD_BUFFER *patchCoords,
1141 PATCH_TABLE *patchTable,
1142 int fvarChannel = 0)
1143 {
1144
1145 return EvalPatches(srcBuffer->get_vertex_buffer(),
1146 srcDesc,
1147 dstBuffer->get_vertex_buffer(),
1148 dstDesc,
1149 0,
1150 OpenSubdiv::Osd::BufferDescriptor(),
1151 0,
1152 OpenSubdiv::Osd::BufferDescriptor(),
1153 numPatchCoords,
1154 patchCoords->get_vertex_buffer(),
1155 patchTable->GetFVarPatchArrays(fvarChannel),
1156 patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1157 patchTable->GetFVarPatchParamBuffer(fvarChannel));
1158 }
1159
1206 template<typename SRC_BUFFER,
1207 typename DST_BUFFER,
1208 typename PATCHCOORD_BUFFER,
1209 typename PATCH_TABLE>
1210 static bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer,
1211 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1212 DST_BUFFER *dstBuffer,
1213 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1214 DST_BUFFER *duBuffer,
1215 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
1216 DST_BUFFER *dvBuffer,
1217 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
1218 int numPatchCoords,
1219 PATCHCOORD_BUFFER *patchCoords,
1220 PATCH_TABLE *patchTable,
1221 int fvarChannel,
1222 GPUComputeEvaluator *instance,
1223 void *deviceContext = nullptr)
1224 {
1225 if (instance) {
1226 return instance->EvalPatchesFaceVarying(srcBuffer,
1227 srcDesc,
1228 dstBuffer,
1229 dstDesc,
1230 duBuffer,
1231 duDesc,
1232 dvBuffer,
1233 dvDesc,
1234 numPatchCoords,
1235 patchCoords,
1236 patchTable,
1237 fvarChannel);
1238 }
1239
1240 // Create an instance on demand (slow)
1241 (void)deviceContext; // unused
1242 instance = Create(srcDesc, dstDesc, duDesc, dvDesc);
1243 if (instance) {
1244 bool r = instance->EvalPatchesFaceVarying(srcBuffer,
1245 srcDesc,
1246 dstBuffer,
1247 dstDesc,
1248 duBuffer,
1249 duDesc,
1250 dvBuffer,
1251 dvDesc,
1252 numPatchCoords,
1253 patchCoords,
1254 patchTable,
1255 fvarChannel);
1256 delete instance;
1257 return r;
1258 }
1259 return false;
1260 }
1261
1300 template<typename SRC_BUFFER,
1301 typename DST_BUFFER,
1302 typename PATCHCOORD_BUFFER,
1303 typename PATCH_TABLE>
1304 bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer,
1305 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1306 DST_BUFFER *dstBuffer,
1307 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1308 DST_BUFFER *duBuffer,
1309 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
1310 DST_BUFFER *dvBuffer,
1311 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
1312 int numPatchCoords,
1313 PATCHCOORD_BUFFER *patchCoords,
1314 PATCH_TABLE *patchTable,
1315 int fvarChannel = 0)
1316 {
1317
1318 return EvalPatches(srcBuffer->get_vertex_buffer(),
1319 srcDesc,
1320 dstBuffer->get_vertex_buffer(),
1321 dstDesc,
1322 duBuffer->get_vertex_buffer(),
1323 duDesc,
1324 dvBuffer->get_vertex_buffer(),
1325 dvDesc,
1326 numPatchCoords,
1327 patchCoords->get_vertex_buffer(),
1328 patchTable->GetFVarPatchArrays(fvarChannel),
1329 patchTable->GetFVarPatchIndexBuffer(fvarChannel),
1330 patchTable->GetFVarPatchParamBuffer(fvarChannel));
1331 }
1332
1338
1341 bool Compile(
1342 OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1343 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1344 OpenSubdiv::Osd::BufferDescriptor const &duDesc = OpenSubdiv::Osd::BufferDescriptor(),
1345 OpenSubdiv::Osd::BufferDescriptor const &dvDesc = OpenSubdiv::Osd::BufferDescriptor());
1346
1348 static void Synchronize(void *deviceContext);
1349
1350 private:
1351 struct _StencilKernel {
1352 _StencilKernel();
1353 ~_StencilKernel();
1354 bool Compile(OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1355 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1356 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
1357 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
1358 int workGroupSize);
1359 blender::gpu::Shader *shader = nullptr;
1360 int uniformStart = 0;
1361 int uniformEnd = 0;
1362 int uniformSrcOffset = 0;
1363 int uniformDstOffset = 0;
1364 int uniformDuDesc = 0;
1365 int uniformDvDesc = 0;
1366 } _stencilKernel;
1367
1368 struct _PatchKernel {
1369 _PatchKernel();
1370 ~_PatchKernel();
1371 bool Compile(OpenSubdiv::Osd::BufferDescriptor const &srcDesc,
1372 OpenSubdiv::Osd::BufferDescriptor const &dstDesc,
1373 OpenSubdiv::Osd::BufferDescriptor const &duDesc,
1374 OpenSubdiv::Osd::BufferDescriptor const &dvDesc,
1375 int workGroupSize);
1376 blender::gpu::Shader *shader = nullptr;
1377 int uniformSrcOffset = 0;
1378 int uniformDstOffset = 0;
1379 int uniformDuDesc = 0;
1380 int uniformDvDesc = 0;
1381 } _patchKernel;
1382
1383 int _workGroupSize;
1384 gpu::StorageBuf *_patchArraysSSBO = nullptr;
1385
1386 int GetDispatchSize(int count) const;
1387
1388 void DispatchCompute(blender::gpu::Shader *shader, int totalDispatchSize) const;
1389};
1390
1391} // namespace blender::opensubdiv
1392
1393#endif // OPENSUBDIV_GPU_COMPUTE_EVALUATOR_H_
static GPUComputeEvaluator * Create(OpenSubdiv::Osd::BufferDescriptor const &srcDesc, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, OpenSubdiv::Osd::BufferDescriptor const &duDesc, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, void *=nullptr)
bool EvalPatches(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable)
Generic limit eval function with derivatives. This function has a same signature as other device kern...
bool EvalStencils(gpu::VertBuf *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, gpu::VertBuf *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, gpu::VertBuf *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, gpu::VertBuf *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, gpu::StorageBuf *sizesBuffer, gpu::StorageBuf *offsetsBuffer, gpu::StorageBuf *indicesBuffer, gpu::StorageBuf *weightsBuffer, gpu::StorageBuf *duWeightsBuffer, gpu::StorageBuf *dvWeightsBuffer, int start, int end) const
Dispatch the GLSL compute kernel on GPU asynchronously returns false if the kernel hasn't been compil...
static bool EvalPatches(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalPatchesVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
static bool EvalPatchesVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalPatches(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
static bool EvalStencils(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, STENCIL_TABLE const *stencilTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic static stencil function. This function has a same signature as other device kernels have so t...
bool EvalStencils(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, STENCIL_TABLE const *stencilTable) const
Generic stencil function.
bool EvalPatchesVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, int fvarChannel=0)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool Compile(OpenSubdiv::Osd::BufferDescriptor const &srcDesc, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, OpenSubdiv::Osd::BufferDescriptor const &duDesc=OpenSubdiv::Osd::BufferDescriptor(), OpenSubdiv::Osd::BufferDescriptor const &dvDesc=OpenSubdiv::Osd::BufferDescriptor())
static void Synchronize(void *deviceContext)
Wait the dispatched kernel finishes.
static bool EvalPatchesVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
static GPUComputeEvaluator * Create(OpenSubdiv::Osd::BufferDescriptor const &srcDesc, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, OpenSubdiv::Osd::BufferDescriptor const &duDesc, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, OpenSubdiv::Osd::BufferDescriptor const &, OpenSubdiv::Osd::BufferDescriptor const &, OpenSubdiv::Osd::BufferDescriptor const &, void *deviceContext=nullptr)
static bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, int fvarChannel, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, int fvarChannel=0)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalPatches(gpu::VertBuf *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, gpu::VertBuf *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, gpu::VertBuf *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, gpu::VertBuf *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, gpu::VertBuf *patchCoordsBuffer, const OpenSubdiv::Osd::PatchArrayVector &patchArrays, gpu::StorageBuf *patchIndexBuffer, gpu::StorageBuf *patchParamsBuffer)
~GPUComputeEvaluator()
Destructor. note that the GL context must be made current.
static bool EvalPatchesFaceVarying(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, int fvarChannel, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
bool EvalStencils(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, STENCIL_TABLE const *stencilTable) const
Generic stencil function.
static bool EvalStencils(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, STENCIL_TABLE const *stencilTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic static stencil function. This function has a same signature as other device kernels have so t...
static bool EvalPatches(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, DST_BUFFER *duBuffer, OpenSubdiv::Osd::BufferDescriptor const &duDesc, DST_BUFFER *dvBuffer, OpenSubdiv::Osd::BufferDescriptor const &dvDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, GPUComputeEvaluator *instance, void *deviceContext=nullptr)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
GPUStencilTableSSBO(OpenSubdiv::Far::StencilTable const *stencilTable)
static GPUStencilTableSSBO * Create(OpenSubdiv::Far::LimitStencilTable const *limitStencilTable, void *deviceContext=nullptr)
GPUStencilTableSSBO(OpenSubdiv::Far::LimitStencilTable const *limitStencilTable)
static GPUStencilTableSSBO * Create(OpenSubdiv::Far::StencilTable const *stencilTable, void *deviceContext=nullptr)
int count