1 //
2 //   Copyright 2018 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_PATCH_BASIS_COMMON_TYPES_H
26 #define OPENSUBDIV3_OSD_PATCH_BASIS_COMMON_TYPES_H
27 
28 #if defined(OSD_PATCH_BASIS_GLSL)
29 
30     #define OSD_FUNCTION_STORAGE_CLASS
31     #define OSD_DATA_STORAGE_CLASS
32     #define OSD_REAL float
33     #define OSD_REAL_CAST float
34     #define OSD_OPTIONAL(a) true
35     #define OSD_OPTIONAL_INIT(a,b) b
36     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 0
37     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
38             elementType identifier[arraySize]
39     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
40             out elementType identifier[arraySize]
41     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
42             inout elementType identifier[arraySize]
43     #define OSD_ARRAY_2(elementType,a0,a1) \
44             elementType[](a0,a1)
45     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
46             elementType[](a0,a1,a2)
47     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
48             elementType[](a0,a1,a2,a3)
49     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
50             elementType[](a0,a1,a2,a3,a4,a5)
51     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
52             elementType[](a0,a1,a2,a3,a4,a5,a6,a7)
53     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
54             elementType[](a0,a1,a2,a3,a4,a5,a6,a7,a8)
55     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
56             elementType[](a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)
57 
58 #elif defined(OSD_PATCH_BASIS_HLSL)
59 
60     #define OSD_FUNCTION_STORAGE_CLASS
61     #define OSD_DATA_STORAGE_CLASS
62     #define OSD_REAL float
63     #define OSD_REAL_CAST float
64     #define OSD_OPTIONAL(a) true
65     #define OSD_OPTIONAL_INIT(a,b) b
66     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 0
67     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
68             elementType identifier[arraySize]
69     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
70             out elementType identifier[arraySize]
71     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
72             inout elementType identifier[arraySize]
73     #define OSD_ARRAY_2(elementType,a0,a1) \
74             {a0,a1}
75     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
76             {a0,a1,a2}
77     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
78             {a0,a1,a2,a3}
79     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
80             {a0,a1,a2,a3,a4,a5}
81     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
82             {a0,a1,a2,a3,a4,a5,a6,a7}
83     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
84             {a0,a1,a2,a3,a4,a5,a6,a7,a8}
85     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
86             {a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11}
87 
88 #elif defined(OSD_PATCH_BASIS_CUDA)
89 
90     #define OSD_FUNCTION_STORAGE_CLASS __device__
91     #define OSD_DATA_STORAGE_CLASS
92     #define OSD_REAL float
93     #define OSD_REAL_CAST float
94     #define OSD_OPTIONAL(a) true
95     #define OSD_OPTIONAL_INIT(a,b) b
96     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 0
97     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
98             elementType identifier[arraySize]
99     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
100             elementType identifier[arraySize]
101     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
102             elementType identifier[arraySize]
103     #define OSD_ARRAY_2(elementType,a0,a1) \
104             {a0,a1}
105     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
106             {a0,a1,a2}
107     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
108             {a0,a1,a2,a3}
109     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
110             {a0,a1,a2,a3,a4,a5}
111     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
112             {a0,a1,a2,a3,a4,a5,a6,a7}
113     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
114             {a0,a1,a2,a3,a4,a5,a6,a7,a8}
115     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
116             {a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11}
117 
118 #elif defined(OSD_PATCH_BASIS_OPENCL)
119 
120     #define OSD_FUNCTION_STORAGE_CLASS static
121     #define OSD_DATA_STORAGE_CLASS
122     #define OSD_REAL float
123     #define OSD_REAL_CAST convert_float
124     #define OSD_OPTIONAL(a) true
125     #define OSD_OPTIONAL_INIT(a,b) b
126     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 0
127     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
128             elementType identifier[arraySize]
129     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
130             elementType identifier[arraySize]
131     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
132             elementType identifier[arraySize]
133     #define OSD_ARRAY_2(elementType,a0,a1) \
134             {a0,a1}
135     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
136             {a0,a1,a2}
137     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
138             {a0,a1,a2,a3}
139     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
140             {a0,a1,a2,a3,a4,a5}
141     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
142             {a0,a1,a2,a3,a4,a5,a6,a7}
143     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
144             {a0,a1,a2,a3,a4,a5,a6,a7,a8}
145     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
146             {a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11}
147 
148 #elif defined(OSD_PATCH_BASIS_METAL)
149 
150     #define OSD_FUNCTION_STORAGE_CLASS
151     #define OSD_DATA_STORAGE_CLASS
152     #define OSD_REAL float
153     #define OSD_REAL_CAST float
154     #define OSD_OPTIONAL(a) true
155     #define OSD_OPTIONAL_INIT(a,b) b
156     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 0
157     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
158             thread elementType* identifier
159     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
160             thread elementType* identifier
161     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
162             thread elementType* identifier
163     #define OSD_ARRAY_2(elementType,a0,a1) \
164             {a0,a1}
165     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
166             {a0,a1,a2}
167     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
168             {a0,a1,a2,a3}
169     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
170             {a0,a1,a2,a3,a4,a5}
171     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
172             {a0,a1,a2,a3,a4,a5,a6,a7}
173     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
174             {a0,a1,a2,a3,a4,a5,a6,a7,a8}
175     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
176             {a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11}
177 
178 #else
179 
180     #define OSD_FUNCTION_STORAGE_CLASS static inline
181     #define OSD_DATA_STORAGE_CLASS static
182     #define OSD_REAL float
183     #define OSD_REAL_CAST float
184     #define OSD_OPTIONAL(a) (a)
185     #define OSD_OPTIONAL_INIT(a,b) (a ? b : 0)
186     #define OSD_ARRAY_ARG_BOUND_OPTIONAL 1
187     #define OSD_IN_ARRAY(elementType, identifier, arraySize) \
188             elementType identifier[arraySize]
189     #define OSD_OUT_ARRAY(elementType, identifier, arraySize) \
190             elementType identifier[arraySize]
191     #define OSD_INOUT_ARRAY(elementType, identifier, arraySize) \
192             elementType identifier[arraySize]
193     #define OSD_ARRAY_2(elementType,a0,a1) \
194             {a0,a1}
195     #define OSD_ARRAY_3(elementType,a0,a1,a2) \
196             {a0,a1,a2}
197     #define OSD_ARRAY_4(elementType,a0,a1,a2,a3) \
198             {a0,a1,a2,a3}
199     #define OSD_ARRAY_6(elementType,a0,a1,a2,a3,a4,a5) \
200             {a0,a1,a2,a3,a4,a5}
201     #define OSD_ARRAY_8(elementType,a0,a1,a2,a3,a4,a5,a6,a7) \
202             {a0,a1,a2,a3,a4,a5,a6,a7}
203     #define OSD_ARRAY_9(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8) \
204             {a0,a1,a2,a3,a4,a5,a6,a7,a8}
205     #define OSD_ARRAY_12(elementType,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
206             {a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11}
207 
208 #endif
209 
210 #if defined(OSD_PATCH_BASIS_OPENCL)
211 // OpenCL binding uses typedef to provide the required "struct" type specifier.
212 typedef struct OsdPatchParam OsdPatchParam;
213 typedef struct OsdPatchArray OsdPatchArray;
214 typedef struct OsdPatchCoord OsdPatchCoord;
215 #endif
216 
217 // Osd reflection of Far::PatchDescriptor
218 #define OSD_PATCH_DESCRIPTOR_QUADS            3
219 #define OSD_PATCH_DESCRIPTOR_TRIANGLES        4
220 #define OSD_PATCH_DESCRIPTOR_LOOP             5
221 #define OSD_PATCH_DESCRIPTOR_REGULAR          6
222 #define OSD_PATCH_DESCRIPTOR_GREGORY_BASIS    9
223 #define OSD_PATCH_DESCRIPTOR_GREGORY_TRIANGLE 10
224 
225 // Osd reflection of Osd::PatchCoord
226 struct OsdPatchCoord {
227    int arrayIndex;
228    int patchIndex;
229    int vertIndex;
230    float s;
231    float t;
232 };
233 
234 OSD_FUNCTION_STORAGE_CLASS
235 OsdPatchCoord
OsdPatchCoordInit(int arrayIndex,int patchIndex,int vertIndex,float s,float t)236 OsdPatchCoordInit(
237     int arrayIndex, int patchIndex, int vertIndex, float s, float t)
238 {
239     OsdPatchCoord coord;
240     coord.arrayIndex = arrayIndex;
241     coord.patchIndex = patchIndex;
242     coord.vertIndex = vertIndex;
243     coord.s = s;
244     coord.t = t;
245     return coord;
246 }
247 
248 // Osd reflection of Osd::PatchArray
249 struct OsdPatchArray {
250     int regDesc;
251     int desc;
252     int numPatches;
253     int indexBase;
254     int stride;
255     int primitiveIdBase;
256 };
257 
258 OSD_FUNCTION_STORAGE_CLASS
259 OsdPatchArray
OsdPatchArrayInit(int regDesc,int desc,int numPatches,int indexBase,int stride,int primitiveIdBase)260 OsdPatchArrayInit(
261     int regDesc, int desc,
262     int numPatches, int indexBase, int stride, int primitiveIdBase)
263 {
264     OsdPatchArray array;
265     array.regDesc = regDesc;
266     array.desc = desc;
267     array.numPatches = numPatches;
268     array.indexBase = indexBase;
269     array.stride = stride;
270     array.primitiveIdBase = primitiveIdBase;
271     return array;
272 }
273 
274 // Osd reflection of Osd::PatchParam
275 struct OsdPatchParam {
276     int field0;
277     int field1;
278     float sharpness;
279 };
280 
281 OSD_FUNCTION_STORAGE_CLASS
282 OsdPatchParam
OsdPatchParamInit(int field0,int field1,float sharpness)283 OsdPatchParamInit(int field0, int field1, float sharpness)
284 {
285     OsdPatchParam param;
286     param.field0 = field0;
287     param.field1 = field1;
288     param.sharpness = sharpness;
289     return param;
290 }
291 
292 OSD_FUNCTION_STORAGE_CLASS
293 int
OsdPatchParamGetFaceId(OsdPatchParam param)294 OsdPatchParamGetFaceId(OsdPatchParam param)
295 {
296     return (param.field0 & 0xfffffff);
297 }
298 
299 OSD_FUNCTION_STORAGE_CLASS
300 int
OsdPatchParamGetU(OsdPatchParam param)301 OsdPatchParamGetU(OsdPatchParam param)
302 {
303     return ((param.field1 >> 22) & 0x3ff);
304 }
305 
306 OSD_FUNCTION_STORAGE_CLASS
307 int
OsdPatchParamGetV(OsdPatchParam param)308 OsdPatchParamGetV(OsdPatchParam param)
309 {
310     return ((param.field1 >> 12) & 0x3ff);
311 }
312 
313 OSD_FUNCTION_STORAGE_CLASS
314 int
OsdPatchParamGetTransition(OsdPatchParam param)315 OsdPatchParamGetTransition(OsdPatchParam param)
316 {
317     return ((param.field0 >> 28) & 0xf);
318 }
319 
320 OSD_FUNCTION_STORAGE_CLASS
321 int
OsdPatchParamGetBoundary(OsdPatchParam param)322 OsdPatchParamGetBoundary(OsdPatchParam param)
323 {
324     return ((param.field1 >> 7) & 0x1f);
325 }
326 
327 OSD_FUNCTION_STORAGE_CLASS
328 int
OsdPatchParamGetNonQuadRoot(OsdPatchParam param)329 OsdPatchParamGetNonQuadRoot(OsdPatchParam param)
330 {
331     return ((param.field1 >> 4) & 0x1);
332 }
333 
334 OSD_FUNCTION_STORAGE_CLASS
335 int
OsdPatchParamGetDepth(OsdPatchParam param)336 OsdPatchParamGetDepth(OsdPatchParam param)
337 {
338     return (param.field1 & 0xf);
339 }
340 
341 OSD_FUNCTION_STORAGE_CLASS
342 OSD_REAL
OsdPatchParamGetParamFraction(OsdPatchParam param)343 OsdPatchParamGetParamFraction(OsdPatchParam param)
344 {
345     return 1.0f / OSD_REAL_CAST(1 <<
346         (OsdPatchParamGetDepth(param) - OsdPatchParamGetNonQuadRoot(param)));
347 }
348 
349 OSD_FUNCTION_STORAGE_CLASS
350 bool
OsdPatchParamIsRegular(OsdPatchParam param)351 OsdPatchParamIsRegular(OsdPatchParam param)
352 {
353     return (((param.field1 >> 5) & 0x1) != 0);
354 }
355 
356 OSD_FUNCTION_STORAGE_CLASS
357 bool
OsdPatchParamIsTriangleRotated(OsdPatchParam param)358 OsdPatchParamIsTriangleRotated(OsdPatchParam param)
359 {
360     return ((OsdPatchParamGetU(param) + OsdPatchParamGetV(param)) >=
361             (1 << OsdPatchParamGetDepth(param)));
362 }
363 
364 OSD_FUNCTION_STORAGE_CLASS
365 void
366 OsdPatchParamNormalize(
367         OsdPatchParam param,
368         OSD_INOUT_ARRAY(OSD_REAL, uv, 2))
369 {
370     OSD_REAL fracInv = 1.0f / OsdPatchParamGetParamFraction(param);
371 
372     uv[0] = uv[0] * fracInv - OSD_REAL_CAST(OsdPatchParamGetU(param));
373     uv[1] = uv[1] * fracInv - OSD_REAL_CAST(OsdPatchParamGetV(param));
374 }
375 
376 OSD_FUNCTION_STORAGE_CLASS
377 void
378 OsdPatchParamUnnormalize(
379         OsdPatchParam param,
380         OSD_INOUT_ARRAY(OSD_REAL, uv, 2))
381 {
382     OSD_REAL frac = OsdPatchParamGetParamFraction(param);
383 
384     uv[0] = (uv[0] + OSD_REAL_CAST(OsdPatchParamGetU(param))) * frac;
385     uv[1] = (uv[1] + OSD_REAL_CAST(OsdPatchParamGetV(param))) * frac;
386 }
387 
388 OSD_FUNCTION_STORAGE_CLASS
389 void
390 OsdPatchParamNormalizeTriangle(
391         OsdPatchParam param,
392         OSD_INOUT_ARRAY(OSD_REAL, uv, 2))
393 {
394     if (OsdPatchParamIsTriangleRotated(param)) {
395         OSD_REAL fracInv = 1.0f / OsdPatchParamGetParamFraction(param);
396 
397         int depthFactor = 1 << OsdPatchParamGetDepth(param);
398         uv[0] = OSD_REAL_CAST(depthFactor - OsdPatchParamGetU(param)) - (uv[0] * fracInv);
399         uv[1] = OSD_REAL_CAST(depthFactor - OsdPatchParamGetV(param)) - (uv[1] * fracInv);
400     } else {
401         OsdPatchParamNormalize(param, uv);
402     }
403 }
404 
405 OSD_FUNCTION_STORAGE_CLASS
406 void
407 OsdPatchParamUnnormalizeTriangle(
408         OsdPatchParam param,
409         OSD_INOUT_ARRAY(OSD_REAL, uv, 2))
410 {
411     if (OsdPatchParamIsTriangleRotated(param)) {
412         OSD_REAL frac = OsdPatchParamGetParamFraction(param);
413 
414         int depthFactor = 1 << OsdPatchParamGetDepth(param);
415         uv[0] = (OSD_REAL_CAST(depthFactor - OsdPatchParamGetU(param)) - uv[0]) * frac;
416         uv[1] = (OSD_REAL_CAST(depthFactor - OsdPatchParamGetV(param)) - uv[1]) * frac;
417     } else {
418         OsdPatchParamUnnormalize(param, uv);
419     }
420 }
421 
422 #endif /* OPENSUBDIV3_OSD_PATCH_BASIS_COMMON_TYPES_H */
423