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