Skip to content
This repository was archived by the owner on Dec 8, 2025. It is now read-only.

Commit d94d9e9

Browse files
authored
GLSL 450 versions of sample shaders (#1158)
A bug whereby gl_FragColor was being generated for recent versions of the OpenGL shading language is also fixed.
1 parent 4a7264f commit d94d9e9

91 files changed

Lines changed: 4809 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ast/src/main/java/com/graphicsfuzz/common/glslversion/Glsl420.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,8 @@ public boolean supportedUnpackSnorm2x16() {
5555
return true;
5656
}
5757

58+
@Override
59+
public boolean supportedGlFragColor() {
60+
return false;
61+
}
5862
}

generator/src/test/java/com/graphicsfuzz/generator/tool/GenerateShaderFamilyTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public void testGenerateSmallWebGL2ShaderFamilyMultiPass() throws Exception {
154154
}
155155

156156
@Test
157-
public void testGenerateSmallVulkanShaderFamilyMultiPass() throws Exception {
157+
public void testGenerateSmallVulkanShaderFamilyFrom320EsMultiPass() throws Exception {
158158
final String samplesSubdir = "320es";
159159
final String referenceShaderName = "stable_bubblesort_flag";
160160
final int numVariants = 3;
@@ -165,6 +165,18 @@ public void testGenerateSmallVulkanShaderFamilyMultiPass() throws Exception {
165165
"--vulkan"), ShadingLanguageVersion.ESSL_320);
166166
}
167167

