/** @brief Function prepares texture object with test's data.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void TextureCubeMapArrayETC2Support::prepareTexture()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture call failed.");

	/* Texture creation and binding. */
	gl.genTextures(1, &m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures call failed.");

	const glw::GLuint target = GL_TEXTURE_CUBE_MAP_ARRAY;
	gl.bindTexture(target, m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture call failed.");

	/* Uploading texture. */
	gl.compressedTexImage3D(target, 0, GL_COMPRESSED_RGB8_ETC2, RENDER_WIDTH, RENDER_HEIGHT, 6, 0,
							s_compressed_RGB_texture_data_size, s_compressed_RGB_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D call failed.");

	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
}
/** Takes a texture ID, binds it to GL_TEXTURE_CUBE_MAP_ARRAY texture target and
 *  initializes an immutable texture storage of @param texture_size x @param texture_size
 *  x (@param n_elements * 6) resolution.
 *
 * @param texture_id                           ID to use for the initialization.
 * @param texture_size                         Width & height to use for each layer-face.
 * @param n_cubemaps                           Amount of cube-maps to initialize.
 * @param should_take_color_texture_properties true if m_color_internal_format, m_color_format,
 *                                             m_color_type should be used for texture storage
 *                                             initialization, false to use relevant m_depth_*
 *                                             fields.
 **/
void TextureCubeMapArrayColorDepthAttachmentsTest::prepareImmutableTextureObject(
	glw::GLuint texture_id, glw::GLuint texture_size, glw::GLuint n_cubemaps, bool should_take_color_texture_properties)
{
	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
	glw::GLenum			  internal_format = GL_NONE;

	/* Set internal_format accordingly to requested texture type */
	if (true == should_take_color_texture_properties)
	{
		internal_format = m_color_internal_format;
	}
	else
	{
		internal_format = m_depth_internal_format;
	}

	/* Bind the texture object to GL_TEXTURE_CUBE_MAP_ARRAY texture target. */
	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	/* Initialize immutable texture storage as per description */
	gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, /* n_mipmap_levels */
					internal_format, texture_size, texture_size, n_cubemaps * 6 /* layer-faces per cube-map */);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
}
示例#3
0
/** Setup frame buffer:
 * 1 allocate texture storage for specified format and dimensions,
 * 2 bind framebuffer and attach texture to GL_COLOR_ATTACHMENT0
 * 3 setup viewport to specified dimensions
 *
 * @param framebuffer_object_id FBO handle
 * @param color_texture_id      Texture handle
 * @param texture_format        Requested texture format, eg. GL_RGBA8
 * @param texture_width         Requested texture width
 * @param texture_height        Requested texture height
 *
 * @return true  All operations succeded
 *         false In case of any error
 **/
bool TestCaseBase::setupFramebufferWithTextureAsAttachment(glw::GLuint framebuffer_object_id,
														   glw::GLuint color_texture_id, glw::GLenum texture_format,
														   glw::GLuint texture_width, glw::GLuint texture_height) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Allocate texture storage */
	gl.bindTexture(GL_TEXTURE_2D, color_texture_id);
	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, texture_format, texture_width, texture_height);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate texture storage!");

	/* Setup framebuffer */
	gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_id, 0 /* level */);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup framebuffer!");

	/* Setup viewport */
	gl.viewport(0, 0, texture_width, texture_height);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup viewport!");

	/* Success */
	return true;
}
void ShaderMultiDrawElementsIndirectParametersTestCase::initChild()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	// Set expected result vector [x, y, red, green, blue]
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.05f, -1.0f + 0.05f, 1.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.05f, -1.0f + 0.15f, 1.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.15f, -1.0f + 0.05f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.15f, -1.0f + 0.15f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.05f, -0.8f + 0.05f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.05f, -0.8f + 0.15f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.15f, -0.8f + 0.05f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-1.0f + 0.15f, -0.8f + 0.15f, 0.0f, 1.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-0.8f + 0.05f, -1.0f + 0.05f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-0.8f + 0.05f, -1.0f + 0.15f, 0.0f, 0.0f, 1.0f));
	m_resultPoints.push_back(ResultPoint(-0.8f + 0.15f, -1.0f + 0.05f, 0.0f, 0.0f, 0.0f));
	m_resultPoints.push_back(ResultPoint(-0.8f + 0.15f, -1.0f + 0.15f, 0.0f, 0.0f, 0.0f));

	const SDPDrawElementsIndirectCommand indirect[] = {
		{ 4, 1, 0, 0, 0 }, { 3, 1, 3, 0, 1 }, { 3, 1, 0, 1, 0 },
	};

	// Setup indirect command buffer
	gl.genBuffers(1, &m_drawIndirectBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");

	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");

	gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 3 * sizeof(SDPDrawElementsIndirectCommand), indirect, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
}
/** Releases a texture object and detaches it from test-maintained draw framebuffer.
 *
 * @param texture_id          Id of the texture object;
 * @param is_color_attachment true if the texture object described by id @param texture_id
 *                            is current draw framebuffer's color attachment, false if it's
 *                            a depth attachment.
 **/
