xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/EmulateGLDrawID_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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