xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/EXT_YUV_target_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 namespace
13 {
14 class EXTYUVTargetTest : public sh::ShaderExtensionTest
15 {
16   public:
InitializeCompiler()17     void InitializeCompiler() { InitializeCompiler(SH_GLSL_450_CORE_OUTPUT); }
InitializeCompiler(ShShaderOutput shaderOutputType)18     void InitializeCompiler(ShShaderOutput shaderOutputType)
19     {
20         DestroyCompiler();
21 
22         mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, testing::get<0>(GetParam()),
23                                           shaderOutputType, &mResources);
24         ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
25     }
26 };
27 
28 const char EXTYTPragma[] = "#extension GL_EXT_YUV_target : require\n";
29 
30 const char ESSL300_SimpleShader[] =
31     R"(precision mediump float;
32     uniform __samplerExternal2DY2YEXT uSampler;
33     out vec4 fragColor;
34     void main() {
35         fragColor = vec4(1.0);
36     })";
37 
38 // Shader that samples the texture and writes to FragColor.
39 const char ESSL300_FragColorShader[] =
40     R"(precision mediump float;
41     uniform __samplerExternal2DY2YEXT uSampler;
42     layout(yuv) out vec4 fragColor;
43     void main() {
44         fragColor = texture(uSampler, vec2(0.0));
45     })";
46 
47 // Shader that samples the texture and swizzle and writes to FragColor.
48 const char ESSL300_textureSwizzleFragColorShader[] =
49     R"(precision mediump float;
50     uniform __samplerExternal2DY2YEXT uSampler;
51     layout(yuv) out vec4 fragColor;
52     void main() {
53         fragColor = vec4(texture(uSampler, vec2(0.0)).zyx, 1.0);
54     })";
55 
56 // Shader that specifies yuv layout qualifier multiple times.
57 const char ESSL300_YUVQualifierMultipleTimesShader[] =
58     R"(precision mediump float;
59     layout(yuv, yuv, yuv) out vec4 fragColor;
60     void main() {
61     })";
62 
63 // Shader that specifies yuv layout qualifier for not output fails to compile.
64 const char ESSL300_YUVQualifierFailureShader1[] =
65     R"(precision mediump float;
66     layout(yuv) in vec4 fragColor;
67     void main() {
68     })";
69 
70 const char ESSL300_YUVQualifierFailureShader2[] =
71     R"(precision mediump float;
72     layout(yuv) uniform;
73     layout(yuv) uniform Transform {
74          mat4 M1;
75     };
76     void main() {
77     })";
78 
79 // Shader that specifies yuv layout qualifier with location fails to compile.
80 const char ESSL300_LocationAndYUVFailureShader[] =
81     R"(precision mediump float;
82     layout(location = 0, yuv) out vec4 fragColor;
83     void main() {
84     })";
85 
86 // Shader that specifies yuv layout qualifier with multiple color outputs fails to compile.
87 const char ESSL300_MultipleColorAndYUVOutputsFailureShader1[] =
88     R"(precision mediump float;
89     layout(yuv) out vec4 fragColor;
90     layout out vec4 fragColor1;
91     void main() {
92     })";
93 
94 const char ESSL300_MultipleColorAndYUVOutputsFailureShader2[] =
95     R"(precision mediump float;
96     layout(yuv) out vec4 fragColor;
97     layout(location = 1) out vec4 fragColor1;
98     void main() {
99     })";
100 
101 // Shader that specifies yuv layout qualifier with depth output fails to compile.
102 const char ESSL300_DepthAndYUVOutputsFailureShader[] =
103     R"(precision mediump float;
104     layout(yuv) out vec4 fragColor;
105     void main() {
106         gl_FragDepth = 1.0f;
107     })";
108 
109 // Shader that specifies yuv layout qualifier with multiple outputs fails to compile.
110 const char ESSL300_MultipleYUVOutputsFailureShader[] =
111     R"(precision mediump float;
112     layout(yuv) out vec4 fragColor;
113     layout(yuv) out vec4 fragColor1;
114     void main() {
115     })";
116 
117 // Shader that specifies yuvCscStandartEXT type and associated values.
118 const char ESSL300_YuvCscStandardEXTShader[] =
119     R"(precision mediump float;
120     yuvCscStandardEXT;
121     yuvCscStandardEXT conv;
122     yuvCscStandardEXT conv1 = itu_601;
123     yuvCscStandardEXT conv2 = itu_601_full_range;
124     yuvCscStandardEXT conv3 = itu_709;
125     const yuvCscStandardEXT conv4 = itu_709;
126 
127     uniform int u;
128     out vec4 my_color;
129 
130     yuvCscStandardEXT conv_standard()
131     {
132         switch(u)
133         {
134             case 1:
135                 return conv1;
136             case 2:
137                 return conv2;
138             case 3:
139                 return conv3;
140             default:
141                 return conv;
142         }
143     }
144     bool is_itu_601(inout yuvCscStandardEXT csc)
145     {
146         csc = itu_601;
147         return csc == itu_601;
148     }
149     bool is_itu_709(yuvCscStandardEXT csc)
150     {
151         return csc == itu_709;
152     }
153     void main()
154     {
155         yuvCscStandardEXT conv = conv_standard();
156         bool csc_check1 = is_itu_601(conv);
157         bool csc_check2 = is_itu_709(itu_709);
158         if (csc_check1 && csc_check2) {
159             my_color = vec4(0, 1, 0, 1);
160         }
161     })";
162 
163 // Shader that specifies yuvCscStandardEXT type constructor fails to compile.
164 const char ESSL300_YuvCscStandardEXTConstructFailureShader1[] =
165     R"(precision mediump float;
166     yuvCscStandardEXT conv = yuvCscStandardEXT();
167     void main() {
168     })";
169 
170 const char ESSL300_YuvCscStandardEXTConstructFailureShader2[] =
171     R"(precision mediump float;
172     yuvCscStandardEXT conv = yuvCscStandardEXT(itu_601);
173     void main() {
174     })";
175 
176 // Shader that specifies yuvCscStandardEXT type conversion fails to compile.
177 const char ESSL300_YuvCscStandardEXTConversionFailureShader1[] =
178     R"(precision mediump float;
179     yuvCscStandardEXT conv = false;
180     void main() {
181     })";
182 
183 const char ESSL300_YuvCscStandardEXTConversionFailureShader2[] =
184     R"(precision mediump float;
185     yuvCscStandardEXT conv = 0;
186     void main() {
187     })";
188 
189 const char ESSL300_YuvCscStandardEXTConversionFailureShader3[] =
190     R"(precision mediump float;
191     yuvCscStandardEXT conv = 2.0f;
192     void main() {
193     })";
194 
195 const char ESSL300_YuvCscStandardEXTConversionFailureShader4[] =
196     R"(precision mediump float;
197     yuvCscStandardEXT conv = itu_601 | itu_709;
198     void main() {
199     })";
200 
201 const char ESSL300_YuvCscStandardEXTConversionFailureShader5[] =
202     R"(precision mediump float;
203     yuvCscStandardEXT conv = itu_601 & 3.0f;
204     void main() {
205     })";
206 
207 // Shader that specifies yuvCscStandardEXT type qualifiers fails to compile.
208 const char ESSL300_YuvCscStandardEXTQualifiersFailureShader1[] =
209     R"(precision mediump float;
210     in yuvCscStandardEXT conv = itu_601;
211     void main() {
212     })";
213 
214 const char ESSL300_YuvCscStandardEXTQualifiersFailureShader2[] =
215     R"(precision mediump float;
216     out yuvCscStandardEXT conv = itu_601;
217     void main() {
218     })";
219 
220 const char ESSL300_YuvCscStandardEXTQualifiersFailureShader3[] =
221     R"(precision mediump float;
222     uniform yuvCscStandardEXT conv = itu_601;
223     void main() {
224     })";
225 
226 // Shader that specifies yuv_to_rgb() and rgb_to_yuv() built-in functions.
227 const char ESSL300_BuiltInFunctionsShader[] =
228     R"(precision mediump float;
229     yuvCscStandardEXT conv = itu_601;
230 
231     out vec4 my_color;
232 
233     void main()
234     {
235         vec3 yuv = rgb_2_yuv(vec3(0.0f), conv);
236         vec3 rgb = yuv_2_rgb(yuv, itu_601);
237         my_color = vec4(rgb, 1.0);
238     })";
239 
240 // Shader with nested yuv_to_rgb() and rgb_to_yuv() built-in functions.
241 const char ESSL300_BuiltInFunctionsNested1Shader[] =
242     R"(precision mediump float;
243     yuvCscStandardEXT conv = itu_601;
244 
245     out vec4 my_color;
246 
247     void main()
248     {
249         vec3 rgb = yuv_2_rgb(rgb_2_yuv(vec3(0.0f), conv), conv);
250         my_color = vec4(rgb, 1.0);
251     })";
252 const char ESSL300_BuiltInFunctionsNested2Shader[] =
253     R"(precision mediump float;
254     yuvCscStandardEXT conv = itu_601_full_range;
255 
256     out vec4 my_color;
257 
258     void main()
259     {
260         vec3 rgb = yuv_2_rgb(vec3(0.1) + rgb_2_yuv(vec3(0.0f), conv), conv);
261         my_color = vec4(rgb, 1.0);
262     })";
263 const char ESSL300_BuiltInFunctionsNested3Shader[] =
264     R"(precision mediump float;
265     yuvCscStandardEXT conv = itu_709;
266 
267     out vec4 my_color;
268 
269     vec3 f(vec3 v) { return v + vec3(0.1); }
270 
271     void main()
272     {
273         vec3 rgb = yuv_2_rgb(f(rgb_2_yuv(vec3(0.0f), conv)), conv);
274         my_color = vec4(rgb, 1.0);
275     })";
276 const char ESSL300_BuiltInFunctionsNested4Shader[] =
277     R"(precision mediump float;
278     yuvCscStandardEXT conv = itu_601;
279 
280     out vec4 my_color;
281 
282     vec3 f(vec3 v) { return v + vec3(0.1); }
283 
284     void main()
285     {
286         vec3 rgb = f(yuv_2_rgb(f(rgb_2_yuv(vec3(0.0f), conv)), conv));
287         my_color = vec4(rgb, 1.0);
288     })";
289 
290 // Shader with yuv_to_rgb() and rgb_to_yuv() built-in functions with different precision.
291 const char ESSL300_BuiltInFunctionsPrecisionShader[] =
292     R"(precision mediump float;
293     yuvCscStandardEXT conv = itu_601;
294 
295     out vec4 my_color;
296 
297     void main()
298     {
299         lowp vec3 rgbLow = vec3(0.1);
300         mediump vec3 rgbMedium = vec3(0.2);
301         highp vec3 rgbHigh = vec3(0.3);
302 
303         lowp vec3 yuvLow = vec3(0.4);
304         mediump vec3 yuvMedium = vec3(0.5);
305         highp vec3 yuvHigh = vec3(0.6);
306 
307         my_color = vec4(
308                 rgb_2_yuv(rgbLow, conv) - rgb_2_yuv(rgbMedium, conv) + rgb_2_yuv(rgbHigh, conv) -
309                 yuv_2_rgb(yuvLow, conv) - yuv_2_rgb(yuvMedium, conv) + yuv_2_rgb(yuvHigh, conv),
310             1.0);
311     })";
312 
313 const char ESSL300_OverloadRgb2Yuv[] =
314     R"(precision mediump float;
315     float rgb_2_yuv(float x) { return x + 1.0; }
316 
317     in float i;
318     out float o;
319 
320     void main()
321     {
322         o = rgb_2_yuv(i);
323     })";
324 
325 const char ESSL300_OverloadYuv2Rgb[] =
326     R"(precision mediump float;
327     float yuv_2_rgb(float x) { return x + 1.0; }
328 
329     in float i;
330     out float o;
331 
332     void main()
333     {
334         o = yuv_2_rgb(i);
335     })";
336 
337 // Extension flag is required to compile properly. Expect failure when it is
338 // not present.
TEST_P(EXTYUVTargetTest,CompileFailsWithoutExtension)339 TEST_P(EXTYUVTargetTest, CompileFailsWithoutExtension)
340 {
341     mResources.EXT_YUV_target = 0;
342     InitializeCompiler();
343     EXPECT_FALSE(TestShaderCompile(EXTYTPragma));
344 }
345 
346 // Extension directive is required to compile properly. Expect failure when
347 // it is not present.
TEST_P(EXTYUVTargetTest,CompileFailsWithExtensionWithoutPragma)348 TEST_P(EXTYUVTargetTest, CompileFailsWithExtensionWithoutPragma)
349 {
350     mResources.EXT_YUV_target = 1;
351     InitializeCompiler();
352     EXPECT_FALSE(TestShaderCompile(""));
353 }
354 
355 // With extension flag and extension directive, compiling succeeds.
356 // Also test that the extension directive state is reset correctly.
TEST_P(EXTYUVTargetTest,CompileSucceedsWithExtensionAndPragma)357 TEST_P(EXTYUVTargetTest, CompileSucceedsWithExtensionAndPragma)
358 {
359     mResources.EXT_YUV_target = 1;
360     InitializeCompiler();
361     EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
362     // Test reset functionality.
363     EXPECT_FALSE(TestShaderCompile(""));
364     EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
365 }
366 
367 INSTANTIATE_TEST_SUITE_P(CorrectVariantsWithExtensionAndPragma,
368                          EXTYUVTargetTest,
369                          Combine(Values(SH_GLES3_SPEC),
370                                  Values(sh::ESSLVersion300),
371                                  Values(ESSL300_SimpleShader, ESSL300_FragColorShader)));
372 
373 class EXTYUVTargetCompileSuccessTest : public EXTYUVTargetTest
374 {};
375 
TEST_P(EXTYUVTargetCompileSuccessTest,CompileSucceeds)376 TEST_P(EXTYUVTargetCompileSuccessTest, CompileSucceeds)
377 {
378     // Expect compile success.
379     mResources.EXT_YUV_target = 1;
380     InitializeCompiler();
381     EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
382 }
383 
384 #ifdef ANGLE_ENABLE_VULKAN
385 // Test that YUV built-in emulation works on Vulkan
TEST_P(EXTYUVTargetCompileSuccessTest,CompileSucceedsWithExtensionAndPragmaOnVulkan)386 TEST_P(EXTYUVTargetCompileSuccessTest, CompileSucceedsWithExtensionAndPragmaOnVulkan)
387 {
388     mResources.EXT_YUV_target   = 1;
389     mCompileOptions.validateAST = 1;
390     InitializeCompiler(SH_SPIRV_VULKAN_OUTPUT);
391     EXPECT_TRUE(TestShaderCompile(EXTYTPragma));
392 }
393 #endif
394 
395 INSTANTIATE_TEST_SUITE_P(CorrectESSL300Shaders,
396                          EXTYUVTargetCompileSuccessTest,
397                          Combine(Values(SH_GLES3_SPEC),
398                                  Values(sh::ESSLVersion300),
399                                  Values(ESSL300_FragColorShader,
400                                         ESSL300_textureSwizzleFragColorShader,
401                                         ESSL300_YUVQualifierMultipleTimesShader,
402                                         ESSL300_YuvCscStandardEXTShader,
403                                         ESSL300_BuiltInFunctionsShader,
404                                         ESSL300_BuiltInFunctionsNested1Shader,
405                                         ESSL300_BuiltInFunctionsNested2Shader,
406                                         ESSL300_BuiltInFunctionsNested3Shader,
407                                         ESSL300_BuiltInFunctionsNested4Shader,
408                                         ESSL300_BuiltInFunctionsPrecisionShader)));
409 
410 class EXTYUVTargetCompileFailureTest : public EXTYUVTargetTest
411 {};
412 
TEST_P(EXTYUVTargetCompileFailureTest,CompileFails)413 TEST_P(EXTYUVTargetCompileFailureTest, CompileFails)
414 {
415     // Expect compile failure due to shader error, with shader having correct pragma.
416     mResources.EXT_YUV_target = 1;
417     InitializeCompiler();
418     EXPECT_FALSE(TestShaderCompile(EXTYTPragma));
419 }
420 
421 INSTANTIATE_TEST_SUITE_P(IncorrectESSL300Shaders,
422                          EXTYUVTargetCompileFailureTest,
423                          Combine(Values(SH_GLES3_SPEC),
424                                  Values(sh::ESSLVersion300),
425                                  Values(ESSL300_YUVQualifierFailureShader1,
426                                         ESSL300_YUVQualifierFailureShader2,
427                                         ESSL300_LocationAndYUVFailureShader,
428                                         ESSL300_MultipleColorAndYUVOutputsFailureShader1,
429                                         ESSL300_MultipleColorAndYUVOutputsFailureShader2,
430                                         ESSL300_DepthAndYUVOutputsFailureShader,
431                                         ESSL300_MultipleYUVOutputsFailureShader,
432                                         ESSL300_YuvCscStandardEXTConstructFailureShader1,
433                                         ESSL300_YuvCscStandardEXTConstructFailureShader2,
434                                         ESSL300_YuvCscStandardEXTConversionFailureShader1,
435                                         ESSL300_YuvCscStandardEXTConversionFailureShader2,
436                                         ESSL300_YuvCscStandardEXTConversionFailureShader3,
437                                         ESSL300_YuvCscStandardEXTConversionFailureShader4,
438                                         ESSL300_YuvCscStandardEXTConversionFailureShader5,
439                                         ESSL300_YuvCscStandardEXTQualifiersFailureShader1,
440                                         ESSL300_YuvCscStandardEXTQualifiersFailureShader2,
441                                         ESSL300_YuvCscStandardEXTQualifiersFailureShader3)));
442 
443 class EXTYUVNotEnabledTest : public EXTYUVTargetTest
444 {};
445 
TEST_P(EXTYUVNotEnabledTest,CanOverloadConversions)446 TEST_P(EXTYUVNotEnabledTest, CanOverloadConversions)
447 {
448     // Expect compile success with a shader that overloads functions in the EXT_YUV_target
449     // extension.
450     mResources.EXT_YUV_target = 0;
451     InitializeCompiler();
452     EXPECT_TRUE(TestShaderCompile(""));
453 }
454 
455 INSTANTIATE_TEST_SUITE_P(CoreESSL300Shaders,
456                          EXTYUVNotEnabledTest,
457                          Combine(Values(SH_GLES3_SPEC),
458                                  Values(sh::ESSLVersion300),
459                                  Values(ESSL300_OverloadRgb2Yuv, ESSL300_OverloadYuv2Rgb)));
460 
461 }  // namespace
462