xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/OES_sample_variables_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2020 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 // OES_sample_variables_test.cpp:
7 //   Test for OES_sample_variables
8 //
9 
10 #include "tests/test_utils/ShaderExtensionTest.h"
11 
12 namespace
13 {
14 const char OESPragma[] = "#extension GL_OES_sample_variables : require\n";
15 
16 // Shader using gl_SampleMask with non-constant index
17 // This shader is in the deqp test
18 // (functional_shaders_sample_variables_sample_mask_discard_half_per_sample_default_framebuffer)
19 const char ESSL310_GLSampleMaskShader[] =
20     R"(
21     layout(location = 0) out mediump vec4 fragColor;
22     void main (void)
23     {
24         for (int i = 0; i < gl_SampleMask.length(); ++i)
25                 gl_SampleMask[i] = int(0xAAAAAAAA);
26 
27         // force per-sample shading
28         highp float blue = float(gl_SampleID);
29 
30         fragColor = vec4(0.0, 1.0, blue, 1.0);
31     })";
32 
33 // Shader using gl_SampleMask with non-constant index
34 // This shader is based on the deqp test on below
35 // (functional_shaders_sample_variables_sample_mask_in_bit_count_per_sample_multisample_texture_2)
36 const char ESSL310_GLSampleMaskInShader[] =
37     R"(
38     layout(location = 0) out mediump vec4 fragColor;
39     void main (void)
40     {
41         mediump int maskBitCount = 0;
42         for (int j = 0; j < gl_SampleMaskIn.length(); ++j)
43         {
44             for (int i = 0; i < 32; ++i)
45             {
46                 if (((gl_SampleMaskIn[j] >> i) & 0x01) == 0x01)
47                 {
48                     ++maskBitCount;
49                 }
50             }
51         }
52 
53         // force per-sample shading
54         highp float blue = float(gl_SampleID);
55 
56         if (maskBitCount != 1)
57             fragColor = vec4(1.0, 0.0, blue, 1.0);
58         else
59             fragColor = vec4(0.0, 1.0, blue, 1.0);
60     })";
61 
62 class OESSampleVariablesTest : public sh::ShaderExtensionTest
63 {
64   public:
InitializeCompiler()65     void InitializeCompiler() { InitializeCompiler(SH_GLSL_450_CORE_OUTPUT); }
InitializeCompiler(ShShaderOutput shaderOutputType)66     void InitializeCompiler(ShShaderOutput shaderOutputType)
67     {
68         DestroyCompiler();
69 
70         mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, testing::get<0>(GetParam()),
71                                           shaderOutputType, &mResources);
72         ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
73     }
74 
TestShaderCompile(const char * pragma)75     testing::AssertionResult TestShaderCompile(const char *pragma)
76     {
77         const char *shaderStrings[] = {testing::get<1>(GetParam()), pragma,
78                                        testing::get<2>(GetParam())};
79 
80         ShCompileOptions compileOptions = {};
81         compileOptions.objectCode       = true;
82 
83         bool success = sh::Compile(mCompiler, shaderStrings, 3, compileOptions);
84         if (success)
85         {
86             return ::testing::AssertionSuccess() << "Compilation success";
87         }
88         return ::testing::AssertionFailure() << sh::GetInfoLog(mCompiler);
89     }
90 };
91 
92 // GLES3 needs OES_sample_variables extension
93 class OESSampleVariablesTestES31 : public OESSampleVariablesTest
94 {};
95 
96 // Extension flag is required to compile properly. Expect failure when it is
97 // not present.
TEST_P(OESSampleVariablesTestES31,CompileFailsWithoutExtension)98 TEST_P(OESSampleVariablesTestES31, CompileFailsWithoutExtension)
99 {
100     mResources.OES_sample_variables = 0;
101     InitializeCompiler();
102     EXPECT_FALSE(TestShaderCompile(OESPragma));
103 }
104 
105 // Extension directive is required to compile properly. Expect failure when
106 // it is not present.
TEST_P(OESSampleVariablesTestES31,CompileFailsWithExtensionWithoutPragma)107 TEST_P(OESSampleVariablesTestES31, CompileFailsWithExtensionWithoutPragma)
108 {
109     mResources.OES_sample_variables = 1;
110     InitializeCompiler();
111     EXPECT_FALSE(TestShaderCompile(""));
112 }
113 
114 // With extension flag and extension directive, compiling succeeds.
115 // Also test that the extension directive state is reset correctly.
116 #ifdef ANGLE_ENABLE_VULKAN
TEST_P(OESSampleVariablesTestES31,CompileSucceedsWithExtensionAndPragmaOnVulkan)117 TEST_P(OESSampleVariablesTestES31, CompileSucceedsWithExtensionAndPragmaOnVulkan)
118 {
119     mResources.OES_sample_variables = 1;
120     InitializeCompiler(SH_SPIRV_VULKAN_OUTPUT);
121     EXPECT_TRUE(TestShaderCompile(OESPragma));
122     // Test reset functionality.
123     EXPECT_FALSE(TestShaderCompile(""));
124     EXPECT_TRUE(TestShaderCompile(OESPragma));
125 }
126 #endif
127 
128 INSTANTIATE_TEST_SUITE_P(CorrectESSL310Shaders,
129                          OESSampleVariablesTestES31,
130                          Combine(Values(SH_GLES3_1_SPEC),
131                                  Values(sh::ESSLVersion310),
132                                  Values(ESSL310_GLSampleMaskShader, ESSL310_GLSampleMaskInShader)));
133 
134 }  // anonymous namespace
135