1 //
2 // Copyright 2018 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 // ANGLE_draw_id.cpp:
7 // Test for ANGLE_draw_id extension
8 //
9
10 #include "GLSLANG/ShaderLang.h"
11 #include "angle_gl.h"
12 #include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
13 #include "gtest/gtest.h"
14 #include "tests/test_utils/compiler_test.h"
15
16 using namespace sh;
17
18 class EmulateGLDrawIDTest : public MatchOutputCodeTest
19 {
20 public:
EmulateGLDrawIDTest()21 EmulateGLDrawIDTest()
22 : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_VARIABLES, SH_GLSL_COMPATIBILITY_OUTPUT)
23 {
24 getResources()->ANGLE_multi_draw = 1;
25 }
26
27 protected:
CheckCompileFailure(const std::string & shaderString,const char * expectedError=nullptr)28 void CheckCompileFailure(const std::string &shaderString, const char *expectedError = nullptr)
29 {
30 std::string translatedCode;
31 std::string infoLog;
32 bool success = compileTestShader(GL_VERTEX_SHADER, SH_GLES2_SPEC,
33 SH_GLSL_COMPATIBILITY_OUTPUT, shaderString, getResources(),
34 SH_VARIABLES, &translatedCode, &infoLog);
35 EXPECT_FALSE(success);
36 if (expectedError)
37 {
38 EXPECT_TRUE(infoLog.find(expectedError) != std::string::npos);
39 }
40 }
41 };
42
43 // Check that compilation fails if the compile option to emulate gl_DrawID
44 // is not set
TEST_F(EmulateGLDrawIDTest,RequiresEmulation)45 TEST_F(EmulateGLDrawIDTest, RequiresEmulation)
46 {
47 CheckCompileFailure(
48 "#extension GL_ANGLE_multi_draw : require\n"
49 "void main() {\n"
50 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
51 "}\n",
52 "extension is not supported");
53 }
54
55 // Check that compiling with emulation with gl_DrawID works with different shader versions
TEST_F(EmulateGLDrawIDTest,CheckCompile)56 TEST_F(EmulateGLDrawIDTest, CheckCompile)
57 {
58 const std::string shaderString =
59 "#extension GL_ANGLE_multi_draw : require\n"
60 "void main() {\n"
61 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
62 "}\n";
63
64 compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
65 compile("#version 100\n" + shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
66 compile("#version 300 es\n" + shaderString,
67 SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
68 }
69
70 // Check that gl_DrawID is properly emulated
TEST_F(EmulateGLDrawIDTest,EmulatesUniform)71 TEST_F(EmulateGLDrawIDTest, EmulatesUniform)
72 {
73 addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
74 addOutputType(SH_ESSL_OUTPUT);
75 #ifdef ANGLE_ENABLE_VULKAN
76 addOutputType(SH_GLSL_VULKAN_OUTPUT);
77 #endif
78 #ifdef ANGLE_ENABLE_HLSL
79 addOutputType(SH_HLSL_3_0_OUTPUT);
80 addOutputType(SH_HLSL_3_0_OUTPUT);
81 #endif
82
83 const std::string &shaderString =
84 "#extension GL_ANGLE_multi_draw : require\n"
85 "void main() {\n"
86 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
87 "}\n";
88
89 compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
90
91 EXPECT_TRUE(notFoundInCode("gl_DrawID"));
92 EXPECT_TRUE(foundInCode("angle_DrawID"));
93 EXPECT_TRUE(notFoundInCode("GL_ANGLE_multi_draw"));
94
95 EXPECT_TRUE(foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, "uniform int angle_DrawID"));
96 EXPECT_TRUE(foundInCode(SH_ESSL_OUTPUT, "uniform highp int angle_DrawID"));
97
98 #ifdef ANGLE_ENABLE_VULKAN
99 EXPECT_TRUE(
100 foundInCode(SH_GLSL_VULKAN_OUTPUT, "uniform defaultUniformsVS\n{\n int angle_DrawID;"));
101 #endif
102 #ifdef ANGLE_ENABLE_HLSL
103 EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
104 EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
105 #endif
106 }
107
108 // Check that a user-defined "gl_DrawID" is not permitted
TEST_F(EmulateGLDrawIDTest,DisallowsUserDefinedGLDrawID)109 TEST_F(EmulateGLDrawIDTest, DisallowsUserDefinedGLDrawID)
110 {
111 // Check that it is not permitted without the extension
112 CheckCompileFailure(
113 "uniform int gl_DrawID;\n"
114 "void main() {\n"
115 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
116 "}\n",
117 "reserved built-in name");
118
119 CheckCompileFailure(
120 "void main() {\n"
121 " int gl_DrawID = 0;\n"
122 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
123 "}\n",
124 "reserved built-in name");
125
126 // Check that it is not permitted with the extension
127 CheckCompileFailure(
128 "#extension GL_ANGLE_multi_draw : require\n"
129 "uniform int gl_DrawID;\n"
130 "void main() {\n"
131 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
132 "}\n",
133 "reserved built-in name");
134
135 CheckCompileFailure(
136 "#extension GL_ANGLE_multi_draw : require\n"
137 "void main() {\n"
138 " int gl_DrawID = 0;\n"
139 " gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
140 "}\n",
141 "reserved built-in name");
142 }
143
144 // gl_DrawID is translated to angle_DrawID internally. Check that a user-defined
145 // angle_DrawID is permitted
TEST_F(EmulateGLDrawIDTest,AllowsUserDefinedANGLEDrawID)146 TEST_F(EmulateGLDrawIDTest, AllowsUserDefinedANGLEDrawID)
147 {
148 addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
149 addOutputType(SH_ESSL_OUTPUT);
150 #ifdef ANGLE_ENABLE_VULKAN
151 addOutputType(SH_GLSL_VULKAN_OUTPUT);
152 #endif
153 #ifdef ANGLE_ENABLE_HLSL
154 addOutputType(SH_HLSL_3_0_OUTPUT);
155 addOutputType(SH_HLSL_3_0_OUTPUT);
156 #endif
157
158 const std::string &shaderString =
159 "#extension GL_ANGLE_multi_draw : require\n"
160 "uniform int angle_DrawID;\n"
161 "void main() {\n"
162 " gl_Position = vec4(float(angle_DrawID + gl_DrawID), 0.0, 0.0, 1.0);\n"
163 "}\n";
164
165 compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
166
167 // " angle_DrawID" (note the space) should appear exactly twice:
168 // once in the declaration and once in the body.
169 // The user-defined angle_DrawID should be decorated
170 EXPECT_TRUE(foundInCode(" angle_DrawID", 2));
171 }
172