Ejemplo n.º 1
0
static void
create_shaders(void)
{
	prog_write_all_red = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs,
				GL_FRAGMENT_SHADER, fs_write_red,
				0);

	prog_write_all_different = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs,
				GL_FRAGMENT_SHADER, fs_write_different,
				0);
}
Ejemplo n.º 2
0
static bool
test_tes_params(void)
{
	bool pass = true;
	int i;

	for (i = 0; i < ARRAY_SIZE(tes_params); ++i) {
		prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_source,
				GL_TESS_EVALUATION_SHADER, tes_params[i].source,
				0);

		pass = test_param(GL_TESS_GEN_MODE,
				  tes_params[i].prim_mode,
				  tes_params[i].source) && pass;
		pass = test_param(GL_TESS_GEN_SPACING,
				  tes_params[i].vertex_spacing,
				  tes_params[i].source) && pass;
		pass = test_param(GL_TESS_GEN_VERTEX_ORDER,
				  tes_params[i].ordering,
				  tes_params[i].source) && pass;
		pass = test_param(GL_TESS_GEN_POINT_MODE,
				  tes_params[i].point_mode,
				  tes_params[i].source) && pass;

		glDeleteProgram(prog);
	}
	return pass;
}
Ejemplo n.º 3
0
/* Test subroutine uniform location query with vs, fs and gs. */
static bool
test_subroutine_stages_vs_fs_gs()
{
	GLuint prog, i;

	if (!piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
		piglit_report_subtest_result(PIGLIT_SKIP, __func__);
		return true;
	}

        prog = piglit_build_simple_program_multiple_shaders(
                     GL_VERTEX_SHADER, vs_subroutine_text,
                     GL_GEOMETRY_SHADER, gs_subroutine_text,
                     GL_FRAGMENT_SHADER, fs_subroutine_text,
                     0);

	glUseProgram(prog);

	/* Iterate through all valid subroutine enums passing invalid name. */
	for (i = 0; i < (sizeof(valid_enums_sub)/sizeof(GLenum)); i++) {
		glGetProgramResourceLocation(prog, valid_enums_sub[i], "name");
			if (!piglit_check_gl_error(GL_NO_ERROR))
				piglit_report_result(PIGLIT_FAIL);
	}

	CHECK_SUB(VERTEX);
	CHECK_SUB(FRAGMENT);
	CHECK_SUB(GEOMETRY);

	piglit_report_subtest_result(PIGLIT_PASS, __func__);
	return true;
}
Ejemplo n.º 4
0
/* Test subroutine uniform location query with compute. */
static bool
test_subroutine_stages_compute()
{
	GLuint prog, i;

	if (!piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
		piglit_report_subtest_result(PIGLIT_SKIP, __func__);
		return true;
	}

	if (!piglit_is_extension_supported("GL_ARB_compute_shader")) {
		piglit_report_subtest_result(PIGLIT_SKIP, __func__);
		return true;
	}

        prog = piglit_build_simple_program_multiple_shaders(
                     GL_COMPUTE_SHADER, compute_subroutine_text,
                     0);

	glUseProgram(prog);

	/* Iterate through all valid subroutine enums passing invalid name. */
	for (i = 0; i < (sizeof(valid_enums_sub_com)/sizeof(GLenum)); i++) {
		glGetProgramResourceLocation(prog, valid_enums_sub_com[i],
                                             "name");
			if (!piglit_check_gl_error(GL_NO_ERROR))
				piglit_report_result(PIGLIT_FAIL);
	}

	CHECK_SUB(COMPUTE);

	piglit_report_subtest_result(PIGLIT_PASS, __func__);
	return true;
}
Ejemplo n.º 5
0
void
piglit_init(int argc, char **argv)
{
	int i;
	GLint program[2];
	bool pass = true;

	float expected[] = {
		0.0, 1.0, 0.0,
		0.0, 0.0, 0.0
	};

	program[0] = piglit_build_simple_program_multiple_shaders(
						GL_VERTEX_SHADER,   vs_source,
						GL_GEOMETRY_SHADER, gs_source,
						GL_FRAGMENT_SHADER, fs_source,
						0);

	program[1] = piglit_build_simple_program(vs_source, fs_source);

	for( i = 0; i < 2; i++) {
		pass = test_gl_layer(program[i], 2, expected) && pass;
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Ejemplo n.º 6
0
static bool
build_and_use_program(GLint gs_invocation_n, const char *gs_template,
                      const char **gs_varyings, int array_size)
{
	GLuint prog;

	char *gs_text;

	asprintf(&gs_text, gs_template, gs_invocation_n);
	prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_pass_thru_text,
				GL_GEOMETRY_SHADER, gs_text, 0);
	free(gs_text);

	glTransformFeedbackVaryings(prog, array_size, gs_varyings,
				GL_INTERLEAVED_ATTRIBS);

	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		return false;
	if (!piglit_check_gl_error(GL_NO_ERROR))
		return false;

	glUseProgram(prog);

	return true;
}
Ejemplo n.º 7
0
PIGLIT_GL_TEST_CONFIG_END

static GLuint
get_program(const char *target)
{
	char fs_text[1024];
	static const char *fs_templ =
		"#version 150\n"
		"#extension GL_ARB_texture_cube_map_array : enable\n"
	        "uniform sampler%s s;\n"
	        "void main()\n"
	        "{\n"
	        "   gl_FragColor = %s;\n"
	        "}\n";
	static const char *vs_text =
		"#version 150\n"
		"#extension GL_ARB_explicit_attrib_location : require\n"
		"layout(location=0) in vec4 pos;\n"
	        "void main()\n"
	        "{\n"
	        "   gl_Position = pos;\n"
	        "}\n";

	if (!strcmp(target, "1D"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, 0, 0)");
        else if (!strcmp(target, "2D"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec2(0), 0)");
	else if (!strcmp(target, "3D"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec3(0), 0)");
	else if (!strcmp(target, "2DRect"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec2(0))");
	else if (!strcmp(target, "1DArray"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec2(0), 0)");
	else if (!strcmp(target, "2DArray"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec3(0), 0)");
	else if (!strcmp(target, "2DMS"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec2(0), 0)");
	else if (!strcmp(target, "2DMSArray"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, ivec3(0), 0)");
	else if (!strcmp(target, "Buffer"))
		sprintf(fs_text, fs_templ, target, "texelFetch(s, 0)");
	else if (!strcmp(target, "Cube"))
		sprintf(fs_text, fs_templ, target, "texture(s, vec3(0.0))");
	else if (!strcmp(target, "CubeArray")) {
		piglit_require_extension("GL_ARB_texture_cube_map_array");
		sprintf(fs_text, fs_templ, target, "texture(s, vec4(0.0))");
	}
	else {
		printf("Unknown target = %s\n", target);
		piglit_report_result(PIGLIT_FAIL);
	}

	return piglit_build_simple_program_multiple_shaders(GL_VERTEX_SHADER, vs_text,
							    GL_FRAGMENT_SHADER, fs_text,
							    0);
}
Ejemplo n.º 8
0
void
piglit_init(int argc, char **argv)
{
	GLuint program;
	char *vsSource;
	char *gsSource;
	char *fsSource;

	piglit_require_extension("GL_ARB_viewport_array");

	(void)!asprintf(&vsSource,
		 "#version 150\n"
		 "in vec4 piglit_vertex;\n"
		 "void main() {\n"
		 "	gl_Position = piglit_vertex;\n"
		 "}\n");

	(void)!asprintf(&gsSource,
		 "#version 150\n"
		 "#extension GL_ARB_viewport_array : enable\n"
		 "layout(triangles) in;\n"
		 "layout(triangle_strip, max_vertices = 18) out;\n"
		 "out vec3 color;\n"
		 "\n"
		 "void main()\n"
		 "{\n"
		 "	for (int j = 0; j < %d; j++) {\n"
		 "		gl_ViewportIndex = j;\n"
		 "		color = vec3(1.0 / (j+1), 1.0 / (j+1), 1.0 / (j+1));\n"
		 "		for(int i = 0; i < gl_in.length(); i++) {\n"
		 "			gl_Position = gl_in[i].gl_Position;\n"
		 "			EmitVertex();\n"
		 "		}\n"
		 "		EndPrimitive();\n"
		 "	}\n"
		 "}\n", divX * divY);

	(void)!asprintf(&fsSource,
		 "#version 150\n"
		 "in vec3 color;\n"
		 "void main() {\n"
		 "	gl_FragColor = vec4(color.xyz, 1.0);\n"
		 "}\n");


	program = piglit_build_simple_program_multiple_shaders(
					GL_VERTEX_SHADER, vsSource,
					GL_GEOMETRY_SHADER, gsSource,
					GL_FRAGMENT_SHADER, fsSource,
					0);
	glUseProgram(program);
}
Ejemplo n.º 9
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint buffer;
	unsigned int i;
	double *map;

	piglit_require_extension("GL_ARB_shader_storage_buffer_object");
	piglit_require_extension("GL_ARB_gpu_shader_fp64");
	piglit_require_GLSL_version(150);

	prog = piglit_build_simple_program_multiple_shaders(
		GL_VERTEX_SHADER, vs_code,
		GL_GEOMETRY_SHADER, gs_source,
		GL_FRAGMENT_SHADER, fs_source,
		NULL);

	glUseProgram(prog);

	glClearColor(0, 0, 0, 0);

	glGenBuffers(1, &buffer);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, buffer);
	glBufferData(GL_SHADER_STORAGE_BUFFER, SSBO_SIZE*sizeof(GLdouble),
		     &ssbo_values[0], GL_DYNAMIC_DRAW);

	glViewport(0, 0, piglit_width, piglit_height);

	piglit_draw_rect(-1, -1, 2, 2);

	glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
	map = (double *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,  GL_READ_ONLY);

	for (i = 0; i < SSBO_SIZE; i++) {
		if (DIFFER(map[i], expected[i])) {
			printf("expected[%d] = %.14g. Read value: %.14g\n",
			       i, expected[i], map[i]);
			pass = false;
		}
	}

	glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		pass = false;

	glDeleteProgram(prog);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Ejemplo n.º 10
0
static void
build_and_use_program(unsigned gs_invocation_n)
{
	GLuint prog;

	if (gs_invocation_n == 0) {
		prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_two_sets_text, 0);
	} else {
		char *gs_text;

		asprintf(&gs_text, gs_text_two_sets_tmpl, gs_invocation_n);
		prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_pass_thru_text,
				GL_GEOMETRY_SHADER, gs_text, 0);
		free(gs_text);
	}

	/**
	 * In the EXT-style the recorded varyings need to be set before linking.
	 *
	 * Also it should be noticed that when mixed mode is used, i.e., where
	 * one records multiple attributes per buffer but also uses separate
	 * buffers, the mode must be set to interleaved.
	 */
	glTransformFeedbackVaryings(prog, ARRAY_SIZE(varyings), varyings,
				GL_INTERLEAVED_ATTRIBS);

	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		piglit_report_result(PIGLIT_FAIL);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glUseProgram(prog);
}
Ejemplo n.º 11
0
void
piglit_init(int argc, char **argv)
{
    GLuint program;

    piglit_require_extension("GL_ARB_viewport_array");

    program = piglit_build_simple_program_multiple_shaders(
                  GL_VERTEX_SHADER, vsSource,
                  GL_GEOMETRY_SHADER, gsSource,
                  GL_FRAGMENT_SHADER, fsSource,
                  0);
    glUseProgram(program);
    colorLoc = glGetUniformLocation(program, "color");
    vpIndexLoc = glGetUniformLocation(program, "idx");
}
static GLuint
build_and_use_program(const char *vs_text)
{
	GLuint prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_text, 0);

	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		piglit_report_result(PIGLIT_FAIL);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glUseProgram(prog);

	return prog;
}
Ejemplo n.º 13
0
static enum piglit_result
query_work_group_size_no_compute(void *data)
{
	/* From the ARB_compute_shader spec, in the description of the
	 * COMPUTE_WORK_GROUP_SIZE query:
	 *
	 *     If <program> is the name of a program that has not been
	 *     successfully linked, or is the name of a linked program
	 *     object that contains no compute shaders, then an
	 *     INVALID_OPERATION error is generated.
	 *
	 * In this test, we use a program that has no compute shaders.
	 */
	GLint prog = piglit_build_simple_program_multiple_shaders(
		GL_VERTEX_SHADER, trivial_vertex_shader, 0);
	return query_work_group_size_expect_error(prog);
}
Ejemplo n.º 14
0
static void
build_and_use_program(GLint gs_invocation_n)
{
	GLuint prog;

	char *gs_text;

	asprintf(&gs_text, gs_tmpl, gs_invocation_n);
	prog = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_pass_thru_text,
				GL_GEOMETRY_SHADER, gs_text, 0);
	free(gs_text);

	glTransformFeedbackVaryings(prog, ARRAY_SIZE(varyings), varyings,
				GL_INTERLEAVED_ATTRIBS);

	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		piglit_report_result(PIGLIT_FAIL);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glUseProgram(prog);
}
Ejemplo n.º 15
0
void
piglit_init(int argc, char **argv)
{
	GLuint program;
	GLuint vao;

#ifdef PIGLIT_USE_OPENGL
	piglit_require_extension("GL_ARB_viewport_array");
	piglit_require_extension("GL_ARB_gpu_shader5");
#else
	piglit_require_extension("GL_OES_viewport_array");
#endif

	program = piglit_build_simple_program_multiple_shaders(
					GL_VERTEX_SHADER, vsSource,
					GL_GEOMETRY_SHADER, gsSource,
					GL_FRAGMENT_SHADER, fsSource,
					0);
	glUseProgram(program);

	glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

}
Ejemplo n.º 16
0
void
piglit_init(int argc, char **argv)
{
	static const char *st_r_tf_varying[] = {"gs_output0", NULL};

	piglit_require_extension("GL_ARB_program_interface_query");
	piglit_require_extension("GL_ARB_separate_shader_objects");

	/* Allocate the different programs */
	prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
					GL_VERTEX_SHADER, vs_std,
					GL_GEOMETRY_SHADER, gs_std,
					GL_FRAGMENT_SHADER, fs_std,
					0);
	glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
				    GL_INTERLEAVED_ATTRIBS);
	piglit_check_gl_error(GL_NO_ERROR);

	/* force the compiler not to optimise away inputs/outputs */
	glProgramParameteri(prog_std, GL_PROGRAM_SEPARABLE, GL_TRUE);
	piglit_check_gl_error(GL_NO_ERROR);

	glLinkProgram(prog_std);
	if (!piglit_link_check_status(prog_std)) {
		glDeleteProgram(prog_std);
		piglit_report_result(PIGLIT_FAIL);
	}

	if (piglit_is_extension_supported("GL_ARB_shader_storage_buffer_object")) {
		prog_stor = piglit_build_simple_program_multiple_shaders(
						GL_VERTEX_SHADER, vs_stor,
						GL_GEOMETRY_SHADER, gs_stor,
						GL_FRAGMENT_SHADER, fs_stor,
						0);
	}

	if (piglit_is_extension_supported("GL_ARB_explicit_attrib_location") &&
	    piglit_is_extension_supported("GL_ARB_explicit_uniform_location")) {
		prog_loc = piglit_build_simple_program_multiple_shaders(
						GL_VERTEX_SHADER, vs_loc,
						GL_FRAGMENT_SHADER, fs_loc,
						0);
	}

	if (piglit_is_extension_supported("GL_ARB_shader_atomic_counters")) {
		prog_atom = piglit_build_simple_program_unlinked_multiple_shaders(
						GL_FRAGMENT_SHADER, fs_atom,
						0);

		/* force the compiler not to optimise away inputs/outputs */
		glProgramParameteri(prog_atom, GL_PROGRAM_SEPARABLE,
				    GL_TRUE);
		piglit_check_gl_error(GL_NO_ERROR);

		glLinkProgram(prog_atom);
		if (!piglit_link_check_status(prog_atom)) {
			glDeleteProgram(prog_atom);
			piglit_report_result(PIGLIT_FAIL);
		}
	}

	if (!piglit_is_extension_supported("GL_ARB_shader_subroutine")) {
		return;
	}

	prog_sub = piglit_build_simple_program_multiple_shaders(
				GL_VERTEX_SHADER, vs_sub,
				GL_GEOMETRY_SHADER, gs_sub,
				GL_FRAGMENT_SHADER, fs_sub,
				0);

	if (piglit_is_extension_supported("GL_ARB_tessellation_shader")) {
		prog_sub_tess =
			  piglit_build_simple_program_unlinked_multiple_shaders(
					GL_TESS_CONTROL_SHADER, tcs_sub,
					0);
		/* force the compiler not to optimise away inputs/outputs */
		glProgramParameteri(prog_sub_tess, GL_PROGRAM_SEPARABLE,
				    GL_TRUE);
		piglit_check_gl_error(GL_NO_ERROR);

		glLinkProgram(prog_sub_tess);
		if (!piglit_link_check_status(prog_sub_tess)) {
			glDeleteProgram(prog_sub_tess);
			piglit_report_result(PIGLIT_FAIL);
		}
	}

	if (piglit_is_extension_supported("GL_ARB_compute_shader")) {
		prog_cs = piglit_build_simple_program_multiple_shaders(
						GL_COMPUTE_SHADER, cs_sub,
						0);
	}
}
Ejemplo n.º 17
0
void
piglit_init(int argc, char **argv)
{
	int j;
	bool pass = true;
	GLuint fbo, texture, program;

	static const float colors[6*3] = {
		0, 0, 1,
		0, 1, 0,
		0, 1, 1,
		1, 0, 0,
		1, 0, 1,
		1, 1, 0
	};

	program = piglit_build_simple_program_multiple_shaders(
					GL_VERTEX_SHADER, vs_source,
					GL_GEOMETRY_SHADER, gs_source,
					GL_FRAGMENT_SHADER, fs_source,
					0);
	glUseProgram(program);

	/* Retrieve index from vs */
	color_uniform = glGetUniformLocation(program, "color");
	layer_uniform = glGetUniformLocation(program, "layer");

	/* Gen textures */
	glGenFramebuffers(1, &fbo);
	glBindFramebuffer(GL_FRAMEBUFFER, fbo);

	texture = create_bind_texture();
	glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			     texture, 0);

	if(!check_framebuffer_status(GL_FRAMEBUFFER,
				     GL_FRAMEBUFFER_COMPLETE) ||
	   !piglit_check_gl_error(GL_NO_ERROR)) {
		printf("Error with setup\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	/* draw quad on each layer with set color*/
	glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
	for(j = 0; j < 6; j++) {
		if (j == 3) {
			glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
		}
		glUniform1i(layer_uniform, j);
		glUniform3fv(color_uniform, 1, &colors[j*3]);
		/* rect larger than vp */
		piglit_draw_rect(-2, -2, 4, 4);
	}

	pass = probe_texture_layered_rgb(texture,
					 0, 0, 0, 6, 6, 6, colors) && pass;

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* Clean up */
	glDeleteTextures(1, &texture);
	glDeleteFramebuffers(1, &fbo);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Ejemplo n.º 18
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	int i;
	unsigned int vao, tcs_prog, tes_prog, normal_prog;
	static const GLenum primitive[] = {
		GL_POINTS,
		GL_LINES,
		GL_LINE_LOOP,
		GL_LINE_STRIP,
		GL_TRIANGLES,
		GL_TRIANGLE_STRIP,
		GL_TRIANGLE_FAN,
		GL_LINES_ADJACENCY,
		GL_LINE_STRIP_ADJACENCY,
		GL_TRIANGLES_ADJACENCY,
		GL_TRIANGLE_STRIP_ADJACENCY,
	};

	piglit_require_extension("GL_ARB_tessellation_shader");

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	tcs_prog = piglit_build_simple_program_multiple_shaders(
			GL_VERTEX_SHADER, vs_source,
			GL_TESS_CONTROL_SHADER, tcs_source,
			GL_FRAGMENT_SHADER, fs_source,
			0);
	tes_prog = piglit_build_simple_program_multiple_shaders(
			GL_VERTEX_SHADER, vs_source,
			GL_TESS_EVALUATION_SHADER, tes_source,
			GL_FRAGMENT_SHADER, fs_source,
			0);
	normal_prog = piglit_build_simple_program_multiple_shaders(
			GL_VERTEX_SHADER, vs_source,
			GL_FRAGMENT_SHADER, fs_source,
			0);

	for (i = 0; i < ARRAY_SIZE(primitive); ++i) {
		glUseProgram(tcs_prog);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		glDrawArrays(primitive[i], 0, 12);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
	}

	for (i = 0; i < ARRAY_SIZE(primitive); ++i) {
		glUseProgram(tes_prog);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		glDrawArrays(primitive[i], 0, 12);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
	}

	/* NV_gpu_shader5 allows drawing patches without tessellation
	 * evaluation shader.
	 */
	if (!piglit_is_extension_supported("GL_NV_gpu_shader5")) {
		glUseProgram(normal_prog);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		glDrawArrays(GL_PATCHES, 0, 12);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
	}

	glUseProgram(0);
	glDeleteProgram(tcs_prog);
	glDeleteProgram(tes_prog);
	glDeleteProgram(normal_prog);
	glBindVertexArray(0);
	glDeleteVertexArrays(1, &vao);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}