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