1 | // Copyright 2009-2021 Intel Corporation |
2 | // SPDX-License-Identifier: Apache-2.0 |
3 | |
4 | #pragma once |
5 | |
6 | #include "../geometry/primitive.h" |
7 | #include "bspline_patch.h" |
8 | #include "bezier_patch.h" |
9 | #include "gregory_patch.h" |
10 | #include "gregory_patch_dense.h" |
11 | #include "tessellation.h" |
12 | #include "tessellation_cache.h" |
13 | #include "gridrange.h" |
14 | #include "patch_eval_grid.h" |
15 | #include "feature_adaptive_eval_grid.h" |
16 | #include "../common/scene_subdiv_mesh.h" |
17 | |
18 | namespace embree |
19 | { |
20 | struct __aligned(64) SubdivPatch1Base |
21 | { |
22 | public: |
23 | |
24 | enum Type { |
25 | INVALID_PATCH = 0, |
26 | BSPLINE_PATCH = 1, |
27 | BEZIER_PATCH = 2, |
28 | GREGORY_PATCH = 3, |
29 | EVAL_PATCH = 5, |
30 | BILINEAR_PATCH = 6, |
31 | }; |
32 | |
33 | enum Flags { |
34 | TRANSITION_PATCH = 16, |
35 | }; |
36 | |
37 | /*! Default constructor. */ |
38 | __forceinline SubdivPatch1Base () {} |
39 | |
40 | SubdivPatch1Base (const unsigned int gID, |
41 | const unsigned int pID, |
42 | const unsigned int subPatch, |
43 | const SubdivMesh *const mesh, |
44 | const size_t time, |
45 | const Vec2f uv[4], |
46 | const float edge_level[4], |
47 | const int subdiv[4], |
48 | const int simd_width); |
49 | |
50 | __forceinline bool needsStitching() const { |
51 | return flags & TRANSITION_PATCH; |
52 | } |
53 | |
54 | __forceinline Vec2f getUV(const size_t i) const { |
55 | return Vec2f((float)u[i],(float)v[i]) * (8.0f/0x10000); |
56 | } |
57 | |
58 | static void computeEdgeLevels(const float edge_level[4], const int subdiv[4], float level[4]); |
59 | static Vec2i computeGridSize(const float level[4]); |
60 | bool updateEdgeLevels(const float edge_level[4], const int subdiv[4], const SubdivMesh *const mesh, const int simd_width); |
61 | |
62 | public: |
63 | |
64 | __forceinline size_t getGridBytes() const { |
65 | const size_t grid_size_xyzuv = (grid_size_simd_blocks * VSIZEX) * 4; |
66 | return 64*((grid_size_xyzuv+15) / 16); |
67 | } |
68 | |
69 | __forceinline void write_lock() { mtx.lock(); } |
70 | __forceinline void write_unlock() { mtx.unlock(); } |
71 | __forceinline bool try_write_lock() { return mtx.try_lock(); } |
72 | //__forceinline bool try_read_lock() { return mtx.try_read_lock(); } |
73 | |
74 | __forceinline void resetRootRef() { |
75 | //assert( mtx.hasInitialState() ); |
76 | root_ref = SharedLazyTessellationCache::Tag(); |
77 | } |
78 | |
79 | __forceinline SharedLazyTessellationCache::CacheEntry& entry() { |
80 | return (SharedLazyTessellationCache::CacheEntry&) root_ref; |
81 | } |
82 | |
83 | public: |
84 | __forceinline unsigned int geomID() const { |
85 | return geom; |
86 | } |
87 | |
88 | __forceinline unsigned int primID() const { |
89 | return prim; |
90 | } |
91 | |
92 | public: |
93 | SharedLazyTessellationCache::Tag root_ref; |
94 | SpinLock mtx; |
95 | |
96 | unsigned short u[4]; //!< 16bit discretized u,v coordinates |
97 | unsigned short v[4]; |
98 | float level[4]; |
99 | |
100 | unsigned char flags; |
101 | unsigned char type; |
102 | unsigned short grid_u_res; |
103 | unsigned int geom; //!< geometry ID of the subdivision mesh this patch belongs to |
104 | unsigned int prim; //!< primitive ID of this subdivision patch |
105 | unsigned short grid_v_res; |
106 | |
107 | unsigned short grid_size_simd_blocks; |
108 | unsigned int time_; |
109 | |
110 | struct PatchHalfEdge { |
111 | const HalfEdge* edge; |
112 | unsigned subPatch; |
113 | }; |
114 | |
115 | Vec3fa patch_v[4][4]; |
116 | |
117 | const HalfEdge *edge() const { return ((PatchHalfEdge*)patch_v)->edge; } |
118 | unsigned time() const { return time_; } |
119 | unsigned subPatch() const { return ((PatchHalfEdge*)patch_v)->subPatch; } |
120 | |
121 | void set_edge(const HalfEdge *h) const { ((PatchHalfEdge*)patch_v)->edge = h; } |
122 | void set_subPatch(const unsigned s) const { ((PatchHalfEdge*)patch_v)->subPatch = s; } |
123 | }; |
124 | |
125 | namespace isa |
126 | { |
127 | Vec3fa patchEval(const SubdivPatch1Base& patch, const float uu, const float vv); |
128 | Vec3fa patchNormal(const SubdivPatch1Base& patch, const float uu, const float vv); |
129 | |
130 | template<typename simdf> |
131 | Vec3<simdf> patchEval(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv); |
132 | |
133 | template<typename simdf> |
134 | Vec3<simdf> patchNormal(const SubdivPatch1Base& patch, const simdf& uu, const simdf& vv); |
135 | |
136 | |
137 | /* eval grid over patch and stich edges when required */ |
138 | void evalGrid(const SubdivPatch1Base& patch, |
139 | const unsigned x0, const unsigned x1, |
140 | const unsigned y0, const unsigned y1, |
141 | const unsigned swidth, const unsigned sheight, |
142 | float *__restrict__ const grid_x, |
143 | float *__restrict__ const grid_y, |
144 | float *__restrict__ const grid_z, |
145 | float *__restrict__ const grid_u, |
146 | float *__restrict__ const grid_v, |
147 | const SubdivMesh* const geom); |
148 | |
149 | /* eval grid over patch and stich edges when required */ |
150 | BBox3fa evalGridBounds(const SubdivPatch1Base& patch, |
151 | const unsigned x0, const unsigned x1, |
152 | const unsigned y0, const unsigned y1, |
153 | const unsigned swidth, const unsigned sheight, |
154 | const SubdivMesh* const geom); |
155 | } |
156 | } |
157 | |