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