Remove mod from GL mustpass
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcShaderGroupVoteTests.cpp
1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file  glcShaderGroupVoteTests.cpp
21 * \brief Conformance tests for the ARB_shader_group_vote functionality.
22 */ /*-------------------------------------------------------------------*/
23
24 #include "glcShaderGroupVoteTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluDefs.hpp"
27 #include "gluDrawUtil.hpp"
28 #include "gluObjectWrapper.hpp"
29 #include "gluShaderProgram.hpp"
30 #include "glwEnums.hpp"
31 #include "glwFunctions.hpp"
32 #include "tcuRenderTarget.hpp"
33 #include "tcuTestLog.hpp"
34
35 using namespace glw;
36
37 namespace glcts
38 {
39
40 enum TextureSize
41 {
42         RENDER_WIDTH  = 16,
43         RENDER_HEIGHT = 16
44 };
45
46 ShaderGroupVoteTestCaseBase::ComputeShader::ComputeShader(const std::string& name, const std::string& shader)
47         : m_name(name), m_shader(shader), m_program(NULL), m_compileOnly(true)
48 {
49 }
50
51 ShaderGroupVoteTestCaseBase::ComputeShader::ComputeShader(const std::string& name, const std::string& shader,
52                                                                                                                   const tcu::IVec4& desiredColor)
53         : m_name(name), m_shader(shader), m_program(NULL), m_desiredColor(desiredColor), m_compileOnly(false)
54 {
55 }
56
57 ShaderGroupVoteTestCaseBase::ComputeShader::~ComputeShader()
58 {
59         if (m_program)
60         {
61                 delete m_program;
62         }
63 }
64
65 void ShaderGroupVoteTestCaseBase::ComputeShader::create(deqp::Context& context)
66 {
67         glu::ProgramSources sourcesCompute;
68         sourcesCompute.sources[glu::SHADERTYPE_COMPUTE].push_back(m_shader);
69         m_program = new glu::ShaderProgram(context.getRenderContext(), sourcesCompute);
70
71         if (!m_program->isOk())
72         {
73                 context.getTestContext().getLog()
74                         << tcu::TestLog::Message << m_shader << m_program->getShaderInfo(glu::SHADERTYPE_COMPUTE).infoLog
75                         << m_program->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
76                 TCU_FAIL("Shader compilation failed");
77         }
78 }
79
80 void ShaderGroupVoteTestCaseBase::ComputeShader::execute(deqp::Context& context)
81 {
82         if (m_compileOnly)
83         {
84                 return;
85         }
86
87         const glw::Functions& gl = context.getRenderContext().getFunctions();
88         const glu::Texture      outputTexture(context.getRenderContext());
89
90         gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
91         gl.clear(GL_COLOR_BUFFER_BIT);
92
93         gl.useProgram(m_program->getProgram());
94         GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram failed");
95
96         // output image
97         gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
98         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, RENDER_WIDTH, RENDER_HEIGHT);
99         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
101         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
102
103         // bind image
104         gl.bindImageTexture(2, *outputTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
105         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture failed");
106
107         // dispatch compute
108         gl.dispatchCompute(1, 1, 1);
109         GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute failed");
110
111         glu::GLSLVersion glslVersion            = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
112         const char*              versionDeclaration = glu::getGLSLVersionDeclaration(glslVersion);
113
114         // render output texture
115         std::string vs = versionDeclaration;
116         vs += "\n"
117                   "in highp vec2 position;\n"
118                   "in highp vec2 inTexcoord;\n"
119                   "out highp vec2 texcoord;\n"
120                   "void main()\n"
121                   "{\n"
122                   "     texcoord = inTexcoord;\n"
123                   "     gl_Position = vec4(position, 0.0, 1.0);\n"
124                   "}\n";
125
126         std::string fs = versionDeclaration;
127         fs += "\n"
128                   "uniform highp sampler2D sampler;\n"
129                   "in highp vec2 texcoord;\n"
130                   "out highp vec4 color;\n"
131                   "void main()\n"
132                   "{\n"
133                   "     color = texture(sampler, texcoord);\n"
134                   "}\n";
135
136         glu::ProgramSources sources;
137         sources.sources[glu::SHADERTYPE_VERTEX].push_back(vs);
138         sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(fs);
139         glu::ShaderProgram renderShader(context.getRenderContext(), sources);
140
141         if (!m_program->isOk())
142         {
143                 TCU_FAIL("Shader compilation failed");
144         }
145
146         gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
147         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
148
149         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
150         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
151         GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri failed");
152
153         gl.useProgram(renderShader.getProgram());
154         GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram failed");
155
156         gl.uniform1i(gl.getUniformLocation(renderShader.getProgram(), "sampler"), 0);
157         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i failed");
158
159         deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
160
161         float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
162
163         float const texCoord[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
164
165         glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
166                                                                                            glu::va::Float("inTexcoord", 2, 4, 0, texCoord) };
167
168         gl.viewport(0, 0, RENDER_WIDTH, RENDER_HEIGHT);
169         glu::draw(context.getRenderContext(), renderShader.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
170                           glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
171
172         GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
173
174         gl.flush();
175 }
176
177 void ShaderGroupVoteTestCaseBase::ComputeShader::validate(deqp::Context& context)
178 {
179         if (m_compileOnly)
180         {
181                 return;
182         }
183
184         bool            validationResult   = validateScreenPixels(context, m_desiredColor);
185         std::string validationErrorMsg = "Validation failed for " + m_name + " test";
186
187         TCU_CHECK_MSG(validationResult, validationErrorMsg.c_str());
188 }
189
190 bool ShaderGroupVoteTestCaseBase::ComputeShader::validateScreenPixels(deqp::Context& context, tcu::IVec4 desiredColor)
191 {
192         const glw::Functions&    gl             = context.getRenderContext().getFunctions();
193         std::size_t                               totalSize = RENDER_WIDTH * RENDER_HEIGHT * 4;
194         std::vector<glw::GLubyte> pixels(totalSize, 128);
195
196         // read pixels
197         gl.readPixels(0, 0, RENDER_WIDTH, RENDER_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
198
199         // compare pixels to desired color
200         for (std::size_t i = 0; i < totalSize; i += 4)
201         {
202                 if ((pixels[i + 0] != desiredColor.x()) || (pixels[i + 1] != desiredColor.y()) ||
203                         (pixels[i + 2] != desiredColor.z()))
204                         return false;
205         }
206
207         return true;
208 }
209
210 /** Constructor.
211 *
212 *  @param context Rendering context
213 *  @param name Test name
214 *  @param description Test description
215 */
216 ShaderGroupVoteTestCaseBase::ShaderGroupVoteTestCaseBase(deqp::Context& context, ExtParameters& extParam,
217                                                                                                                  const char* name, const char* description)
218         : TestCaseBase(context, glcts::ExtParameters(glu::GLSL_VERSION_450, glcts::EXTENSIONTYPE_EXT), name, description)
219         , m_extensionSupported(true)
220 {
221         glu::ContextType contextType   = m_context.getRenderContext().getType();
222         m_specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(extParam.glslVersion);
223
224         if (glu::contextSupports(contextType, glu::ApiType::core(4, 6)))
225         {
226                 m_specializationMap["GROUP_VOTE_EXTENSION"] = "";
227                 m_specializationMap["EXT_TYPE"]                         = "";
228         }
229         else
230         {
231                 bool            isCoreGL          = glu::isContextTypeGLCore(contextType);
232                 std::string extensionName = isCoreGL ? "GL_ARB_shader_group_vote" : "GL_EXT_shader_group_vote";
233                 m_extensionSupported      = context.getContextInfo().isExtensionSupported(extensionName.c_str());
234                 std::stringstream extensionString;
235                 extensionString << "#extension " + extensionName + " : enable";
236
237                 m_specializationMap["GROUP_VOTE_EXTENSION"] = extensionString.str();
238                 m_specializationMap["EXT_TYPE"]                         = isCoreGL ? "ARB" : "EXT";
239         }
240 }
241
242 void ShaderGroupVoteTestCaseBase::init()
243 {
244         if (m_extensionSupported)
245         {
246                 for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
247                 {
248                         (*iter)->create(m_context);
249                 }
250         }
251 }
252
253 void ShaderGroupVoteTestCaseBase::deinit()
254 {
255         for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
256         {
257                 delete (*iter);
258         }
259 }
260
261 tcu::TestNode::IterateResult ShaderGroupVoteTestCaseBase::iterate()
262 {
263         if (!m_extensionSupported)
264         {
265                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
266                 return STOP;
267         }
268
269         for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
270         {
271                 (*iter)->execute(m_context);
272                 (*iter)->validate(m_context);
273         }
274
275         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
276         return STOP;
277 }
278
279 /** Constructor.
280 *
281 *  @param context Rendering context
282 */
283 ShaderGroupVoteAvailabilityTestCase::ShaderGroupVoteAvailabilityTestCase(deqp::Context& context,
284                                                                                                                                                  ExtParameters& extParam)
285         : ShaderGroupVoteTestCaseBase(context, extParam, "availability", "Implements ...")
286 {
287         const char* shader = "${VERSION}\n"
288                                                  "${GROUP_VOTE_EXTENSION}\n"
289                                                  "layout(rgba8, binding = 2) writeonly uniform highp image2D destImage;\n"
290                                                  "layout(local_size_x = 16, local_size_y = 16) in;\n"
291                                                  "void main (void)\n"
292                                                  "{\n"
293                                                  "      vec4 outColor = vec4(0.0);\n"
294                                                  "      outColor.r = allInvocations${EXT_TYPE}(true) ? 1.0 : 0.0;\n"
295                                                  "      outColor.g = anyInvocation${EXT_TYPE}(true) ? 1.0 : 0.0;\n"
296                                                  "      outColor.b = allInvocationsEqual${EXT_TYPE}(true) ? 1.0 : 0.0;\n"
297                                                  "      imageStore(destImage, ivec2(gl_GlobalInvocationID.xy), outColor);\n"
298                                                  "}\n";
299
300         m_shaders.push_back(new ComputeShader("availability", specializeShader(1, &shader)));
301 }
302
303 /** Constructor.
304 *
305 *  @param context Rendering context
306 *  @param name Test name
307 *  @param description Test description
308 */
309 ShaderGroupVoteFunctionTestCaseBase::ShaderGroupVoteFunctionTestCaseBase(deqp::Context& context,
310                                                                                                                                                  ExtParameters& extParam, const char* name,
311                                                                                                                                                  const char* description)
312         : ShaderGroupVoteTestCaseBase(context, extParam, name, description)
313 {
314         m_shaderBase += "${VERSION}\n"
315                                         "${GROUP_VOTE_EXTENSION}\n"
316                                         "layout(rgba8, binding = 2) writeonly uniform highp image2D destImage;\n"
317                                         "layout(local_size_x = 16, local_size_y = 16) in;\n"
318                                         "void main (void)\n"
319                                         "{\n"
320                                         "       bool result = ${FUNC}${EXT_TYPE}(${FUNC_PARAMETER});\n"
321                                         "       vec4 outColor = vec4(vec3(result ? 1.0 : 0.0), 1.0);\n"
322                                         "       imageStore(destImage, ivec2(gl_GlobalInvocationID.xy), outColor);\n"
323                                         "}\n";
324 }
325
326 /** Constructor.
327 *
328 *  @param context Rendering context
329 */
330 ShaderGroupVoteAllInvocationsTestCase::ShaderGroupVoteAllInvocationsTestCase(deqp::Context& context,
331                                                                                                                                                          ExtParameters& extParam)
332         : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "all_invocations", "Implements ...")
333 {
334         const char* shaderBase                            = m_shaderBase.c_str();
335         m_specializationMap["FUNC"]                       = "allInvocations";
336         m_specializationMap["FUNC_PARAMETER"] = "true";
337
338         m_shaders.push_back(
339                 new ComputeShader("allInvocationsARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
340 }
341
342 /** Constructor.
343 *
344 *  @param context Rendering context
345 */
346 ShaderGroupVoteAnyInvocationTestCase::ShaderGroupVoteAnyInvocationTestCase(deqp::Context& context,
347                                                                                                                                                    ExtParameters& extParam)
348         : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "any_invocation", "Implements ...")
349 {
350         const char* shaderBase                            = m_shaderBase.c_str();
351         m_specializationMap["FUNC"]                       = "anyInvocation";
352         m_specializationMap["FUNC_PARAMETER"] = "false";
353
354         m_shaders.push_back(
355                 new ComputeShader("anyInvocationARB", specializeShader(1, &shaderBase), tcu::IVec4(0, 0, 0, 255)));
356 }
357
358 /** Constructor.
359 *
360 *  @param context Rendering context
361 */
362 ShaderGroupVoteAllInvocationsEqualTestCase::ShaderGroupVoteAllInvocationsEqualTestCase(deqp::Context& context,
363                                                                                                                                                                            ExtParameters& extParam)
364         : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "all_invocations_equal", "Implements ...")
365 {
366         const char* shaderBase                            = m_shaderBase.c_str();
367         m_specializationMap["FUNC"]                       = "allInvocationsEqual";
368         m_specializationMap["FUNC_PARAMETER"] = "true";
369         m_shaders.push_back(
370                 new ComputeShader("allInvocationsEqualARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
371
372         m_specializationMap["FUNC"]                       = "allInvocationsEqual";
373         m_specializationMap["FUNC_PARAMETER"] = "false";
374         m_shaders.push_back(
375                 new ComputeShader("allInvocationsEqualARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
376 }
377
378 /** Constructor.
379 *
380 *  @param context Rendering context.
381 */
382 ShaderGroupVote::ShaderGroupVote(deqp::Context& context)
383         : TestCaseGroup(context, "shader_group_vote",
384                                         "Verify conformance of shader_group_vote functionality implementation")
385 {
386 }
387
388 /** Initializes the test group contents. */
389 void ShaderGroupVote::init()
390 {
391         glu::GLSLVersion glslVersion = getContextTypeGLSLVersion(m_context.getRenderContext().getType());
392         ExtParameters   extParam        = glcts::ExtParameters(glslVersion, glcts::EXTENSIONTYPE_EXT);
393
394         addChild(new ShaderGroupVoteAvailabilityTestCase(m_context, extParam));
395         addChild(new ShaderGroupVoteAllInvocationsTestCase(m_context, extParam));
396         addChild(new ShaderGroupVoteAnyInvocationTestCase(m_context, extParam));
397         addChild(new ShaderGroupVoteAllInvocationsEqualTestCase(m_context, extParam));
398 }
399 } /* glcts namespace */