1 //
2 // Copyright 2019 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_base_vertex_base_instance.cpp:
7 // Test for ANGLE_base_vertex_base_instance 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 EmulateGLBaseVertexBaseInstanceTest : public MatchOutputCodeTest
19 {
20 public:
EmulateGLBaseVertexBaseInstanceTest()21 EmulateGLBaseVertexBaseInstanceTest()
22 : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_GLSL_COMPATIBILITY_OUTPUT)
23 {
24 ShCompileOptions defaultCompileOptions = {};
25 setDefaultCompileOptions(defaultCompileOptions);
26
27 getResources()->ANGLE_base_vertex_base_instance_shader_builtin = 1;
28 }
29
30 protected:
CheckCompileFailure(const std::string & shaderString,const char * expectedError=nullptr,ShCompileOptions * compileOptions=nullptr)31 void CheckCompileFailure(const std::string &shaderString,
32 const char *expectedError = nullptr,
33 ShCompileOptions *compileOptions = nullptr)
34 {
35 ShCompileOptions options = {};
36 if (compileOptions != nullptr)
37 {
38 options = *compileOptions;
39 }
40
41 std::string translatedCode;
42 std::string infoLog;
43 bool success =
44 compileTestShader(GL_VERTEX_SHADER, SH_GLES3_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT,
45 shaderString, getResources(), options, &translatedCode, &infoLog);
46 EXPECT_FALSE(success);
47 if (expectedError)
48 {
49 EXPECT_TRUE(infoLog.find(expectedError) != std::string::npos);
50 }
51 }
52 };
53
54 // Check that compilation fails if the compile option to emulate gl_BaseVertex and gl_BaseInstance
55 // is not set
TEST_F(EmulateGLBaseVertexBaseInstanceTest,RequiresEmulation)56 TEST_F(EmulateGLBaseVertexBaseInstanceTest, RequiresEmulation)
57 {
58 CheckCompileFailure(
59 "#version 300 es\n"
60 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
61 "void main() {\n"
62 " gl_Position = vec4(float(gl_BaseVertex), float(gl_BaseInstance), 0.0, 1.0);\n"
63 "}\n",
64 "extension is not supported");
65 }
66
67 // Check that compiling with emulation with gl_BaseVertex and gl_BaseInstance works
TEST_F(EmulateGLBaseVertexBaseInstanceTest,CheckCompile)68 TEST_F(EmulateGLBaseVertexBaseInstanceTest, CheckCompile)
69 {
70 const std::string shaderString =
71 "#version 300 es\n"
72 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
73 "void main() {\n"
74 " gl_Position = vec4(float(gl_BaseVertex), float(gl_BaseInstance), 0.0, 1.0);\n"
75 "}\n";
76
77 ShCompileOptions compileOptions = {};
78 compileOptions.objectCode = true;
79 compileOptions.emulateGLBaseVertexBaseInstance = true;
80
81 compile(shaderString, compileOptions);
82 }
83
84 // Check that compiling with the old extension doesn't work
TEST_F(EmulateGLBaseVertexBaseInstanceTest,CheckCompileOldExtension)85 TEST_F(EmulateGLBaseVertexBaseInstanceTest, CheckCompileOldExtension)
86 {
87 const std::string shaderString =
88 "#version 300 es\n"
89 "#extension GL_ANGLE_base_vertex_base_instance : require\n"
90 "void main() {\n"
91 " gl_Position = vec4(float(gl_BaseVertex), float(gl_BaseInstance), 0.0, 1.0);\n"
92 "}\n";
93
94 ShCompileOptions compileOptions = {};
95 compileOptions.objectCode = true;
96 compileOptions.emulateGLBaseVertexBaseInstance = true;
97
98 CheckCompileFailure(shaderString, "extension is not supported", &compileOptions);
99 }
100
101 // Check that gl_BaseVertex and gl_BaseInstance is properly emulated
TEST_F(EmulateGLBaseVertexBaseInstanceTest,EmulatesUniform)102 TEST_F(EmulateGLBaseVertexBaseInstanceTest, EmulatesUniform)
103 {
104 addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
105 addOutputType(SH_ESSL_OUTPUT);
106 #ifdef ANGLE_ENABLE_VULKAN
107 addOutputType(SH_SPIRV_VULKAN_OUTPUT);
108 #endif
109 #ifdef ANGLE_ENABLE_HLSL
110 addOutputType(SH_HLSL_3_0_OUTPUT);
111 addOutputType(SH_HLSL_3_0_OUTPUT);
112 #endif
113
114 const std::string &shaderString =
115 "#version 300 es\n"
116 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
117 "void main() {\n"
118 " gl_Position = vec4(float(gl_BaseVertex), float(gl_BaseInstance), 0.0, 1.0);\n"
119 "}\n";
120
121 ShCompileOptions compileOptions = {};
122 compileOptions.objectCode = true;
123 compileOptions.emulateGLBaseVertexBaseInstance = true;
124
125 compile(shaderString, compileOptions);
126
127 EXPECT_TRUE(notFoundInCode("gl_BaseVertex"));
128 EXPECT_TRUE(foundInCode("angle_BaseVertex"));
129 EXPECT_TRUE(notFoundInCode("gl_BaseInstance"));
130 EXPECT_TRUE(foundInCode("angle_BaseInstance"));
131 EXPECT_TRUE(notFoundInCode("GL_ANGLE_base_vertex_base_instance_shader_builtin"));
132
133 EXPECT_TRUE(foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, "uniform int angle_BaseVertex"));
134 EXPECT_TRUE(foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, "uniform int angle_BaseInstance"));
135 EXPECT_TRUE(foundInCode(SH_ESSL_OUTPUT, "uniform highp int angle_BaseVertex"));
136 EXPECT_TRUE(foundInCode(SH_ESSL_OUTPUT, "uniform highp int angle_BaseInstance"));
137
138 #ifdef ANGLE_ENABLE_HLSL
139 EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_BaseVertex : register"));
140 EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_BaseInstance : register"));
141 #endif
142 }
143
144 // Check that a user-defined "gl_BaseVertex" or "gl_BaseInstance" is not permitted
TEST_F(EmulateGLBaseVertexBaseInstanceTest,DisallowsUserDefinedGLDrawID)145 TEST_F(EmulateGLBaseVertexBaseInstanceTest, DisallowsUserDefinedGLDrawID)
146 {
147 // Check that it is not permitted without the extension
148 CheckCompileFailure(
149 "#version 300 es\n"
150 "uniform int gl_BaseVertex;\n"
151 "void main() {\n"
152 " gl_Position = vec4(float(gl_BaseVertex), 0.0, 0.0, 1.0);\n"
153 "}\n",
154 "reserved built-in name");
155
156 CheckCompileFailure(
157 "#version 300 es\n"
158 "uniform int gl_BaseInstance;\n"
159 "void main() {\n"
160 " gl_Position = vec4(float(gl_BaseInstance), 0.0, 0.0, 1.0);\n"
161 "}\n",
162 "reserved built-in name");
163
164 CheckCompileFailure(
165 "#version 300 es\n"
166 "void main() {\n"
167 " int gl_BaseVertex = 0;\n"
168 " gl_Position = vec4(float(gl_BaseVertex), 0.0, 0.0, 1.0);\n"
169 "}\n",
170 "reserved built-in name");
171
172 CheckCompileFailure(
173 "#version 300 es\n"
174 "void main() {\n"
175 " int gl_BaseInstance = 0;\n"
176 " gl_Position = vec4(float(gl_BaseInstance), 0.0, 0.0, 1.0);\n"
177 "}\n",
178 "reserved built-in name");
179
180 // Check that it is not permitted with the extension
181 CheckCompileFailure(
182 "#version 300 es\n"
183 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
184 "uniform int gl_BaseVertex;\n"
185 "void main() {\n"
186 " gl_Position = vec4(float(gl_BaseVertex), 0.0, 0.0, 1.0);\n"
187 "}\n",
188 "reserved built-in name");
189
190 CheckCompileFailure(
191 "#version 300 es\n"
192 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
193 "uniform int gl_BaseInstance;\n"
194 "void main() {\n"
195 " gl_Position = vec4(float(gl_BaseInstance), 0.0, 0.0, 1.0);\n"
196 "}\n",
197 "reserved built-in name");
198
199 CheckCompileFailure(
200 "#version 300 es\n"
201 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
202 "void main() {\n"
203 " int gl_BaseVertex = 0;\n"
204 " gl_Position = vec4(float(gl_BaseVertex), 0.0, 0.0, 1.0);\n"
205 "}\n",
206 "reserved built-in name");
207
208 CheckCompileFailure(
209 "#version 300 es\n"
210 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
211 "void main() {\n"
212 " int gl_BaseInstance = 0;\n"
213 " gl_Position = vec4(float(gl_BaseInstance), 0.0, 0.0, 1.0);\n"
214 "}\n",
215 "reserved built-in name");
216 }
217
218 // gl_BaseVertex and gl_BaseInstance are translated to angle_BaseVertex and angle_BaseInstance
219 // internally. Check that a user-defined angle_BaseVertex or angle_BaseInstance is permitted
TEST_F(EmulateGLBaseVertexBaseInstanceTest,AllowsUserDefinedANGLEDrawID)220 TEST_F(EmulateGLBaseVertexBaseInstanceTest, AllowsUserDefinedANGLEDrawID)
221 {
222 addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
223 addOutputType(SH_ESSL_OUTPUT);
224 #ifdef ANGLE_ENABLE_VULKAN
225 addOutputType(SH_SPIRV_VULKAN_OUTPUT);
226 #endif
227 #ifdef ANGLE_ENABLE_HLSL
228 addOutputType(SH_HLSL_3_0_OUTPUT);
229 addOutputType(SH_HLSL_3_0_OUTPUT);
230 #endif
231
232 const std::string &shaderString =
233 "#version 300 es\n"
234 "#extension GL_ANGLE_base_vertex_base_instance_shader_builtin : require\n"
235 "uniform int angle_BaseVertex;\n"
236 "uniform int angle_BaseInstance;\n"
237 "void main() {\n"
238 " gl_Position = vec4(\n"
239 " float(angle_BaseVertex + gl_BaseVertex),\n"
240 " float(angle_BaseInstance + gl_BaseInstance),\n"
241 " 0.0, 1.0);\n"
242 "}\n";
243
244 ShCompileOptions compileOptions = {};
245 compileOptions.objectCode = true;
246 compileOptions.emulateGLBaseVertexBaseInstance = true;
247
248 compile(shaderString, compileOptions);
249
250 // " angle_BaseVertex" (note the space) should appear exactly twice:
251 // once in the declaration and once in the body.
252 // The user-defined angle_BaseVertex should be decorated
253 EXPECT_TRUE(foundInCode(" angle_BaseVertex", 2));
254 EXPECT_TRUE(foundInCode(" angle_BaseInstance", 2));
255 }
256