168+
@Test
169+
public void testGenerateSmallVulkanShaderFamilyFrom450MultiPass() throws Exception {
170+
final String samplesSubdir = "450";
171+
final String referenceShaderName = "stable_bubblesort_flag";
172+
final int numVariants = 3;
173+
int seed = 9;
174+
checkShaderFamilyGeneration(samplesSubdir, referenceShaderName, numVariants,
175+
seed, Arrays.asList("--stop-on-fail", "--max-uniforms",
176+
String.valueOf(10),
177+
"--vulkan"), ShadingLanguageVersion.ESSL_320);
178+
}
179+
168180
@Test
169181
public void testIgnoreShaderTranslator() throws Exception {
170182
// shader_translator would reject this due to the non-constant array access; glslangValidator
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#version 450
2+
3+
/*
4+
* Copyright 2019 The GraphicsFuzz Project Authors
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
precision highp float;
20+
21+
layout(location = 0) out vec4 _GLF_color;
22+
23+
uniform vec2 injectionSwitch;
24+
25+
uniform vec2 resolution;
26+
27+
struct BinarySearchObject{
28+
int prime_numbers[10];
29+
};
30+
31+
vec2 brick(vec2 uv) {
32+
int a = 4;
33+
do {
34+
uv.y -= step(injectionSwitch.y, uv.x);
35+
uv.x -= fract(tanh(uv.x)) / ldexp(injectionSwitch.y, findMSB(a));
36+
a--;
37+
} while (a > int(injectionSwitch.x));
38+
int b = 3;
39+
do {
40+
uv.y -= step(injectionSwitch.y, uv.x) + float(a);
41+
uv.x *= (isnan(uv.y) ? cosh(gl_FragCoord.y) : tanh(gl_FragCoord.x));
42+
b--;
43+
} while (b > int(injectionSwitch.x));
44+
int c = 2;
45+
do {
46+
uv.y -= step(injectionSwitch.y, uv.x) + float(a) + float(b);
47+
uv.x += ldexp(injectionSwitch.y, isinf(uv.y + uv.x) ? findMSB(b) : findMSB(a));
48+
c--;
49+
} while (c > int(injectionSwitch.x));
50+
int d = 1;
51+
do {
52+
uv.y -= step(injectionSwitch.y, uv.x) + float(a) + float(b) + float(c);
53+
d--;
54+
} while (d > int(injectionSwitch.x));
55+
return fract(uv);
56+
}
57+
58+
float patternize(vec2 uv) {
59+
vec2 size = vec2(0.45);
60+
vec2 st = smoothstep(size, size, uv);
61+
switch (int(mod(gl_FragCoord.y, 5.0))) {
62+
case 0:
63+
return mix(pow(st.x, injectionSwitch.y), st.x, size.y);
64+
break;
65+
case 1:
66+
return mix(pow(uv.y, injectionSwitch.y), st.y, size.x);
67+
break;
68+
case 2:
69+
discard;
70+
break;
71+
case 3:
72+
return mix(pow(uv.y, injectionSwitch.y), uv.y, size.y);
73+
break;
74+
case 4:
75+
return mix(pow(st.y, injectionSwitch.y), st.x, size.x);
76+
break;
77+
}
78+
}
79+
80+
int binarySearch(BinarySearchObject obj, int x) {
81+
int l = 0, r = 9;
82+
while (l <= r) {
83+
int m = (l + r) / 2;
84+
if (obj.prime_numbers[m] == x) {
85+
return m;
86+
}
87+
88+
if (obj.prime_numbers[m] < x) {
89+
l = m + 1;
90+
} else {
91+
r = m - 1;
92+
}
93+
}
94+
// If an element is not present in the array we return -1.
95+
return -1;
96+
}
97+
98+
void main() {
99+
BinarySearchObject obj;
100+
// Initialize first 10 prime numbers to the array.
101+
for (int i = 0; i < 10; i++) {
102+
if (i == 0) {
103+
obj.prime_numbers[i] = 2;
104+
} else if (i == 1) {
105+
obj.prime_numbers[i] = 3;
106+
} else if (i == 2) {
107+
obj.prime_numbers[i] = 5;
108+
} else if (i == 3) {
109+
obj.prime_numbers[i] = 7;
110+
} else if (i == 4) {
111+
obj.prime_numbers[i] = 11;
112+
} else if (i == 5) {
113+
obj.prime_numbers[i] = 13;
114+
} else if (i == 6) {
115+
obj.prime_numbers[i] = 17;
116+
} else if (i == 7) {
117+
obj.prime_numbers[i] = 19;
118+
} else if (i == 8) {
119+
obj.prime_numbers[i] = 23;
120+
} else if (i == 9) {
121+
obj.prime_numbers[i] = 29;
122+
}
123+
}
124+
125+
vec2 uv = (gl_FragCoord.xy / resolution.x) * vec2(resolution.x / resolution.y, 1.0);
126+
vec2 b = brick(uv * 7.0);
127+
vec3 color = vec3(patternize(b));
128+
129+
if (gl_FragCoord.y < resolution.y / 1.1) {
130+
// We are going to search the item in array by giving the value of the item index 4 and 0 in an array.
131+
if (binarySearch(obj, obj.prime_numbers[4]) != -(int(resolution.y)) && binarySearch(obj, obj.prime_numbers[0]) >= -(int(resolution.x))) {
132+
color.yz -= dot(float(binarySearch(obj, obj.prime_numbers[4])), float(binarySearch(obj, obj.prime_numbers[0])));
133+
} else {
134+
discard;
135+
}
136+
} else {
137+
// The following condition is true as there is no value 1 in the array.
138+
if (binarySearch(obj, 1) == -1) {
139+
discard;
140+
} else {
141+
color.yz += color.yz;
142+
}
143+
}
144+
145+
_GLF_color = vec4(color, injectionSwitch.y);
146+
147+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"injectionSwitch": {
3+
"func": "glUniform2f",
4+
"args": [
5+
0.0,
6+
1.0
7+
]
8+
},
9+
"resolution": {
10+
"func": "glUniform2f",
11+
"args": [
12+
256.0,
13+
256.0
14+
]
15+
}
16+
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#version 450
2+
3+
/*
4+
* Copyright 2019 The GraphicsFuzz Project Authors
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
precision highp float;
20+
21+
layout(location = 0) out vec4 _GLF_color;
22+
23+
uniform vec2 resolution;
24+
25+
struct BST{
26+
int data;
27+
int leftIndex;
28+
int rightIndex;
29+
};
30+
31+
BST tree[10];
32+
33+
void makeTreeNode(inout BST tree, int data)
34+
{
35+
tree.data = data;
36+
tree.leftIndex = -1;
37+
tree.rightIndex = -1;
38+
}
39+
40+
void insert(int treeIndex, int data)
41+
{
42+
int baseIndex = 0;
43+
while (baseIndex <= treeIndex) {
44+
// If new value is smaller thatn the current node, we known that we will have
45+
// add this element in the left side.
46+
if (data <= tree[baseIndex].data) {
47+
// If a left subtree of the current node is empty, the new node is added as
48+
// a left subtree of the current node.
49+
if (tree[baseIndex].leftIndex == -1) {
50+
tree[baseIndex].leftIndex = treeIndex;
51+
makeTreeNode(tree[treeIndex], data);
52+
return;
53+
} else {
54+
baseIndex = tree[baseIndex].leftIndex;
55+
continue;
56+
}
57+
} else {
58+
// If a right subtree of the current node is empty, the new node is added as
59+
// a right subtree of the current node.
60+
if (tree[baseIndex].rightIndex == -1) {
61+
tree[baseIndex].rightIndex = treeIndex;
62+
makeTreeNode(tree[treeIndex], data);
63+
return;
64+
} else {
65+
baseIndex = tree[baseIndex].rightIndex;
66+
continue;
67+
}
68+
}
69+
}
70+
}
71+
72+
// Return element data if the given target exists in a tree. Otherwise, we simply return -1.
73+
int search(int target){
74+
BST currentNode;
75+
int index = 0;
76+
while (index != -1) {
77+
currentNode = tree[index];
78+
if (currentNode.data == target) {
79+
return target;
80+
}
81+
index = target > currentNode.data ? currentNode.rightIndex : currentNode.leftIndex;
82+
}
83+
return -1;
84+
}
85+
86+
vec3 hueColor(float angle) {
87+
float nodeData = float(search(15));
88+
vec3 color;
89+
color = clamp(fract(angle * vec3(1.0, 5.0, nodeData)), 0.0, 1.0);
90+
color.x *= cosh(isnan(float(search(30))) ? 0.0 : 1.0);
91+
return color;
92+
}
93+
94+
float makeFrame(float v) {
95+
v *= 6.5;
96+
if (v < 1.5) {
97+
return float(search(100));
98+
}
99+
if (v < 4.0) {
100+
return 0.0;
101+
}
102+
if (v < float(search(6))) {
103+
return 1.0;
104+
}
105+
return 10.0 + float(search(30));
106+
}
107+
108+
/*
109+
* This shader implements binary search tree using an array data structure. The elements of
110+
* tree are kept in the array that contains a list of BST object holding indices of left and
111+
* right subtree in the array.
112+
*
113+
* - Tree representation of the number used in this shader:
114+
* 9
115+
* / \
116+
* 5 12
117+
* / \ \
118+
* 2 7 15
119+
* / \ / \
120+
* 6 8 13 17
121+
*
122+
* - Array representation:
123+
* [9, 5, 12, 15, 7, 8, 2, 6, 17, 13]
124+
*
125+
*/
126+
127+
void main() {
128+
int treeIndex = 0;
129+
// Initialize root node.
130+
makeTreeNode(tree[0], 9);
131+
// Each time we insert a new node into the tree, we increment one.
132+
treeIndex++;
133+
134+
insert(treeIndex, 5);
135+
treeIndex++;
136+
insert(treeIndex, 12);
137+
treeIndex++;
138+
insert(treeIndex, 15);
139+
treeIndex++;
140+
insert(treeIndex, 7);
141+
treeIndex++;
142+
insert(treeIndex, 8);
143+
treeIndex++;
144+
insert(treeIndex, 2);
145+
treeIndex++;
146+
insert(treeIndex, 6);
147+
treeIndex++;
148+
insert(treeIndex, 17);
149+
treeIndex++;
150+
insert(treeIndex, 13);
151+
152+
vec2 z = (gl_FragCoord.yx / resolution);
153+
float x = makeFrame(z.x);
154+
float y = makeFrame(z.y);
155+
156+
int sum = -100;
157+
for (int target = 0; target < 20; target ++) {
158+
int result = search(target);
159+
if (result > 0) {
160+
sum += result;
161+
} else {
162+
switch (result) {
163+
case -1:
164+
sum += 1;
165+
break;
166+
case 0:
167+
return;
168+
}
169+
}
170+
}
171+
float a = tan(x + y * float(sum));
172+
_GLF_color = vec4(hueColor(a), 1.);
173+
174+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"resolution": {
3+
"func": "glUniform2f",
4+
"args": [
5+
256.0,
6+
256.0
7+
]
8+
}
9+
}

0 commit comments

Comments
 (0)