• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SPIRV_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_HLSL
99     EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
100     EXPECT_TRUE(foundInCode(SH_HLSL_3_0_OUTPUT, "uniform int angle_DrawID : register"));
101 #endif
102 }
103 
104 // Check that a user-defined "gl_DrawID" is not permitted
TEST_F(EmulateGLDrawIDTest,DisallowsUserDefinedGLDrawID)105 TEST_F(EmulateGLDrawIDTest, DisallowsUserDefinedGLDrawID)
106 {
107     // Check that it is not permitted without the extension
108     CheckCompileFailure(
109         "uniform int gl_DrawID;\n"
110         "void main() {\n"
111         "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
112         "}\n",
113         "reserved built-in name");
114 
115     CheckCompileFailure(
116         "void main() {\n"
117         "   int gl_DrawID = 0;\n"
118         "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
119         "}\n",
120         "reserved built-in name");
121 
122     // Check that it is not permitted with the extension
123     CheckCompileFailure(
124         "#extension GL_ANGLE_multi_draw : require\n"
125         "uniform int gl_DrawID;\n"
126         "void main() {\n"
127         "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
128         "}\n",
129         "reserved built-in name");
130 
131     CheckCompileFailure(
132         "#extension GL_ANGLE_multi_draw : require\n"
133         "void main() {\n"
134         "   int gl_DrawID = 0;\n"
135         "   gl_Position = vec4(float(gl_DrawID), 0.0, 0.0, 1.0);\n"
136         "}\n",
137         "reserved built-in name");
138 }
139 
140 // gl_DrawID is translated to angle_DrawID internally. Check that a user-defined
141 // angle_DrawID is permitted
TEST_F(EmulateGLDrawIDTest,AllowsUserDefinedANGLEDrawID)142 TEST_F(EmulateGLDrawIDTest, AllowsUserDefinedANGLEDrawID)
143 {
144     addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
145     addOutputType(SH_ESSL_OUTPUT);
146 #ifdef ANGLE_ENABLE_VULKAN
147     addOutputType(SH_SPIRV_VULKAN_OUTPUT);
148 #endif
149 #ifdef ANGLE_ENABLE_HLSL
150     addOutputType(SH_HLSL_3_0_OUTPUT);
151     addOutputType(SH_HLSL_3_0_OUTPUT);
152 #endif
153 
154     const std::string &shaderString =
155         "#extension GL_ANGLE_multi_draw : require\n"
156         "uniform int angle_DrawID;\n"
157         "void main() {\n"
158         "   gl_Position = vec4(float(angle_DrawID + gl_DrawID), 0.0, 0.0, 1.0);\n"
159         "}\n";
160 
161     compile(shaderString, SH_OBJECT_CODE | SH_VARIABLES | SH_EMULATE_GL_DRAW_ID);
162 
163     // " angle_DrawID" (note the space) should appear exactly twice:
164     //    once in the declaration and once in the body.
165     // The user-defined angle_DrawID should be decorated
166     EXPECT_TRUE(foundInCode(" angle_DrawID", 2));
167 }
168