xref: /aosp_15_r20/external/angle/third_party/glslang/src/Test/spv.debuginfo.glsl.tesc (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1/*
2The MIT License (MIT)
3
4Copyright (c) 2022 Sascha Willems
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#version 450
26
27layout(set = 0, binding = 0) uniform UBO
28{
29	mat4 projection;
30	mat4 modelview;
31	vec4 lightPos;
32	vec4 frustumPlanes[6];
33	float displacementFactor;
34	float tessellationFactor;
35	vec2 viewportDim;
36	float tessellatedEdgeSize;
37} ubo;
38
39layout(set = 0, binding = 1) uniform sampler2D samplerHeight;
40
41layout (vertices = 4) out;
42
43layout (location = 0) in vec3 inNormal[];
44layout (location = 1) in vec2 inUV[];
45
46layout (location = 0) out vec3 outNormal[4];
47layout (location = 1) out vec2 outUV[4];
48
49// Calculate the tessellation factor based on screen space
50// dimensions of the edge
51float screenSpaceTessFactor(vec4 p0, vec4 p1)
52{
53	// Calculate edge mid point
54	vec4 midPoint = 0.5 * (p0 + p1);
55	// Sphere radius as distance between the control points
56	float radius = distance(p0, p1) / 2.0;
57
58	// View space
59	vec4 v0 = ubo.modelview  * midPoint;
60
61	// Project into clip space
62	vec4 clip0 = (ubo.projection * (v0 - vec4(radius, vec3(0.0))));
63	vec4 clip1 = (ubo.projection * (v0 + vec4(radius, vec3(0.0))));
64
65	// Get normalized device coordinates
66	clip0 /= clip0.w;
67	clip1 /= clip1.w;
68
69	// Convert to viewport coordinates
70	clip0.xy *= ubo.viewportDim;
71	clip1.xy *= ubo.viewportDim;
72
73	// Return the tessellation factor based on the screen size
74	// given by the distance of the two edge control points in screen space
75	// and a reference (min.) tessellation size for the edge set by the application
76	return clamp(distance(clip0, clip1) / ubo.tessellatedEdgeSize * ubo.tessellationFactor, 1.0, 64.0);
77}
78
79// Checks the current's patch visibility against the frustum using a sphere check
80// Sphere radius is given by the patch size
81bool frustumCheck()
82{
83	// Fixed radius (increase if patch size is increased in example)
84	const float radius = 8.0f;
85	vec4 pos = gl_in[gl_InvocationID].gl_Position;
86	pos.y -= textureLod(samplerHeight, inUV[0], 0.0).r * ubo.displacementFactor;
87
88	// Check sphere against frustum planes
89	for (int i = 0; i < 6; i++) {
90		if (dot(pos, ubo.frustumPlanes[i]) + radius < 0.0)
91		{
92			return false;
93		}
94	}
95	return true;
96}
97
98void main()
99{
100	if (gl_InvocationID == 0)
101	{
102		if (!frustumCheck())
103		{
104			gl_TessLevelInner[0] = 0.0;
105			gl_TessLevelInner[1] = 0.0;
106			gl_TessLevelOuter[0] = 0.0;
107			gl_TessLevelOuter[1] = 0.0;
108			gl_TessLevelOuter[2] = 0.0;
109			gl_TessLevelOuter[3] = 0.0;
110		}
111		else
112		{
113			if (ubo.tessellationFactor > 0.0)
114			{
115				gl_TessLevelOuter[0] = screenSpaceTessFactor(gl_in[3].gl_Position, gl_in[0].gl_Position);
116				gl_TessLevelOuter[1] = screenSpaceTessFactor(gl_in[0].gl_Position, gl_in[1].gl_Position);
117				gl_TessLevelOuter[2] = screenSpaceTessFactor(gl_in[1].gl_Position, gl_in[2].gl_Position);
118				gl_TessLevelOuter[3] = screenSpaceTessFactor(gl_in[2].gl_Position, gl_in[3].gl_Position);
119				gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
120				gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
121			}
122			else
123			{
124				// Tessellation factor can be set to zero by example
125				// to demonstrate a simple passthrough
126				gl_TessLevelInner[0] = 1.0;
127				gl_TessLevelInner[1] = 1.0;
128				gl_TessLevelOuter[0] = 1.0;
129				gl_TessLevelOuter[1] = 1.0;
130				gl_TessLevelOuter[2] = 1.0;
131				gl_TessLevelOuter[3] = 1.0;
132			}
133		}
134
135	}
136
137	gl_out[gl_InvocationID].gl_Position =  gl_in[gl_InvocationID].gl_Position;
138	outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
139	outUV[gl_InvocationID] = inUV[gl_InvocationID];
140}
141