|  | // | 
|  | // Copyright 2017 The ANGLE Project Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  | // | 
|  | // ExtensionDirective_test.cpp: | 
|  | //   Miscellaneous tests for extension directives toggling functionality correctly. | 
|  | // | 
|  |  | 
|  | #include "GLSLANG/ShaderLang.h" | 
|  | #include "angle_gl.h" | 
|  | #include "compiler/translator/ExtensionBehavior.h" | 
|  | #include "gtest/gtest.h" | 
|  | #include "tests/test_utils/ShaderCompileTreeTest.h" | 
|  |  | 
|  | using namespace sh; | 
|  |  | 
|  | class FragmentShaderExtensionDirectiveTest : public ShaderCompileTreeTest | 
|  | { | 
|  | public: | 
|  | FragmentShaderExtensionDirectiveTest() {} | 
|  |  | 
|  | protected: | 
|  | ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; } | 
|  | ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; } | 
|  |  | 
|  | void testCompileNeedsExtensionDirective(const std::string &shader, const std::string &extension) | 
|  | { | 
|  | testCompileNeedsExtensionDirective(shader, extension, ""); | 
|  | } | 
|  |  | 
|  | void testCompileNeedsExtensionDirective(const std::string &shader, | 
|  | const std::string &extension, | 
|  | const std::string &versionDirective) | 
|  | { | 
|  | if (compile(versionDirective + shader)) | 
|  | { | 
|  | FAIL() | 
|  | << "Shader compilation without extension directive succeeded, expecting failure:\n" | 
|  | << mInfoLog; | 
|  | } | 
|  | if (compile(versionDirective + getExtensionDirective(extension, sh::EBhDisable) + shader)) | 
|  | { | 
|  | FAIL() << "Shader compilation with extension disable directive succeeded, expecting " | 
|  | "failure:\n" | 
|  | << mInfoLog; | 
|  | } | 
|  | if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhEnable) + shader)) | 
|  | { | 
|  | FAIL() | 
|  | << "Shader compilation with extension enable directive failed, expecting success:\n" | 
|  | << mInfoLog; | 
|  | } | 
|  |  | 
|  | if (!compile(versionDirective + getExtensionDirective(extension, sh::EBhWarn) + shader)) | 
|  | { | 
|  | FAIL() | 
|  | << "Shader compilation with extension warn directive failed, expecting success:\n" | 
|  | << mInfoLog; | 
|  | } | 
|  | else if (!hasWarning()) | 
|  | { | 
|  | FAIL() << "Expected compilation to succeed with warning, but warning not present:\n" | 
|  | << mInfoLog; | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | std::string getExtensionDirective(const std::string &extension, sh::TBehavior behavior) | 
|  | { | 
|  | std::string extensionDirective("#extension "); | 
|  | extensionDirective += extension + " : "; | 
|  | switch (behavior) | 
|  | { | 
|  | case EBhRequire: | 
|  | extensionDirective += "require"; | 
|  | break; | 
|  | case EBhEnable: | 
|  | extensionDirective += "enable"; | 
|  | break; | 
|  | case EBhWarn: | 
|  | extensionDirective += "warn"; | 
|  | break; | 
|  | case EBhDisable: | 
|  | extensionDirective += "disable"; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | extensionDirective += "\n"; | 
|  | return extensionDirective; | 
|  | } | 
|  | }; | 
|  |  | 
|  | class OESEGLImageExternalTest : public FragmentShaderExtensionDirectiveTest | 
|  | { | 
|  | public: | 
|  | OESEGLImageExternalTest() {} | 
|  |  | 
|  | protected: | 
|  | void initResources(ShBuiltInResources *resources) override | 
|  | { | 
|  | resources->OES_EGL_image_external = 1; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // OES_EGL_image_external needs to be enabled in GLSL to be able to use samplerExternalOES. | 
|  | TEST_F(OESEGLImageExternalTest, SamplerExternalOESUsageNeedsExtensionDirective) | 
|  | { | 
|  | const std::string &shaderString = | 
|  | R"( | 
|  | precision mediump float; | 
|  |  | 
|  | uniform samplerExternalOES s; | 
|  | void main() | 
|  | {})"; | 
|  | testCompileNeedsExtensionDirective(shaderString, "GL_OES_EGL_image_external"); | 
|  | } | 
|  |  | 
|  | class NVEGLStreamConsumerExternalTest : public FragmentShaderExtensionDirectiveTest | 
|  | { | 
|  | public: | 
|  | NVEGLStreamConsumerExternalTest() {} | 
|  |  | 
|  | protected: | 
|  | void initResources(ShBuiltInResources *resources) override | 
|  | { | 
|  | resources->NV_EGL_stream_consumer_external = 1; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // NV_EGL_stream_consumer_external needs to be enabled in GLSL to be able to use samplerExternalOES. | 
|  | TEST_F(NVEGLStreamConsumerExternalTest, SamplerExternalOESUsageNeedsExtensionDirective) | 
|  | { | 
|  | const std::string &shaderString = | 
|  | R"( | 
|  | precision mediump float; | 
|  |  | 
|  | uniform samplerExternalOES s; | 
|  | void main() | 
|  | {})"; | 
|  | testCompileNeedsExtensionDirective(shaderString, "GL_NV_EGL_stream_consumer_external"); | 
|  | } | 
|  |  | 
|  | class EXTYUVTargetTest : public FragmentShaderExtensionDirectiveTest | 
|  | { | 
|  | public: | 
|  | EXTYUVTargetTest() {} | 
|  |  | 
|  | protected: | 
|  | void initResources(ShBuiltInResources *resources) override { resources->EXT_YUV_target = 1; } | 
|  | }; | 
|  |  | 
|  | // GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT. | 
|  | TEST_F(EXTYUVTargetTest, SamplerExternal2DY2YEXTUsageNeedsExtensionDirective) | 
|  | { | 
|  | const std::string &shaderString = | 
|  | R"( | 
|  | precision mediump float; | 
|  |  | 
|  | uniform __samplerExternal2DY2YEXT s; | 
|  | void main() | 
|  | {})"; | 
|  | testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n"); | 
|  | } | 
|  |  | 
|  | // GL_EXT_YUV_target needs to be enabled in GLSL to be able to use samplerExternal2DY2YEXT. | 
|  | TEST_F(EXTYUVTargetTest, YUVLayoutNeedsExtensionDirective) | 
|  | { | 
|  | const std::string &shaderString = | 
|  | R"( | 
|  | precision mediump float; | 
|  |  | 
|  | layout(yuv) out vec4 color; | 
|  | void main() | 
|  | {})"; | 
|  | testCompileNeedsExtensionDirective(shaderString, "GL_EXT_YUV_target", "#version 300 es\n"); | 
|  | } |