void TextureCubeMapArrayColorDepthAttachmentsTest::releaseAndDetachTextureObject(glw::GLuint texture_id,
																				 bool		 is_color_attachment)
{
	glw::GLenum			  attachment = GL_NONE;
	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();

	if (true == is_color_attachment)
	{
		attachment = GL_COLOR_ATTACHMENT0;
	}
	else
	{
		attachment = GL_DEPTH_ATTACHMENT;
	}

	/* Update draw framewbuffer binding just in case. */
	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");

	/* Clean framebuffer's attachment */
	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, /* texture */
							0);												   /* level */
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");

	/* Unbind the texture object from GL_TEXTURE_CUBE_MAP_ARRAY binding point */
	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	/* Finally delete the texture object */
	gl.deleteTextures(1, &texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
}
void ShaderAtomicCounterOpsTestBase::bindBuffers()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_atomicCounterBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferBase() call failed.");

	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 1, m_atomicCounterCallsBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferBase() call failed.");
}
/** @brief Function generate and bind empty vertex array object.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void TextureCubeMapArrayETC2Support::prepareVertexArrayObject()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
}
void ShaderDrawArraysInstancedParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawArraysInstanced(GL_TRIANGLE_STRIP, 2, 4, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced");
}
void ShaderDrawArraysIndirectParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawArraysIndirect(GL_TRIANGLE_STRIP, (GLvoid*)0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysIndirect");
}
/** Verify rendered polygon anisotropy.
 *
 *  @param gl  OpenGL functions wrapper
 *
 *  @return Returns points value. Less points means better anisotropy (smoother strips).
 */
GLuint TextureFilterAnisotropicDrawingTestCase::verifyScene(const glw::Functions& gl)
{
	std::vector<GLubyte> pixels;
	pixels.resize(32 * 8 * 4);

	gl.readPixels(0, 23, 32, 8, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");

	GLuint sum = 0;

	GLubyte last	= 0;
	GLubyte current = 0;
	for (int j = 0; j < 8; ++j)
	{
		for (int i = 0; i < 32; ++i)
		{
			current = pixels[(i + j * 32) * 4];

			if (i > 0)
				sum += deAbs32((int)current - (int)last);

			last = current;
		}
	}

	return sum;
}
void ShaderDrawElementsInstancedParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawElementsInstanced(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_SHORT, (GLvoid*)0, 3);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstanced");
}
void ShaderDrawElementsParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.drawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (GLvoid*)(2 * sizeof(GLushort)));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements");
}
/** Releases existing color & depth cube-map texture array objects, generates new
 *  ones and configures them as per user-specified properties.
 *
 *  @param texture_width                    Size to use for each layer-face's width and height.
 *  @param n_cubemaps                       Number of cube-maps to initialize for the cube-map texture arrays.
 *  @param should_generate_mutable_textures true if the texture should be initialized as mutable, false otherwise.
 **/
void TextureCubeMapArrayColorDepthAttachmentsTest::generateAndConfigureTextureObjects(
	glw::GLuint texture_width, glw::GLuint n_cubemaps, bool should_generate_mutable_textures)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release any texture objects that may have already been initialized */
	releaseAndDetachTextureObject(m_color_texture_id, true /* is_color_attachment */);
	releaseAndDetachTextureObject(m_depth_texture_id, false /* is_color_attachment */);

	/* Generate texture objects */
	gl.genTextures(1, &m_color_texture_id);
	gl.genTextures(1, &m_depth_texture_id);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");

	/* Configure new textures' storage */
	if (true == should_generate_mutable_textures)
	{
		prepareMutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
									true /* should_take_color_texture_properties */);
		prepareMutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
									false /* should_take_color_texture_properties */);
	}
	else
	{
		prepareImmutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
									  true /* should_take_color_texture_properties */);
		prepareImmutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
									  false /* should_take_color_texture_properties */);
	}
}
/** Reads read buffer's depth data (assuming it's of 32-bit FP resolution)
 *  and verifies its correctness.
 *
 *  @param texture_size Texture size
 *  @param n_layer      Index of the layer to verify.
 *
 *  @return true if the retrieved data was found correct, false otherwise.
 **/
bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth32FData(const _texture_size& texture_size,
																	  glw::GLuint		   n_layer)
{
	/* Allocate buffer for the data we will retrieve from the implementation */
	glw::GLfloat		  expected_value   = (glw::GLfloat)n_layer / 256.0f;
	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
	bool				  result		   = false;
	const glw::GLuint	 result_data_size = texture_size.m_size * texture_size.m_size;
	glw::GLfloat*		  result_data	  = new glw::GLfloat[result_data_size];

	DE_ASSERT(result_data != NULL);

	/* Read the data */
	gl.readPixels(0, /* x */
				  0, /* y */
				  texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");

	/* Verify image, expected value is layer index */
	result = verifyImage<glw::GLfloat, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);

	/* Release the buffer */
	if (result_data != NULL)
	{
		delete[] result_data;

		result_data = NULL;
	}

	return result;
}
void ShaderMultiDrawArraysIndirectCountParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.multiDrawArraysIndirectCountARB(GL_TRIANGLE_STRIP, 0, 0, 3, sizeof(SDPDrawArraysIndirectCommand));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawArraysIndirect");
}
void ShaderMultiDrawElementsIndirectParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.multiDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, (GLvoid*)0, 3,
								 sizeof(SDPDrawElementsIndirectCommand));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElementsIndirect");
}
/** Execute a draw call that renders (texture_size.m_n_cubemaps * 6) points.
 *  First, the viewport is configured to match the texture resolution and
 *  both color & depth buffers are cleared.
 *
 *  @param texture_size Render-target resolution.
 *
 **/
void TextureCubeMapArrayColorDepthAttachmentsTest::draw(const _texture_size& texture_size)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Set up the viewport */
	gl.viewport(0, /* x */
				0, /* y */
				texture_size.m_size, texture_size.m_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");

	/* Clear color & depth buffers */
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

	gl.drawArrays(GL_POINTS, 0 /* first */, texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
}
示例#18
0
/** Retrieves compilation OR linking info log for a shader/program object with GLES id
 *  @param id.
 *
 *  @param is_compilation_info_log true if @param id is a GLES id of a shader object;
 *                                 false if it represents a program object.
 *  @param id                      GLES id of a shader OR a program object to
 *                                 retrieve info log for.
 *
 *  @return String instance containing the log..
 **/
std::string TestCaseBase::getInfoLog(LOG_TYPE log_type, glw::GLuint id)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLint n_characters = 0;
	/* Retrieve amount of characters needed to store the info log (terminator-inclusive) */
	switch (log_type)
	{
	case LT_SHADER_OBJECT:
		gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &n_characters);
		break;
	case LT_PROGRAM_OBJECT:
		gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &n_characters);
		break;
	case LT_PIPELINE_OBJECT:
		gl.getProgramPipelineiv(id, GL_INFO_LOG_LENGTH, &n_characters);
		break;
	default:
		TCU_FAIL("Invalid parameter");
	}

	/* Check if everything is fine so far */
	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query info log length!");

	/* Allocate buffer */
	std::vector<char> result_vec(n_characters + 1);

	/* Retrieve the info log */
	switch (log_type)
	{
	case LT_SHADER_OBJECT:
		gl.getShaderInfoLog(id, n_characters + 1, 0, &result_vec[0]);
		break;
	case LT_PROGRAM_OBJECT:
		gl.getProgramInfoLog(id, n_characters + 1, 0, &result_vec[0]);
		break;
	case LT_PIPELINE_OBJECT:
		gl.getProgramPipelineInfoLog(id, n_characters + 1, 0, &result_vec[0]);
		break;
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve info log!");

	return std::string(&result_vec[0]);
}
/** Set contents of texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param level           Mipmap level
 * @param internal_format Format of data
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 * @param format          Format of data
 * @param type            Type of data
 * @param data            Buffer with image data
 **/
