blob: c2f8036b76c37449c198198c8111e33245502c1c [file] [log] [blame]
Martin Radev4c4c8e72016-08-04 12:25:34 +03001//
2// Copyright 2016 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// ComputeShaderTest:
7// Compute shader specific tests.
8
9#include "test_utils/ANGLETest.h"
10#include "test_utils/gl_raii.h"
11#include <vector>
12
13using namespace angle;
14
15namespace
16{
17
18class ComputeShaderTest : public ANGLETest
19{
20 protected:
21 ComputeShaderTest() {}
22};
23
Xinghua Cao2b396592017-03-29 15:36:04 +080024class DispatchComputeTest : public ANGLETest
25{
26 protected:
27 DispatchComputeTest() {}
28};
29
Martin Radev4c4c8e72016-08-04 12:25:34 +030030class ComputeShaderTestES3 : public ANGLETest
31{
32 protected:
33 ComputeShaderTestES3() {}
34};
35
36// link a simple compute program. It should be successful.
37TEST_P(ComputeShaderTest, LinkComputeProgram)
38{
39 const std::string csSource =
40 "#version 310 es\n"
41 "layout(local_size_x=1) in;\n"
42 "void main()\n"
43 "{\n"
44 "}\n";
45
46 ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
47
48 EXPECT_GL_NO_ERROR();
49}
50
51// link a simple compute program. There is no local size and linking should fail.
52TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError)
53{
54 const std::string csSource =
55 "#version 310 es\n"
56 "void main()\n"
57 "{\n"
58 "}\n";
59
60 GLuint program = CompileComputeProgram(csSource, false);
61 EXPECT_EQ(0u, program);
62
63 glDeleteProgram(program);
64
65 EXPECT_GL_NO_ERROR();
66}
67
68// link a simple compute program.
69// make sure that uniforms and uniform samplers get recorded
70TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms)
71{
72 const std::string csSource =
73 "#version 310 es\n"
74 "precision mediump sampler2D;\n"
75 "layout(local_size_x=1) in;\n"
76 "uniform int myUniformInt;\n"
77 "uniform sampler2D myUniformSampler;\n"
78 "void main()\n"
79 "{\n"
80 "int q = myUniformInt;\n"
81 "texture(myUniformSampler, vec2(0.0));\n"
82 "}\n";
83
84 ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
85
86 GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
87 EXPECT_NE(-1, uniformLoc);
88
89 uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
90 EXPECT_NE(-1, uniformLoc);
91
92 EXPECT_GL_NO_ERROR();
93}
94
95// Attach both compute and non-compute shaders. A link time error should occur.
96// OpenGL ES 3.10, 7.3 Program Objects
97TEST_P(ComputeShaderTest, AttachMultipleShaders)
98{
99 const std::string csSource =
100 "#version 310 es\n"
101 "layout(local_size_x=1) in;\n"
102 "void main()\n"
103 "{\n"
104 "}\n";
105
106 const std::string vsSource =
107 "#version 310 es\n"
108 "void main()\n"
109 "{\n"
110 "}\n";
111
112 const std::string fsSource =
113 "#version 310 es\n"
114 "void main()\n"
115 "{\n"
116 "}\n";
117
118 GLuint program = glCreateProgram();
119
120 GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
121 GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
122 GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
123
124 EXPECT_NE(0u, vs);
125 EXPECT_NE(0u, fs);
126 EXPECT_NE(0u, cs);
127
128 glAttachShader(program, vs);
129 glDeleteShader(vs);
130
131 glAttachShader(program, fs);
132 glDeleteShader(fs);
133
134 glAttachShader(program, cs);
135 glDeleteShader(cs);
136
137 glLinkProgram(program);
138
139 GLint linkStatus;
140 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
141
142 EXPECT_EQ(0, linkStatus);
143
144 EXPECT_GL_NO_ERROR();
145}
146
147// Attach a vertex, fragment and compute shader.
148// Query for the number of attached shaders and check the count.
149TEST_P(ComputeShaderTest, AttachmentCount)
150{
Martin Radev4c4c8e72016-08-04 12:25:34 +0300151 const std::string csSource =
152 "#version 310 es\n"
153 "layout(local_size_x=1) in;\n"
154 "void main()\n"
155 "{\n"
156 "}\n";
157
158 const std::string vsSource =
159 "#version 310 es\n"
160 "void main()\n"
161 "{\n"
162 "}\n";
163
164 const std::string fsSource =
165 "#version 310 es\n"
166 "void main()\n"
167 "{\n"
168 "}\n";
169
170 GLuint program = glCreateProgram();
171
172 GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
173 GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
174 GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
175
176 EXPECT_NE(0u, vs);
177 EXPECT_NE(0u, fs);
178 EXPECT_NE(0u, cs);
179
180 glAttachShader(program, vs);
181 glDeleteShader(vs);
182
183 glAttachShader(program, fs);
184 glDeleteShader(fs);
185
186 glAttachShader(program, cs);
187 glDeleteShader(cs);
188
189 GLint numAttachedShaders;
190 glGetProgramiv(program, GL_ATTACHED_SHADERS, &numAttachedShaders);
191
192 EXPECT_EQ(3, numAttachedShaders);
193
194 glDeleteProgram(program);
195
196 EXPECT_GL_NO_ERROR();
197}
198
Xinghua Caob1239382016-12-13 15:07:05 +0800199// Access all compute shader special variables.
200TEST_P(ComputeShaderTest, AccessAllSpecialVariables)
201{
202 const std::string csSource =
203 "#version 310 es\n"
204 "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
205 "void main()\n"
206 "{\n"
207 " uvec3 temp1 = gl_NumWorkGroups;\n"
208 " uvec3 temp2 = gl_WorkGroupSize;\n"
209 " uvec3 temp3 = gl_WorkGroupID;\n"
210 " uvec3 temp4 = gl_LocalInvocationID;\n"
211 " uvec3 temp5 = gl_GlobalInvocationID;\n"
212 " uint temp6 = gl_LocalInvocationIndex;\n"
213 "}\n";
214
215 ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
216}
217
218// Access part compute shader special variables.
219TEST_P(ComputeShaderTest, AccessPartSpecialVariables)
220{
221 const std::string csSource =
222 "#version 310 es\n"
223 "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
224 "void main()\n"
225 "{\n"
226 " uvec3 temp1 = gl_WorkGroupSize;\n"
227 " uvec3 temp2 = gl_WorkGroupID;\n"
228 " uint temp3 = gl_LocalInvocationIndex;\n"
229 "}\n";
230
231 ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
232}
233
Xinghua Cao2b396592017-03-29 15:36:04 +0800234// TODO(Xinghua): A temporary test for glDispatchCompute, remove and merge it
235// ComputeShaderTest after implementing this API on D3D backend.
236TEST_P(DispatchComputeTest, DispatchCompute)
237{
238 const std::string csSource =
239 "#version 310 es\n"
240 "layout(local_size_x=4, local_size_y=3, local_size_z=2) in;\n"
241 "void main()\n"
242 "{\n"
243 " uvec3 temp1 = gl_NumWorkGroups;\n"
244 "}\n";
245
246 ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
247
248 glUseProgram(program.get());
249 glDispatchCompute(8, 4, 2);
250 EXPECT_GL_NO_ERROR();
251}
252
Martin Radev4c4c8e72016-08-04 12:25:34 +0300253// Check that it is not possible to create a compute shader when the context does not support ES
254// 3.10
255TEST_P(ComputeShaderTestES3, NotSupported)
256{
257 GLuint computeShaderHandle = glCreateShader(GL_COMPUTE_SHADER);
258 EXPECT_EQ(0u, computeShaderHandle);
259 EXPECT_GL_ERROR(GL_INVALID_ENUM);
260}
261
Xinghua Caob1239382016-12-13 15:07:05 +0800262ANGLE_INSTANTIATE_TEST(ComputeShaderTest, ES31_OPENGL(), ES31_OPENGLES(), ES31_D3D11());
Xinghua Cao2b396592017-03-29 15:36:04 +0800263ANGLE_INSTANTIATE_TEST(DispatchComputeTest, ES31_OPENGL(), ES31_OPENGLES());
Martin Radev4c4c8e72016-08-04 12:25:34 +0300264ANGLE_INSTANTIATE_TEST(ComputeShaderTestES3, ES3_OPENGL(), ES3_OPENGLES());
265
266} // namespace