Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/subdiv/tessellation.h
9913 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
namespace embree
7
{
8
/* adjust discret tessellation level for feature-adaptive pre-subdivision */
9
__forceinline float adjustTessellationLevel(float l, const size_t sublevel)
10
{
11
for (size_t i=0; i<sublevel; i++) l *= 0.5f;
12
float r = ceilf(l);
13
for (size_t i=0; i<sublevel; i++) r *= 2.0f;
14
return r;
15
}
16
17
__forceinline int stitch(const int x, const int fine, const int coarse) {
18
return (2*x+1)*coarse/(2*fine);
19
}
20
21
__forceinline void stitchGridEdges(const unsigned int low_rate,
22
const unsigned int high_rate,
23
const unsigned int x0,
24
const unsigned int x1,
25
float * __restrict__ const uv_array,
26
const unsigned int uv_array_step)
27
{
28
#if 1
29
const float inv_low_rate = rcp((float)(low_rate-1));
30
for (unsigned x=x0; x<=x1; x++) {
31
uv_array[(x-x0)*uv_array_step] = float(stitch(x,high_rate-1,low_rate-1))*inv_low_rate;
32
}
33
if (unlikely(x1 == high_rate-1))
34
uv_array[(x1-x0)*uv_array_step] = 1.0f;
35
#else
36
assert(low_rate < high_rate);
37
assert(high_rate >= 2);
38
39
const float inv_low_rate = rcp((float)(low_rate-1));
40
const unsigned int dy = low_rate - 1;
41
const unsigned int dx = high_rate - 1;
42
43
int p = 2*dy-dx;
44
45
unsigned int offset = 0;
46
unsigned int y = 0;
47
float value = 0.0f;
48
for(unsigned int x=0;x<high_rate-1; x++) // '<=' would be correct but we will leave the 1.0f at the end
49
{
50
uv_array[offset] = value;
51
52
offset += uv_array_step;
53
if (unlikely(p > 0))
54
{
55
y++;
56
value = (float)y * inv_low_rate;
57
p -= 2*dx;
58
}
59
p += 2*dy;
60
}
61
#endif
62
}
63
64
__forceinline void stitchUVGrid(const float edge_levels[4],
65
const unsigned int swidth,
66
const unsigned int sheight,
67
const unsigned int x0,
68
const unsigned int y0,
69
const unsigned int grid_u_res,
70
const unsigned int grid_v_res,
71
float * __restrict__ const u_array,
72
float * __restrict__ const v_array)
73
{
74
const unsigned int x1 = x0+grid_u_res-1;
75
const unsigned int y1 = y0+grid_v_res-1;
76
const unsigned int int_edge_points0 = (unsigned int)edge_levels[0] + 1;
77
const unsigned int int_edge_points1 = (unsigned int)edge_levels[1] + 1;
78
const unsigned int int_edge_points2 = (unsigned int)edge_levels[2] + 1;
79
const unsigned int int_edge_points3 = (unsigned int)edge_levels[3] + 1;
80
81
if (unlikely(y0 == 0 && int_edge_points0 < swidth))
82
stitchGridEdges(int_edge_points0,swidth,x0,x1,u_array,1);
83
84
if (unlikely(y1 == sheight-1 && int_edge_points2 < swidth))
85
stitchGridEdges(int_edge_points2,swidth,x0,x1,&u_array[(grid_v_res-1)*grid_u_res],1);
86
87
if (unlikely(x0 == 0 && int_edge_points1 < sheight))
88
stitchGridEdges(int_edge_points1,sheight,y0,y1,&v_array[grid_u_res-1],grid_u_res);
89
90
if (unlikely(x1 == swidth-1 && int_edge_points3 < sheight))
91
stitchGridEdges(int_edge_points3,sheight,y0,y1,v_array,grid_u_res);
92
}
93
94
__forceinline void gridUVTessellator(const float edge_levels[4],
95
const unsigned int swidth,
96
const unsigned int sheight,
97
const unsigned int x0,
98
const unsigned int y0,
99
const unsigned int grid_u_res,
100
const unsigned int grid_v_res,
101
float * __restrict__ const u_array,
102
float * __restrict__ const v_array)
103
{
104
assert( grid_u_res >= 1);
105
assert( grid_v_res >= 1);
106
assert( edge_levels[0] >= 1.0f );
107
assert( edge_levels[1] >= 1.0f );
108
assert( edge_levels[2] >= 1.0f );
109
assert( edge_levels[3] >= 1.0f );
110
111
#if defined(__AVX__)
112
const vint8 grid_u_segments = vint8(swidth)-1;
113
const vint8 grid_v_segments = vint8(sheight)-1;
114
115
const vfloat8 inv_grid_u_segments = rcp(vfloat8(grid_u_segments));
116
const vfloat8 inv_grid_v_segments = rcp(vfloat8(grid_v_segments));
117
118
unsigned int index = 0;
119
vint8 v_i( zero );
120
for (unsigned int y=0;y<grid_v_res;y++,index+=grid_u_res,v_i += 1)
121
{
122
vint8 u_i ( step );
123
124
const vbool8 m_v = v_i < grid_v_segments;
125
126
for (unsigned int x=0;x<grid_u_res;x+=8, u_i += 8)
127
{
128
const vbool8 m_u = u_i < grid_u_segments;
129
const vfloat8 u = select(m_u, vfloat8(x0+u_i) * inv_grid_u_segments, 1.0f);
130
const vfloat8 v = select(m_v, vfloat8(y0+v_i) * inv_grid_v_segments, 1.0f);
131
vfloat8::storeu(&u_array[index + x],u);
132
vfloat8::storeu(&v_array[index + x],v);
133
}
134
}
135
#else
136
const vint4 grid_u_segments = vint4(swidth)-1;
137
const vint4 grid_v_segments = vint4(sheight)-1;
138
139
const vfloat4 inv_grid_u_segments = rcp(vfloat4(grid_u_segments));
140
const vfloat4 inv_grid_v_segments = rcp(vfloat4(grid_v_segments));
141
142
unsigned int index = 0;
143
vint4 v_i( zero );
144
for (unsigned int y=0;y<grid_v_res;y++,index+=grid_u_res,v_i += 1)
145
{
146
vint4 u_i ( step );
147
148
const vbool4 m_v = v_i < grid_v_segments;
149
150
for (unsigned int x=0;x<grid_u_res;x+=4, u_i += 4)
151
{
152
const vbool4 m_u = u_i < grid_u_segments;
153
const vfloat4 u = select(m_u, vfloat4(x0+u_i) * inv_grid_u_segments, 1.0f);
154
const vfloat4 v = select(m_v, vfloat4(y0+v_i) * inv_grid_v_segments, 1.0f);
155
vfloat4::storeu(&u_array[index + x],u);
156
vfloat4::storeu(&v_array[index + x],v);
157
}
158
}
159
#endif
160
}
161
}
162
163