• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // APPLE_clip_distance_test.cpp:
7 //   Test for APPLE_clip_distance
8 //
9 
10 #include "tests/test_utils/ShaderExtensionTest.h"
11 
12 namespace
13 {
14 const char EXTPragma[] = "#extension GL_APPLE_clip_distance : require\n";
15 
16 // Shader using gl_ClipDistance
17 const char ESSL100_APPLEClipDistanceShader1[] =
18     R"(
19     uniform vec4 uPlane;
20 
21     attribute vec4 aPosition;
22 
23     void main()
24     {
25         gl_Position = aPosition;
26         gl_ClipDistance[1] = dot(aPosition, uPlane);
27     })";
28 
29 // Shader redeclares gl_ClipDistance
30 const char ESSL100_APPLEClipDistanceShader2[] =
31     R"(
32     uniform vec4 uPlane;
33 
34     attribute vec4 aPosition;
35 
36     varying highp float gl_ClipDistance[4];
37 
38     void main()
39     {
40         gl_Position = aPosition;
41         gl_ClipDistance[gl_MaxClipDistances - 6 + 1] = dot(aPosition, uPlane);
42         gl_ClipDistance[gl_MaxClipDistances - int(aPosition.x)] = dot(aPosition, uPlane);
43     })";
44 
45 class APPLEClipDistanceTest : public sh::ShaderExtensionTest
46 {
47   public:
InitializeCompiler()48     void InitializeCompiler() { InitializeCompiler(SH_GLSL_130_OUTPUT); }
InitializeCompiler(ShShaderOutput shaderOutputType)49     void InitializeCompiler(ShShaderOutput shaderOutputType)
50     {
51         DestroyCompiler();
52 
53         mCompiler = sh::ConstructCompiler(GL_VERTEX_SHADER, testing::get<0>(GetParam()),
54                                           shaderOutputType, &mResources);
55         ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
56     }
57 
TestShaderCompile(const char * pragma)58     testing::AssertionResult TestShaderCompile(const char *pragma)
59     {
60         const char *shaderStrings[] = {testing::get<1>(GetParam()), pragma,
61                                        testing::get<2>(GetParam())};
62         bool success = sh::Compile(mCompiler, shaderStrings, 3, SH_VARIABLES | SH_OBJECT_CODE);
63         if (success)
64         {
65             return ::testing::AssertionSuccess() << "Compilation success";
66         }
67         return ::testing::AssertionFailure() << sh::GetInfoLog(mCompiler);
68     }
69 };
70 
71 // Extension flag is required to compile properly. Expect failure when it is
72 // not present.
TEST_P(APPLEClipDistanceTest,CompileFailsWithoutExtension)73 TEST_P(APPLEClipDistanceTest, CompileFailsWithoutExtension)
74 {
75     mResources.APPLE_clip_distance = 0;
76     InitializeCompiler();
77     EXPECT_FALSE(TestShaderCompile(EXTPragma));
78 }
79 
80 // Extension directive is required to compile properly. Expect failure when
81 // it is not present.
TEST_P(APPLEClipDistanceTest,CompileFailsWithExtensionWithoutPragma)82 TEST_P(APPLEClipDistanceTest, CompileFailsWithExtensionWithoutPragma)
83 {
84     mResources.APPLE_clip_distance = 1;
85     InitializeCompiler();
86     EXPECT_FALSE(TestShaderCompile(""));
87 }
88 
89 // With extension flag and extension directive, compiling succeeds.
90 // Also test that the extension directive state is reset correctly.
TEST_P(APPLEClipDistanceTest,CompileSucceedsWithExtensionAndPragma)91 TEST_P(APPLEClipDistanceTest, CompileSucceedsWithExtensionAndPragma)
92 {
93     mResources.APPLE_clip_distance = 1;
94     mResources.MaxClipDistances    = 8;
95     InitializeCompiler();
96     EXPECT_TRUE(TestShaderCompile(EXTPragma));
97     // Test reset functionality.
98     EXPECT_FALSE(TestShaderCompile(""));
99     EXPECT_TRUE(TestShaderCompile(EXTPragma));
100 }
101 
102 #if defined(ANGLE_ENABLE_VULKAN)
103 // With extension flag and extension directive, compiling using TranslatorVulkan succeeds.
TEST_P(APPLEClipDistanceTest,CompileSucceedsVulkan)104 TEST_P(APPLEClipDistanceTest, CompileSucceedsVulkan)
105 {
106     mResources.APPLE_clip_distance = 1;
107     mResources.MaxClipDistances    = 8;
108 
109     InitializeCompiler(SH_SPIRV_VULKAN_OUTPUT);
110     EXPECT_TRUE(TestShaderCompile(EXTPragma));
111 }
112 #endif
113 
114 #if defined(ANGLE_ENABLE_METAL)
115 // With extension flag and extension directive, compiling using TranslatorMetal succeeds.
TEST_P(APPLEClipDistanceTest,CompileSucceedsMetal)116 TEST_P(APPLEClipDistanceTest, CompileSucceedsMetal)
117 {
118     mResources.APPLE_clip_distance = 1;
119     mResources.MaxClipDistances    = 8;
120 
121     InitializeCompiler(SH_SPIRV_METAL_OUTPUT);
122     EXPECT_TRUE(TestShaderCompile(EXTPragma));
123 }
124 #endif
125 
126 // The SL #version 100 shaders that are correct work similarly
127 // in both GL2 and GL3, with and without the version string.
128 INSTANTIATE_TEST_SUITE_P(CorrectESSL100Shaders,
129                          APPLEClipDistanceTest,
130                          Combine(Values(SH_GLES2_SPEC),
131                                  Values(sh::ESSLVersion100),
132                                  Values(ESSL100_APPLEClipDistanceShader1,
133                                         ESSL100_APPLEClipDistanceShader2)));
134 
135 }  // anonymous namespace
136