1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * \file glcShaderGroupVoteTests.cpp
21 * \brief Conformance tests for the ARB_shader_group_vote functionality.
22 */ /*-------------------------------------------------------------------*/
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"
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)
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)
57 ShaderGroupVoteTestCaseBase::ComputeShader::~ComputeShader()
65 void ShaderGroupVoteTestCaseBase::ComputeShader::create(deqp::Context& context)
67 glu::ProgramSources sourcesCompute;
68 sourcesCompute.sources[glu::SHADERTYPE_COMPUTE].push_back(m_shader);
69 m_program = new glu::ShaderProgram(context.getRenderContext(), sourcesCompute);
71 if (!m_program->isOk())
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");
80 void ShaderGroupVoteTestCaseBase::ComputeShader::execute(deqp::Context& context)
87 const glw::Functions& gl = context.getRenderContext().getFunctions();
88 const glu::Texture outputTexture(context.getRenderContext());
90 gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
91 gl.clear(GL_COLOR_BUFFER_BIT);
93 gl.useProgram(m_program->getProgram());
94 GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram failed");
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");
104 gl.bindImageTexture(2, *outputTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
105 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture failed");
108 gl.dispatchCompute(1, 1, 1);
109 GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute failed");
111 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
112 const char* versionDeclaration = glu::getGLSLVersionDeclaration(glslVersion);
114 // render output texture
115 std::string vs = versionDeclaration;
117 "in highp vec2 position;\n"
118 "in highp vec2 inTexcoord;\n"
119 "out highp vec2 texcoord;\n"
122 " texcoord = inTexcoord;\n"
123 " gl_Position = vec4(position, 0.0, 1.0);\n"
126 std::string fs = versionDeclaration;
128 "uniform highp sampler2D sampler;\n"
129 "in highp vec2 texcoord;\n"
130 "out highp vec4 color;\n"
133 " color = texture(sampler, texcoord);\n"
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);
141 if (!m_program->isOk())
143 TCU_FAIL("Shader compilation failed");
146 gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
147 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
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");
153 gl.useProgram(renderShader.getProgram());
154 GLU_EXPECT_NO_ERROR(gl.getError(), "useProgram failed");
156 gl.uniform1i(gl.getUniformLocation(renderShader.getProgram(), "sampler"), 0);
157 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i failed");
159 deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
161 float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
163 float const texCoord[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
165 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
166 glu::va::Float("inTexcoord", 2, 4, 0, texCoord) };
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));
172 GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
177 void ShaderGroupVoteTestCaseBase::ComputeShader::validate(deqp::Context& context)
184 bool validationResult = validateScreenPixels(context, m_desiredColor);
185 std::string validationErrorMsg = "Validation failed for " + m_name + " test";
187 TCU_CHECK_MSG(validationResult, validationErrorMsg.c_str());
190 bool ShaderGroupVoteTestCaseBase::ComputeShader::validateScreenPixels(deqp::Context& context, tcu::IVec4 desiredColor)
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);
197 gl.readPixels(0, 0, RENDER_WIDTH, RENDER_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
199 // compare pixels to desired color
200 for (std::size_t i = 0; i < totalSize; i += 4)
202 if ((pixels[i + 0] != desiredColor.x()) || (pixels[i + 1] != desiredColor.y()) ||
203 (pixels[i + 2] != desiredColor.z()))
212 * @param context Rendering context
213 * @param name Test name
214 * @param description Test description
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)
221 glu::ContextType contextType = m_context.getRenderContext().getType();
222 m_specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(extParam.glslVersion);
224 if (glu::contextSupports(contextType, glu::ApiType::core(4, 6)))
226 m_specializationMap["GROUP_VOTE_EXTENSION"] = "";
227 m_specializationMap["EXT_TYPE"] = "";
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";
237 m_specializationMap["GROUP_VOTE_EXTENSION"] = extensionString.str();
238 m_specializationMap["EXT_TYPE"] = isCoreGL ? "ARB" : "EXT";
242 void ShaderGroupVoteTestCaseBase::init()
244 if (m_extensionSupported)
246 for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
248 (*iter)->create(m_context);
253 void ShaderGroupVoteTestCaseBase::deinit()
255 for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
261 tcu::TestNode::IterateResult ShaderGroupVoteTestCaseBase::iterate()
263 if (!m_extensionSupported)
265 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
269 for (ComputeShaderIter iter = m_shaders.begin(); iter != m_shaders.end(); ++iter)
271 (*iter)->execute(m_context);
272 (*iter)->validate(m_context);
275 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
281 * @param context Rendering context
283 ShaderGroupVoteAvailabilityTestCase::ShaderGroupVoteAvailabilityTestCase(deqp::Context& context,
284 ExtParameters& extParam)
285 : ShaderGroupVoteTestCaseBase(context, extParam, "availability", "Implements ...")
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"
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"
300 m_shaders.push_back(new ComputeShader("availability", specializeShader(1, &shader)));
305 * @param context Rendering context
306 * @param name Test name
307 * @param description Test description
309 ShaderGroupVoteFunctionTestCaseBase::ShaderGroupVoteFunctionTestCaseBase(deqp::Context& context,
310 ExtParameters& extParam, const char* name,
311 const char* description)
312 : ShaderGroupVoteTestCaseBase(context, extParam, name, description)
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"
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"
328 * @param context Rendering context
330 ShaderGroupVoteAllInvocationsTestCase::ShaderGroupVoteAllInvocationsTestCase(deqp::Context& context,
331 ExtParameters& extParam)
332 : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "all_invocations", "Implements ...")
334 const char* shaderBase = m_shaderBase.c_str();
335 m_specializationMap["FUNC"] = "allInvocations";
336 m_specializationMap["FUNC_PARAMETER"] = "true";
339 new ComputeShader("allInvocationsARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
344 * @param context Rendering context
346 ShaderGroupVoteAnyInvocationTestCase::ShaderGroupVoteAnyInvocationTestCase(deqp::Context& context,
347 ExtParameters& extParam)
348 : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "any_invocation", "Implements ...")
350 const char* shaderBase = m_shaderBase.c_str();
351 m_specializationMap["FUNC"] = "anyInvocation";
352 m_specializationMap["FUNC_PARAMETER"] = "false";
355 new ComputeShader("anyInvocationARB", specializeShader(1, &shaderBase), tcu::IVec4(0, 0, 0, 255)));
360 * @param context Rendering context
362 ShaderGroupVoteAllInvocationsEqualTestCase::ShaderGroupVoteAllInvocationsEqualTestCase(deqp::Context& context,
363 ExtParameters& extParam)
364 : ShaderGroupVoteFunctionTestCaseBase(context, extParam, "all_invocations_equal", "Implements ...")
366 const char* shaderBase = m_shaderBase.c_str();
367 m_specializationMap["FUNC"] = "allInvocationsEqual";
368 m_specializationMap["FUNC_PARAMETER"] = "true";
370 new ComputeShader("allInvocationsEqualARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
372 m_specializationMap["FUNC"] = "allInvocationsEqual";
373 m_specializationMap["FUNC_PARAMETER"] = "false";
375 new ComputeShader("allInvocationsEqualARB", specializeShader(1, &shaderBase), tcu::IVec4(255, 255, 255, 255)));
380 * @param context Rendering context.
382 ShaderGroupVote::ShaderGroupVote(deqp::Context& context)
383 : TestCaseGroup(context, "shader_group_vote",
384 "Verify conformance of shader_group_vote functionality implementation")
388 /** Initializes the test group contents. */
389 void ShaderGroupVote::init()
391 glu::GLSLVersion glslVersion = getContextTypeGLSLVersion(m_context.getRenderContext().getType());
392 ExtParameters extParam = glcts::ExtParameters(glslVersion, glcts::EXTENSIONTYPE_EXT);
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));
399 } /* glcts namespace */