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