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 // ExtensionDirective_test.cpp:
7 // Miscellaneous tests for extension directives toggling functionality correctly.
8 //
9
10 #include "GLSLANG/ShaderLang.h"
11 #include "angle_gl.h"
12 #include "compiler/translator/ExtensionBehavior.h"
13 #include "gtest/gtest.h"
14 #include "tests/test_utils/ShaderCompileTreeTest.h"
15
16 using namespace sh;
17
18 class FragmentShaderExtensionDirectiveTest : public ShaderCompileTreeTest
19 {
20 public:
FragmentShaderExtensionDirectiveTest()21 FragmentShaderExtensionDirectiveTest() {}
22
23 protected:
getShaderType() const24 ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
getShaderSpec() const25 ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
26
testCompileNeedsExtensionDirective(const std::string & shader,const std::string & extension)27 void testCompileNeedsExtensionDirective(const std::string &shader, const std::string &extension)
28 {
29 testCompileNeedsExtensionDirective(shader, extension, "");
30 }
31
testCompileNeedsExtensionDirective(const std::string & shader,const std::string & extension,const std::string & versionDirective)32 void testCompileNeedsExtensionDirective(const std::string &shader,
33 const std::string &extension,
34 const std::string &versionDirective)
35 {
36 if (compile(versionDirective + shader))
37 {
38 FAIL()
39 << "Shader compilation without extension directive succeeded, expecting failure:\n"
40 << mInfoLog;
41 }
42 if (compile(versionDirective + getExtensionDirective(extension, sh::EBhDisable) + shader))
43 {
44 FAIL() << "Shader compilation with extension disable directive succeeded, expecting "
45 "failure:\n"
46 << mInfoLog;
47 }
48 if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhEnable) + shader))
49 {
50 FAIL()
51 << "Shader compilation with extension enable directive failed, expecting success:\n"
52 << mInfoLog;
53 }
54
55 if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhWarn) + shader))
56 {
57 FAIL()
58 << "Shader compilation with extension warn directive failed, expecting success:\n"
59 << mInfoLog;
60 }
61 else if (!hasWarning())
62 {
63 FAIL() << "Expected compilation to succeed with warning, but warning not present:\n"
64 << mInfoLog;
65 }
66 }
67
68 private:
getExtensionDirective(const std::string & extension,sh::TBehavior behavior)69 std::string getExtensionDirective(const std::string &extension, sh::TBehavior behavior)
70 {
71 std::string extensionDirective("#extension ");
72 extensionDirective += extension + " : ";
73 switch (behavior)
74 {
75 case EBhRequire:
76 extensionDirective += "require";
77 break;
78 case EBhEnable:
79 extensionDirective += "enable";
80 break;
81 case EBhWarn:
82 extensionDirective += "warn";
83 break;
84 case EBhDisable:
85 extensionDirective += "disable";
86 break;
87 default:
88 break;
89 }
90 extensionDirective += "\n";
91 return extensionDirective;
92 }
93 };
94
95 class OESEGLImageExternalTest : public FragmentShaderExtensionDirectiveTest
96 {
97 public:
OESEGLImageExternalTest()98 OESEGLImageExternalTest() {}
99
100 protected:
initResources(ShBuiltInResources * resources)101 void initResources(ShBuiltInResources *resources) override
102 {
103 resources->OES_EGL_image_external = 1;
104 }
105 };
106
107 // OES_EGL_image_external needs to be enabled in GLSL to be able to use samplerExternalOES.
TEST_F(OESEGLImageExternalTest,SamplerExternalOESUsageNeedsExtensionDirective)108 TEST_F(OESEGLImageExternalTest, SamplerExternalOESUsageNeedsExtensionDirective)
109 {
110 const std::string &shaderString =
111 R"(
112 precision mediump float;
113
114 uniform samplerExternalOES s;
115 void main()
116 {})";
117 testCompileNeedsExtensionDirective(shaderString, "GL_OES_EGL_image_external");
118 }
119
120 class NVEGLStreamConsumerExternalTest : public FragmentShaderExtensionDirectiveTest
121 {
122 public:
NVEGLStreamConsumerExternalTest()123 NVEGLStreamConsumerExternalTest() {}
124
125 protected:
initResources(ShBuiltInResources * resources)126 void initResources(ShBuiltInResources *resources) override
127 {
128 resources->NV_EGL_stream_consumer_external = 1;
129 }
130 };
131
132 // NV_EGL_stream_consumer_external needs to be enabled in GLSL to be able to use samplerExternalOES.
TEST_F(NVEGLStreamConsumerExternalTest,SamplerExternalOESUsageNeedsExtensionDirective)133 TEST_F(NVEGLStreamConsumerExternalTest, SamplerExternalOESUsageNeedsExtensionDirective)
134 {
135 const std::string &shaderString =
136 R"(
137 precision mediump float;
138
139 uniform samplerExternalOES s;
140 void main()
141 {})";
142 testCompileNeedsExtensionDirective(shaderString, "GL_NV_EGL_stream_consumer_external");
143 }
144
145 class EXTYUVTargetTest : public FragmentShaderExtensionDirectiveTest
146 {
147 public:
EXTYUVTargetTest()148 EXTYUVTargetTest() {}
149
150 protected:
initResources(ShBuiltInResources * resources)151 void initResources(ShBuiltInResources *resources) override { resources->EXT_YUV_target = 1; }
152 };
153
154 // GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT.
TEST_F(EXTYUVTargetTest,SamplerExternal2DY2YEXTUsageNeedsExtensionDirective)155 TEST_F(EXTYUVTargetTest, SamplerExternal2DY2YEXTUsageNeedsExtensionDirective)
156 {
157 const std::string &shaderString =
158 R"(
159 precision mediump float;
160
161 uniform __samplerExternal2DY2YEXT s;
162 void main()
163 {})";
164 testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n");
165 }
166
167 // GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT.
TEST_F(EXTYUVTargetTest,YUVLayoutNeedsExtensionDirective)168 TEST_F(EXTYUVTargetTest, YUVLayoutNeedsExtensionDirective)
169 {
170 const std::string &shaderString =
171 R"(
172 precision mediump float;
173
174 layout(yuv) out vec4 color;
175 void main()
176 {})";
177 testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n");
178 }
179