1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EXT_YUV_target.cpp:
7 // Test for EXT_YUV_target implementation.
8 //
9
10 #include "tests/test_utils/ShaderExtensionTest.h"
11
12 using EXTYUVTargetTest = sh::ShaderExtensionTest;
13
14 namespace
15 {
16 const char EXTYTPragma[] = "#extension GL_EXT_YUV_target : require\n";
17
18 const char ESSL300_SimpleShader[] =
19 "precision mediump float;\n"
20 "uniform __samplerExternal2DY2YEXT uSampler;\n"
21 "out vec4 fragColor;\n"
22 "void main() { \n"
23 " fragColor = vec4(1.0);\n"
24 "}\n";
25
26 // Shader that samples the texture and writes to FragColor.
27 const char ESSL300_FragColorShader[] =
28 "precision mediump float;\n"
29 "uniform __samplerExternal2DY2YEXT uSampler;\n"
30 "layout(yuv) out vec4 fragColor;\n"
31 "void main() { \n"
32 " fragColor = texture(uSampler, vec2(0.0));\n"
33 "}\n";
34
35 // Shader that specifies yuv layout qualifier multiple times.
36 const char ESSL300_YUVQualifierMultipleTimesShader[] =
37 "precision mediump float;\n"
38 "layout(yuv, yuv, yuv) out vec4 fragColor;\n"
39 "void main() { \n"
40 "}\n";
41
42 // Shader that specifies yuv layout qualifier for not output fails to compile.
43 const char ESSL300_YUVQualifierFailureShader1[] =
44 "precision mediump float;\n"
45 "layout(yuv) in vec4 fragColor;\n"
46 "void main() { \n"
47 "}\n";
48
49 const char ESSL300_YUVQualifierFailureShader2[] =
50 "precision mediump float;\n"
51 "layout(yuv) uniform;\n"
52 "layout(yuv) uniform Transform {\n"
53 " mat4 M1;\n"
54 "}\n"
55 "void main() { \n"
56 "}\n";
57
58 // Shader that specifies yuv layout qualifier with location fails to compile.
59 const char ESSL300_LocationAndYUVFailureShader[] =
60 "precision mediump float;\n"
61 "layout(location = 0, yuv) out vec4 fragColor;\n"
62 "void main() { \n"
63 "}\n";
64
65 // Shader that specifies yuv layout qualifier with multiple color outputs fails to compile.
66 const char ESSL300_MultipleColorAndYUVOutputsFailureShader1[] =
67 "precision mediump float;\n"
68 "layout(yuv) out vec4 fragColor;\n"
69 "layout out vec4 fragColor1;\n"
70 "void main() { \n"
71 "}\n";
72
73 const char ESSL300_MultipleColorAndYUVOutputsFailureShader2[] =
74 "precision mediump float;\n"
75 "layout(yuv) out vec4 fragColor;\n"
76 "layout(location = 1) out vec4 fragColor1;\n"
77 "void main() { \n"
78 "}\n";
79
80 // Shader that specifies yuv layout qualifier with depth output fails to compile.
81 const char ESSL300_DepthAndYUVOutputsFailureShader[] =
82 "precision mediump float;\n"
83 "layout(yuv) out vec4 fragColor;\n"
84 "void main() { \n"
85 " gl_FragDepth = 1.0f;\n"
86 "}\n";
87
88 // Shader that specifies yuv layout qualifier with multiple outputs fails to compile.
89 const char ESSL300_MultipleYUVOutputsFailureShader[] =
90 "precision mediump float;\n"
91 "layout(yuv) out vec4 fragColor;\n"
92 "layout(yuv) out vec4 fragColor1;\n"
93 "void main() { \n"
94 "}\n";
95
96 // Shader that specifies yuvCscStandartEXT type and associated values.
97 const char ESSL300_YuvCscStandardEXTShader[] =
98 R"(precision mediump float;
99 yuvCscStandardEXT;
100 yuvCscStandardEXT conv;
101 yuvCscStandardEXT conv1 = itu_601;
102 yuvCscStandardEXT conv2 = itu_601_full_range;
103 yuvCscStandardEXT conv3 = itu_709;
104 const yuvCscStandardEXT conv4 = itu_709;
105
106 uniform int u;
107 out vec4 my_color;
108
109 yuvCscStandardEXT conv_standard()
110 {
111 switch(u)
112 {
113 case 1:
114 return conv1;
115 case 2:
116 return conv2;
117 case 3:
118 return conv3;
119 default:
120 return conv;
121 }
122 }
123 bool is_itu_601(inout yuvCscStandardEXT csc)
124 {
125 csc = itu_601;
126 return csc == itu_601;
127 }
128 bool is_itu_709(yuvCscStandardEXT csc)
129 {
130 return csc == itu_709;
131 }
132 void main()
133 {
134 yuvCscStandardEXT conv = conv_standard();
135 bool csc_check1 = is_itu_601(conv);
136 bool csc_check2 = is_itu_709(itu_709);
137 if (csc_check1 && csc_check2) {
138 my_color = vec4(0, 1, 0, 1);
139 }
140 })";
141
142 // Shader that specifies yuvCscStandartEXT type constructor fails to compile.
143 const char ESSL300_YuvCscStandartdEXTConstructFailureShader1[] =
144 "precision mediump float;\n"
145 "yuvCscStandardEXT conv = yuvCscStandardEXT();\n"
146 "void main() { \n"
147 "}\n";
148
149 const char ESSL300_YuvCscStandartdEXTConstructFailureShader2[] =
150 "precision mediump float;\n"
151 "yuvCscStandardEXT conv = yuvCscStandardEXT(itu_601);\n"
152 "void main() { \n"
153 "}\n";
154
155 // Shader that specifies yuvCscStandartEXT type conversion fails to compile.
156 const char ESSL300_YuvCscStandartdEXTConversionFailureShader1[] =
157 "precision mediump float;\n"
158 "yuvCscStandardEXT conv = false;\n"
159 "void main() { \n"
160 "}\n";
161
162 const char ESSL300_YuvCscStandartdEXTConversionFailureShader2[] =
163 "precision mediump float;\n"
164 "yuvCscStandardEXT conv = 0;\n"
165 "void main() { \n"
166 "}\n";
167
168 const char ESSL300_YuvCscStandartdEXTConversionFailureShader3[] =
169 "precision mediump float;\n"
170 "yuvCscStandardEXT conv = 2.0f;\n"
171 "void main() { \n"
172 "}\n";
173
174 const char ESSL300_YuvCscStandartdEXTConversionFailureShader4[] =
175 "precision mediump float;\n"
176 "yuvCscStandardEXT conv = itu_601 | itu_709;\n"
177 "void main() { \n"
178 "}\n";
179
180 const char ESSL300_YuvCscStandartdEXTConversionFailureShader5[] =
181 "precision mediump float;\n"
182 "yuvCscStandardEXT conv = itu_601 & 3.0f;\n"
183 "void main() { \n"
184 "}\n";
185
186 // Shader that specifies yuvCscStandartEXT type qualifiers fails to compile.
187 const char ESSL300_YuvCscStandartdEXTQualifiersFailureShader1[] =
188 "precision mediump float;\n"
189 "in yuvCscStandardEXT conv = itu_601;\n"
190 "void main() { \n"
191 "}\n";
192
193 const char ESSL300_YuvCscStandartdEXTQualifiersFailureShader2[] =
194 "precision mediump float;\n"
195 "out yuvCscStandardEXT conv = itu_601;\n"
196 "void main() { \n"
197 "}\n";
198
199 const char ESSL300_YuvCscStandartdEXTQualifiersFailureShader3[] =
200 "precision mediump float;\n"
201 "uniform yuvCscStandardEXT conv = itu_601;\n"
202 "void main() { \n"
203 "}\n";
204
205 // Shader that specifies yuv_to_rgb() and rgb_to_yuv() built-in functions.
206 const char ESSL300_BuiltInFunctionsShader[] =
207 R"(precision mediump float;
208 yuvCscStandardEXT conv = itu_601;
209
210 out vec4 my_color;
211
212 void main()
213 {
214 vec3 yuv = rgb_2_yuv(vec3(0.0f), conv);
215 vec3 rgb = yuv_2_rgb(yuv, itu_601);
216 my_color = vec4(rgb, 1.0);
217 })";
218
219 const char ESSL300_OverloadRgb2Yuv[] =
220 R"(precision mediump float;
221 float rgb_2_yuv(float x) { return x + 1.0; }
222
223 in float i;
224 out float o;
225
226 void main()
227 {
228 o = rgb_2_yuv(i);
229 })";
230
231 const char ESSL300_OverloadYuv2Rgb[] =
232 R"(precision mediump float;
233 float yuv_2_rgb(float x) { return x + 1.0; }
234
235 in float i;
236 out float o;
237
238 void main()
239 {
240 o = yuv_2_rgb(i);
241 })";
242
243 // Extension flag is required to compile properly. Expect failure when it is
244 // not present.
TEST_P(EXTYUVTargetTest,CompileFailsWithoutExtension)245 TEST_P(EXTYUVTargetTest, CompileFailsWithoutExtension)
246 {
247 mResources.EXT_YUV_target = 0;
248 InitializeCompiler();
249 EXPECT_FALSE(TestShaderCompile(EXTYTPragma));
250 }
251
252 // Extension directive is required to compile properly. Expect failure when
253 // it is not present.
TEST_P(EXTYUVTargetTest,CompileFailsWithExtensionWithoutPragma)254 TEST_P(EXTYUVTargetTest, CompileFailsWithExtensionWithoutPragma)
255 {
256 mResources.EXT_YUV_target = 1;
257 InitializeCompiler();
258 EXPECT_FALSE(TestShaderCompile(""));
259 }
260
261 // With extension flag and extension directive, compiling succeeds.
262 // Also test that the extension directive state is reset correctly.
TEST_P(EXTYUVTargetTest,CompileSucceedsWithExtensionAndPragma)263 TEST_P(EXTYUVTargetTest, CompileSucceedsWithExtensionAndPragma)
264 {
265 mResources.EXT_YUV_target = 1;
266 InitializeCompiler();
267 EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
268 // Test reset functionality.
269 EXPECT_FALSE(TestShaderCompile(""));
270 EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
271 }
272
273 INSTANTIATE_TEST_SUITE_P(CorrectVariantsWithExtensionAndPragma,
274 EXTYUVTargetTest,
275 Combine(Values(SH_GLES3_SPEC),
276 Values(sh::ESSLVersion300),
277 Values(ESSL300_SimpleShader, ESSL300_FragColorShader)));
278
279 class EXTYUVTargetCompileSuccessTest : public EXTYUVTargetTest
280 {};
281
TEST_P(EXTYUVTargetCompileSuccessTest,CompileSucceeds)282 TEST_P(EXTYUVTargetCompileSuccessTest, CompileSucceeds)
283 {
284 // Expect compile success.
285 mResources.EXT_YUV_target = 1;
286 InitializeCompiler();
287 EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
288 }
289
290 INSTANTIATE_TEST_SUITE_P(CorrectESSL300Shaders,
291 EXTYUVTargetCompileSuccessTest,
292 Combine(Values(SH_GLES3_SPEC),
293 Values(sh::ESSLVersion300),
294 Values(ESSL300_FragColorShader,
295 ESSL300_YUVQualifierMultipleTimesShader,
296 ESSL300_YuvCscStandardEXTShader,
297 ESSL300_BuiltInFunctionsShader)));
298
299 class EXTYUVTargetCompileFailureTest : public EXTYUVTargetTest
300 {};
301
TEST_P(EXTYUVTargetCompileFailureTest,CompileFails)302 TEST_P(EXTYUVTargetCompileFailureTest, CompileFails)
303 {
304 // Expect compile failure due to shader error, with shader having correct pragma.
305 mResources.EXT_YUV_target = 1;
306 InitializeCompiler();
307 EXPECT_FALSE(TestShaderCompile(EXTYTPragma));
308 }
309
310 INSTANTIATE_TEST_SUITE_P(IncorrectESSL300Shaders,
311 EXTYUVTargetCompileFailureTest,
312 Combine(Values(SH_GLES3_SPEC),
313 Values(sh::ESSLVersion300),
314 Values(ESSL300_YUVQualifierFailureShader1,
315 ESSL300_YUVQualifierFailureShader2,
316 ESSL300_LocationAndYUVFailureShader,
317 ESSL300_MultipleColorAndYUVOutputsFailureShader1,
318 ESSL300_MultipleColorAndYUVOutputsFailureShader2,
319 ESSL300_DepthAndYUVOutputsFailureShader,
320 ESSL300_MultipleYUVOutputsFailureShader,
321 ESSL300_YuvCscStandartdEXTConstructFailureShader1,
322 ESSL300_YuvCscStandartdEXTConstructFailureShader2,
323 ESSL300_YuvCscStandartdEXTConversionFailureShader1,
324 ESSL300_YuvCscStandartdEXTConversionFailureShader2,
325 ESSL300_YuvCscStandartdEXTConversionFailureShader3,
326 ESSL300_YuvCscStandartdEXTConversionFailureShader4,
327 ESSL300_YuvCscStandartdEXTConversionFailureShader5,
328 ESSL300_YuvCscStandartdEXTQualifiersFailureShader1,
329 ESSL300_YuvCscStandartdEXTQualifiersFailureShader2,
330 ESSL300_YuvCscStandartdEXTQualifiersFailureShader3)));
331
332 class EXTYUVNotEnabledTest : public EXTYUVTargetTest
333 {};
334
TEST_P(EXTYUVNotEnabledTest,CanOverloadConversions)335 TEST_P(EXTYUVNotEnabledTest, CanOverloadConversions)
336 {
337 // Expect compile success with a shader that overloads functions in the EXT_YUV_target
338 // extension.
339 mResources.EXT_YUV_target = 0;
340 InitializeCompiler();
341 EXPECT_TRUE(TestShaderCompile(""));
342 }
343
344 INSTANTIATE_TEST_SUITE_P(CoreESSL300Shaders,
345 EXTYUVNotEnabledTest,
346 Combine(Values(SH_GLES3_SPEC),
347 Values(sh::ESSLVersion300),
348 Values(ESSL300_OverloadRgb2Yuv, ESSL300_OverloadYuv2Rgb)));
349
350 } // namespace
351