void texImage(const Functions& gl, GLenum target, GLint level, GLenum internal_format, GLuint width, GLuint height,
			  GLuint depth, GLenum format, GLenum type, const GLvoid* data)
{
	switch (target)
	{
	case GL_TEXTURE_2D:
		gl.texImage2D(target, level, internal_format, width, height, 0 /* border */, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "texImage");
		break;
	case GL_TEXTURE_2D_ARRAY:
		gl.texImage3D(target, level, internal_format, width, height, depth, 0 /* border */, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "texImage");
		break;
	default:
		TCU_FAIL("Invalid enum");
		break;
	}
}
/** Set contents of texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param level           Mipmap level
 * @param x               X offset
 * @param y               Y offset
 * @param z               Z offset
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 * @param format          Format of data
 * @param type            Type of data
 * @param pixels          Buffer with image data
 **/
void subImage(const Functions& gl, GLenum target, GLint level, GLint x, GLint y, GLint z, GLsizei width, GLsizei height,
			  GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
	switch (target)
	{
	case GL_TEXTURE_2D:
		gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
		break;
	case GL_TEXTURE_2D_ARRAY:
		gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
		break;
	default:
		TCU_FAIL("Invalid enum");
		break;
	}
}
/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult MultisampleTextureSampleMaskiGettersTest::iterate()
{
	/* Get GL_MAX_SAMPLE_MASK_WORDS value */
	const glw::Functions& gl							 = m_context.getRenderContext().getFunctions();
	glw::GLint			  gl_max_sample_mask_words_value = 0;

	gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &gl_max_sample_mask_words_value);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_SAMPLE_MASK_WORDS value");

	/* Iterate over valid index & mask values */
	const glw::GLuint  valid_masks[] = { 0, 0xFFFFFFFF, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF };
	const unsigned int n_valid_masks = sizeof(valid_masks) / sizeof(valid_masks[0]);

	for (int index = 0; index < gl_max_sample_mask_words_value; ++index)
	{
		for (unsigned int n_mask = 0; n_mask < n_valid_masks; ++n_mask)
		{
			glw::GLint mask = valid_masks[n_mask];

			/* Make sure a valid glSampleMaski() call does not result in an error */
			gl.sampleMaski(index, mask);

			GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glSampleMaski() call resulted in an error");

			/* Check the property value as reported by implementation */
			glw::GLint int_value = -1;

			gl.getIntegeri_v(GL_SAMPLE_MASK_VALUE, index, &int_value);
			GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glGetIntegeri_v() call resulted in an error");

			if (int_value != mask)
			{
				TCU_FAIL("Invalid sample mask reported");
			}
		} /* for (all masks) */
	}	 /* for (all valid index argument values) */

	/* Test case passed */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return STOP;
}
void ShaderMultiDrawArraysParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	const GLint   dFirst[] = { 0, 1 };
	const GLsizei dCount[] = { 4, 4 };

	gl.multiDrawArrays(GL_TRIANGLE_STRIP, dFirst, dCount, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawArrays");
}
/** @brief Function draws a quad.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void TextureCubeMapArrayETC2Support::draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.viewport(0, 0, RENDER_WIDTH, RENDER_HEIGHT);

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
}
/** Executes the test.
 *
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  Note the function throws exception should an error occur!
 *
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 **/
tcu::TestCase::IterateResult TextureCubeMapArrayColorDepthAttachmentsTest::iterate()
{
	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Initialize all ES objects needed to run the test */
	initTest();

	/* Setup clear values */
	gl.clearColor(0.0f /* red */, 0.0f /* green */, 0.0f /* blue */, 0.0f /* alpha */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");

	gl.clearDepthf(1.0f /* d */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearDepthf() call failed.");

	/* Enable depth test */
	gl.enable(GL_DEPTH_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed");

	/* Execute tests for each resolution */
	for (_texture_size_vector::iterator texture_size_iterator = m_resolutions.begin(),
										end_iterator		  = m_resolutions.end();
		 end_iterator != texture_size_iterator; ++texture_size_iterator)
	{
		testNonLayeredRendering(*texture_size_iterator, false);
		testNonLayeredRendering(*texture_size_iterator, true);
		testLayeredRendering(*texture_size_iterator, false);
		testLayeredRendering(*texture_size_iterator, true);
	}

	/* Test passes if there were no errors */
	if ((0 != m_n_invalid_color_checks) || (0 != m_n_invalid_depth_checks))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}

	/* Done */
	return STOP;
}
void ShaderMultiDrawElementsParametersTestCase::drawCommand()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	const GLsizei dCount[]   = { 5, 4 };
	const GLvoid* dIndices[] = { (GLvoid*)(1 * sizeof(GLushort)), (GLvoid*)(1 * sizeof(GLushort)) };

	gl.multiDrawElements(GL_TRIANGLE_STRIP, dCount, GL_UNSIGNED_SHORT, dIndices, 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElements");
}
void ShaderAtomicCounterOpsTestBase::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// delete atomic counter buffer

	gl.deleteBuffers(1, &m_atomicCounterBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "deleteBuffers() call failed.");

	// delete atomic counter calls buffer

	gl.deleteBuffers(1, &m_atomicCounterCallsBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "deleteBuffers() call failed.");

	// delete operations

	for (AtomicOperationIter iter = m_operations.begin(); iter != m_operations.end(); ++iter)
	{
		delete *iter;
	}
}
/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult TextureFilterAnisotropicQueriesTestCase::iterate()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	GLuint texture;
	gl.genTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
	gl.bindTexture(GL_TEXTURE_2D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
	TextureFilterAnisotropicUtils::texImage(gl, GL_TEXTURE_2D, 0, GL_RGBA8, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

	if (verifyTexParameters(gl) && verifyGet(gl))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	gl.deleteTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");

	return STOP;
}
/** Drawing quads method using drawArrays.
 */
bool MultiDrawElementsIndirectCountCase::draw()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
	ShaderProgram  program(gl, sources);

	if (!program.isOk())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
						   << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
						   << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
						   << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
		return false;
	}

	gl.useProgram(program.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	gl.enable(GL_BLEND);
	gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	gl.enableVertexAttribArray(0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
	gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");

	gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, 0, 0, 2, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElementsIndirectCountARB");

	gl.disableVertexAttribArray(0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");

	gl.disable(GL_BLEND);

	return true;
}
void ShaderMetamorphicVariant::render (const tcu::PixelBufferAccess& img, const std::string& vertexSrc, const std::string& fragmentSrc)
{
	TestLog&				log		= m_testCtx.getLog();
	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();

	// Positions, shared between shaders
	const float positions[] =
	{
		-1.0f,  1.0f,	// top-left
		-1.0f, -1.0f,	// bottom-left
		 1.0f, -1.0f,	// bottom-right
		 1.0f,  1.0f,	// top-right
	};

	const deUint16 indices[] =
	{
		0, 1, 2,	// bottom-left triangle
		0, 3, 2,	// top-right triangle
	};

	glu::VertexArrayBinding posBinding = glu::va::Float("coord2d", 2, 6, 0, &positions[0]);

	const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSrc, fragmentSrc));
	log << program;

	if (!program.isOk())
		throw tcu::TestError("Compile failed");

	// Set uniforms expected in GraphicsFuzz generated programs
	gl.useProgram(program.getProgram());
	// Uniform: injectionSwitch
	int uniformLoc = gl.getUniformLocation(program.getProgram(), "injectionSwitch");
	if (uniformLoc != -1)
		gl.uniform2f(uniformLoc, 0.0f, 1.0f);
	// Uniform: resolution
	uniformLoc = gl.getUniformLocation(program.getProgram(), "resolution");
	if (uniformLoc != -1)
		gl.uniform2f(uniformLoc, glw::GLfloat(img.getWidth()), glw::GLfloat(img.getHeight()));
	// Uniform: mouse
	uniformLoc = gl.getUniformLocation(program.getProgram(), "mouse");
	if (uniformLoc != -1)
		gl.uniform2f(uniformLoc, 0.0f, 0.0f);
	// Uniform: time
	uniformLoc = gl.getUniformLocation(program.getProgram(), "time");
	if (uniformLoc != -1)
		gl.uniform1f(uniformLoc, 0.0f);

	// Render two times to check nondeterministic renderings
	glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding, glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
	glu::readPixels(m_context.getRenderContext(), 0, 0, img);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
}
void ShaderAtomicCounterOpsTestBase::ShaderPipeline::renderQuad(deqp::Context& context)
{
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };

	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };

	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, position) };

	this->use(context);

	glu::PrimitiveList primitiveList = glu::pr::Patches(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);

	glu::draw(context.getRenderContext(), this->getShaderProgram()->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
			  vertexArrays, primitiveList);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");

	gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier() error");
}