Пример #1
0
enum piglit_result
piglit_display(void)
{
	bool pass = true;
	int x0 = piglit_width / 4;
	int x1 = piglit_width * 3 / 4;
	int y0 = piglit_height / 4;
	int y1 = piglit_height * 3 / 4;
	int i;

	glViewport(0, 0, piglit_width, piglit_height);

	glClear(GL_COLOR_BUFFER_BIT);

	for (i = 0; i < NUM_SQUARES; i++) {
		/* Load UBO data, at offset=alignment */
		glNamedBufferSubData(buffers[0], alignment, sizeof(pos_size[0]),
                                     pos_size[i]);
		glNamedBufferSubData(buffers[1], alignment, sizeof(color[0]),
                                     color[i]);
		glNamedBufferSubData(buffers[2], alignment, sizeof(rotation[0]),
                                     &rotation[i]);

		if (!piglit_check_gl_error(GL_NO_ERROR))
			return PIGLIT_FAIL;

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

	pass = probe(x0, y0, 0) && pass;
	pass = probe(x1, y0, 1) && pass;
	pass = probe(x0, y1, 2) && pass;
	pass = probe(x1, y1, 3) && pass;

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Пример #2
0
void
piglit_init(int argc, char **argv)
{
	GLuint vs;
	const char *varying_name = "output_value";

	/* Parse args */
	if (argc != 2)
		print_usage_and_exit(argv[0]);
	selected_test = interpret_test_case_arg(argv[1]);
	if (selected_test == NULL)
		print_usage_and_exit(argv[0]);

	/* Make sure required GL features are present */
	piglit_require_GLSL_version(120);
	piglit_require_transform_feedback();
	if (selected_test->bind_offset != 0 && selected_test->bind_size == 0) {
		/* Test requires glBindBufferOffsetEXT, which is in
		 * EXT_transform_feedback, but was never adopted into
		 * OpenGL.
		 */
		piglit_require_extension("GL_EXT_transform_feedback");
	}

	/* Create program and buffer */
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glTransformFeedbackVaryings(prog, 1, &varying_name,
				    GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		piglit_report_result(PIGLIT_FAIL);
	glGenBuffers(1, &xfb_buf);
	glGenQueries(1, &query);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
}
Пример #3
0
static enum piglit_result
query_work_group_size_expect_error(GLint prog)
{
	const GLint orig_query_result[3] = { 1234, 2345, 3456 };
	GLint query_result[3];
	int i;

	for (i = 0; i < 3; i++)
		query_result[i] = orig_query_result[i];

	glGetProgramiv(prog, GL_COMPUTE_WORK_GROUP_SIZE, query_result);

	if (!piglit_check_gl_error(GL_INVALID_OPERATION))
		return PIGLIT_FAIL;
	for (i = 0; i < 3; i++) {
		if (query_result[i] != orig_query_result[i]) {
			printf("Error was generated, but query returned a "
			       "result anyway.");
			return PIGLIT_FAIL;
		}
	}
	return PIGLIT_PASS;
}
Пример #4
0
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char **argv)
{
	GLint objID = glCreateProgram();

	/* Check the link status is set to false */
	glLinkProgram(objID);
	if (piglit_link_check_status(objID))
		piglit_report_result(PIGLIT_FAIL);

	/* UseProgram should throw an error when the program has not been
	 * successfully linked.
	 */
	glUseProgram(objID);
	if (!piglit_check_gl_error(GL_INVALID_OPERATION))
		piglit_report_result(PIGLIT_FAIL);

	glDeleteProgram(objID);

	piglit_report_result(PIGLIT_PASS);
}
Пример #5
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;

	/* The first 5 indices should be ignored */
	const unsigned indices[6] = {0, 0, 0, 0, 0, 1};

	piglit_require_extension("GL_ARB_shader_subroutine");
	piglit_require_extension("GL_ARB_explicit_uniform_location");
	piglit_require_extension("GL_ARB_explicit_attrib_location");

	prog = piglit_build_simple_program(NULL, frag_shader_text);

	glUseProgram(prog);
	glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 6, indices);

	if (!piglit_check_gl_error(0)) {
		pass = false;
	}

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void
piglit_init(int argc, char **argv)
{
	GLuint buffer;
	double ssbo_values[SSBO_SIZE] = {0};

	piglit_require_extension("GL_ARB_shader_storage_buffer_object");
	piglit_require_GLSL_version(400);

	prog = piglit_build_simple_program(vs_pass_thru_text, fs_source);

	glUseProgram(prog);

	glClearColor(0, 0, 0, 1);

	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);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
}
Пример #7
0
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint bo;
	uint8_t in_data[1] = {0xaa};
	uint8_t out_data[1] = {0xd0};
	void *ptr1, *ptr2;

	piglit_require_extension("GL_ARB_uniform_buffer_object");

	glGenBuffers(1, &bo);

	glBindBuffer(GL_UNIFORM_BUFFER, bo);
	pass = pass && piglit_check_gl_error(0);

	glBufferData(GL_UNIFORM_BUFFER, 1, NULL, GL_STATIC_READ);
	pass = pass && piglit_check_gl_error(0);

	glBufferSubData(GL_UNIFORM_BUFFER, 0, 1, in_data);
	pass = pass && piglit_check_gl_error(0);

	ptr1 = glMapBuffer(GL_UNIFORM_BUFFER, GL_READ_ONLY);
	pass = pass && piglit_check_gl_error(0);

	glGetBufferPointerv(GL_UNIFORM_BUFFER, GL_BUFFER_MAP_POINTER, &ptr2);
	pass = pass && piglit_check_gl_error(0);
	assert(ptr1 == ptr2);

	glUnmapBuffer(GL_UNIFORM_BUFFER);
	pass = pass && piglit_check_gl_error(0);

	glGetBufferSubData(GL_UNIFORM_BUFFER, 0, 1, out_data);
	pass = pass && piglit_check_gl_error(0);
	assert(memcmp(in_data, out_data, sizeof(in_data)) == 0);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
enum piglit_result
piglit_display()
{
	bool pass = true;
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	allocate_data_arrays();

	/* Set sample_alpha_to_one = false to generate the reference image */
	draw_reference_image(false /* sample_alpha_to_coverage */,
			     false /* sample_alpha_to_one */);

	/* Test multisample fbo with GL_SAMPLE_ALPHA_TO_ONE enabled but
	 * GL_MULTISAMPLE disabled */
	glDisable(GL_MULTISAMPLE);

	draw_test_image(false /* sample_alpha_to_coverage */,
			true /* sample_alpha_to_one */);

	glEnable(GL_MULTISAMPLE);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindFramebuffer(GL_READ_FRAMEBUFFER, piglit_winsys_fbo);
	pass = piglit_probe_rect_halves_equal_rgba(0, 0,
						   piglit_width,
						   piglit_height)
	       && pass;
	/* Free the memory allocated for data arrays */
	free_data_arrays();

	if (!piglit_automatic)
		piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Пример #9
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;

	piglit_require_extension("GL_ARB_texture_storage");
	piglit_require_extension("GL_ARB_texture_view");
	piglit_require_extension("GL_ARB_texture_cube_map_array");
	piglit_require_extension("GL_EXT_texture_array");
	piglit_require_extension("GL_ARB_texture_rectangle");

	if (piglit_get_gl_version() < 31)
	    piglit_require_extension("GL_ARB_texture_cube_map");

	X(test_target_errors(GL_TEXTURE_1D), "1D tex target validity");
	X(test_target_errors(GL_TEXTURE_2D), "2D tex target validity");
	X(test_target_errors(GL_TEXTURE_3D), "3D tex target validity");
	X(test_target_errors(GL_TEXTURE_CUBE_MAP),
		"Cubemap tex target validity");
	X(test_target_errors(GL_TEXTURE_RECTANGLE),
		"Rectangle tex target validity");
	X(test_target_errors(GL_TEXTURE_1D_ARRAY),
		"1D Array tex target validity");
	X(test_target_errors(GL_TEXTURE_2D_ARRAY),
		"2D Array tex target validity");
	X(test_target_errors(GL_TEXTURE_CUBE_MAP_ARRAY),
		"Cubemap Array tex target validity");
	if (piglit_is_extension_supported("GL_ARB_texture_storage_multisample")) {
		X(test_target_errors(GL_TEXTURE_2D_MULTISAMPLE),
		  "Multisample 2D tex target validity");
		X(test_target_errors(GL_TEXTURE_2D_MULTISAMPLE_ARRAY),
		  "Multisample 2D array tex target validity");
	}
#undef X
    pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
    piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Пример #10
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLint box[9 * 4] = {0};
	int max;
	piglit_require_extension("GL_EXT_window_rectangles");

	glGetIntegerv(GL_MAX_WINDOW_RECTANGLES_EXT, &max);

	glWindowRectanglesEXT(0, 0, NULL);
	if (!piglit_check_gl_error(GL_INVALID_ENUM))
		pass = false;

	glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, -1, NULL);
	if (!piglit_check_gl_error(GL_INVALID_VALUE))
		pass = false;

	if (max < 9) {
		GLint t[4];
		glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max + 1, box);
		if (!piglit_check_gl_error(GL_INVALID_VALUE))
			pass = false;

		glGetIntegeri_v(GL_WINDOW_RECTANGLE_EXT, max + 1, t);
		if (!piglit_check_gl_error(GL_INVALID_VALUE))
			pass = false;
	}

	if (max > 9)
		max = 9;

	box[2] = -1;
	glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max, box);
	if (!piglit_check_gl_error(GL_INVALID_VALUE))
		pass = false;
	box[2] = 0;
	box[3] = -1;
	glWindowRectanglesEXT(GL_EXCLUSIVE_EXT, max, box);
	if (!piglit_check_gl_error(GL_INVALID_VALUE))
		pass = false;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Пример #11
0
void
piglit_init(int argc, char **argv)
{
	GLenum targets[] = {
		0,
		GL_TEXTURE_2D,
		GL_TEXTURE_BUFFER + 1,
	};
	GLuint tex;
	int i;

	piglit_require_extension("GL_ARB_texture_buffer_object");

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_BUFFER, tex);

	for (i = 0; i < ARRAY_SIZE(targets); i++) {
		glTexBufferARB(targets[i], GL_RGBA8, 0);
		if (!piglit_check_gl_error(GL_INVALID_ENUM))
			piglit_report_result(PIGLIT_FAIL);
	}

	piglit_report_result(PIGLIT_PASS);
}
static GLuint
attach_texture(int i)
{
	GLuint tex;

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
		     32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
				  GL_COLOR_ATTACHMENT0_EXT + i,
				  GL_TEXTURE_2D,
				  tex,
				  0);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	return tex;
}
Пример #13
0
/**
 * Draws a single quad full window size, with different scissor rectangles.
 * Scissor rectangles restrict drawing to sub-area of full window.
 * Geometry shader is responsible for expanding primitives to cover all
 * divX * divY viewport/scissor indices.  The function reads back the expected
 * color to test if the scissored drawing was correct.
 */
static bool
draw_multi_scissor_rect(void)
{
	bool pass = true;
	int i, j;
	GLfloat w = (GLfloat) piglit_width / (GLfloat) divX;
	GLfloat h = (GLfloat) piglit_height / (GLfloat) divY;

	glViewport(0, 0, piglit_width, piglit_height);
	glClear(GL_COLOR_BUFFER_BIT);
	glEnable(GL_SCISSOR_TEST);
	/* setup scissor rectangles for viewport indices */
	for (i = 0; i < divX; i++) {
		for (j = 0; j < divY; j++) {
			glScissorIndexed(j + i*divY, i * w, j * h, w, h);
		}
	}

	/* draw full viewport sized quads scissored down and check results */
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	pass = draw_check_pixels() & pass;
	glDisable(GL_SCISSOR_TEST);
	return pass;
}
Пример #14
0
/**
 * Verify that attaching a 0x0 renderbuffer results in incompleteness.
 */
bool
incomplete_0_by_0_renderbuffer(void)
{
	incomplete_fbo_test t("0x0 renderbuffer", GL_RENDERBUFFER);

	/* Attach a 0x0 renderbuffer to the framebuffer.  That should make it
	 * incomplete.
	 */
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 0, 0);
	glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
				  GL_RENDERBUFFER, t.rb);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		return t.fail();

	if (!t.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
		return t.fail();

	/* Allocate some storage for the renderbuffer and verify that
	 * the FBO is now complete.
	 */
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 4, 4);

	if (!t.check_fbo_status(GL_FRAMEBUFFER_COMPLETE))
		return t.fail();

	/* Verify that simple rendering can occur to the FBO.
	 */
	glClearColor(0.f, 1.f, 0.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);

	glBindFramebuffer(GL_READ_FRAMEBUFFER, t.fbo);
	if (!piglit_probe_rect_rgba(0, 0, 4, 4, green))
		return t.fail();

	return t.pass();
}
Пример #15
0
/* Page 156 */
static bool
test_bindtexture()
{
	GLenum targets[] = {
		GL_TEXTURE_1D,
		GL_TEXTURE_1D_ARRAY,
		GL_TEXTURE_2D,
		GL_TEXTURE_2D_ARRAY,
		GL_TEXTURE_3D,
		GL_TEXTURE_CUBE_MAP,
		GL_TEXTURE_RECTANGLE,
		GL_TEXTURE_BUFFER,
	};
	int i;
	bool pass = true;

	for (i = 0; i < ARRAY_SIZE(targets); i++) {
		glBindTexture(targets[i], 400 + i);
		if (!piglit_check_gl_error(GL_INVALID_OPERATION))
			pass = false;
	}

	return pass;
}
Пример #16
0
bool
generate_grid_arrays(GLuint *vao, GLuint *vbo,
                     float x, float y, float dx, float dy,
                     unsigned nx, unsigned ny)
{
        float (*verts)[4] = malloc(sizeof(*verts) * nx * ny);
        int i, j;

        for (i = 0; i < nx; ++i) {
                for (j = 0; j < ny; ++j) {
                        const unsigned k = (nx * (j & ~1) + 2 * (i & ~1) +
                                            (i & 1) + 2 * (j & 1));
                        verts[k][0] = x + i * dx;
                        verts[k][1] = y + j * dy;
                        verts[k][2] = 0.0;
                        verts[k][3] = 1.0;
                }
        }

        if (!*vao) {
                glGenVertexArrays(1, vao);
                glGenBuffers(1, vbo);
        }

        glBindVertexArray(*vao);
        glBindBuffer(GL_ARRAY_BUFFER, *vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(*verts) * nx * ny,
                     verts, GL_STATIC_DRAW);

        glVertexAttribPointer(PIGLIT_ATTRIB_POS, 4, GL_FLOAT,
                              GL_FALSE, 0, 0);
        glEnableVertexAttribArray(PIGLIT_ATTRIB_POS);

        free(verts);
        return piglit_check_gl_error(GL_NO_ERROR);
}
Пример #17
0
static void
check_subtest(struct subtest *t)
{
    int limit;
    glGetIntegerv(t->limit, &limit);

    if (t->use_texture) {
        GLuint texture;
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
        glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, limit+1,
                t->internalformat, 64, 64, GL_TRUE);
    } else {
        GLuint rb;
        glGenRenderbuffers(1, &rb);
        glBindRenderbuffer(GL_RENDERBUFFER, rb);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER,
                limit + 1, t->internalformat, 64, 64);
    }

    piglit_report_subtest_result(
            piglit_check_gl_error(t->error) ? PIGLIT_PASS : PIGLIT_FAIL,
            "%s", t->name);
}
Пример #18
0
PIGLIT_GL_TEST_CONFIG_END


void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint prog;
	int i;

	piglit_require_extension("GL_ARB_geometry_shader4");

	/* Create shader. */
	prog = create_shader(vs_text, gs_text, fs_text);

	for (i = 0; i < ARRAY_SIZE(primitives_out); i++) {
		const struct primitive_geom_info p = primitives_out[i];
		printf("Testing %s.\n", piglit_get_prim_name(p.type));
		glProgramParameteri(prog, GL_GEOMETRY_OUTPUT_TYPE_ARB, p.type);
		pass = piglit_check_gl_error(p.error) && pass;
	}

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Пример #19
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);
}
Пример #20
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);
}
Пример #21
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	int i;
	const int buffer_size = 3<<20;
	unsigned int buffer;

	piglit_require_extension("GL_ARB_clear_buffer_object");

	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, buffer_size, NULL, GL_STREAM_READ);

	for (i = 0; i < ARRAY_SIZE(formats); ++i)
		pass = test_format(i) && pass;

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glDeleteBuffers(1, &buffer);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Пример #22
0
/**
 * Test clamping for depth range near and far. Make sure clamped
 *  to [0, 1]. Test default values for near and far.
 * OpenGL 4.3 Core section 13.6.1 ref:
 *    "Values in v are each clamped to the range [0, 1] when specified."
 *
 */
static bool
depth_range_bounds(GLint maxVP)
{
	bool pass = true;
	GLdouble dr[2], drGet[2];
	int i;

	/* intial values for near, far are 0.0, 1.0 repsectively */
	for (i = 0; i < maxVP; i++) {
		glGetDoublei_v(GL_DEPTH_RANGE, i, dr);
		if (dr[0] != 0.0 || dr[1] != 1.0) {
			printf("depth_range default value wrong for idx %d\n",
			       i);
			pass = false;
		}
	}
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* test clamping of depth_range values */
	dr[0] = -0.001;
	dr[1] = 2.0;
	glDepthRangeArrayv(0, 1, dr);
	glGetDoublei_v(GL_DEPTH_RANGE, 0, drGet);
	if (drGet[0] != 0.0 || drGet[1] != 1.0) {
		printf("depth_range clamping failed glDepthRangeArrayv\n");
		pass = false;
	}
	glDepthRangeIndexed(1, dr[0], dr[1]);
	glGetDoublei_v(GL_DEPTH_RANGE, 1, drGet);
	if (drGet[0] != 0.0 || drGet[1] != 1.0) {
		printf("depth_range clamping failed glDepthRangeIndexed\n");
		pass = false;
	}

	return pass;
}
Пример #23
0
void
piglit_init(int argc, char **argv)
{
	piglit_require_gl_version(20);

	prog = glCreateProgram();

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

	glUseProgram(prog);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glEnable(GL_TEXTURE_2D);
	piglit_checkerboard_texture(tex, 0, 16, 16, 2, 2, black, white);

	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
}
Пример #24
0
void
piglit_init(int argc, char **argv)
{
	GLuint tex;
	GLuint fb;
	GLenum status;
	const float color[] = {1.0,0.0,0.0,1.0};

	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

	piglit_require_extension("GL_ARB_framebuffer_object");
	piglit_require_extension("GL_ARB_texture_cube_map");

	/* This texture will be incomplete because one of the cubemap faces
	 * has the wrong size.
	 */
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 32, 32, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 64, 64, 0,
		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	glGenFramebuffers(1, &fb);
	glBindFramebuffer(GL_FRAMEBUFFER, fb);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			       GL_TEXTURE_CUBE_MAP_POSITIVE_X, tex, 0);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE) {
		fprintf(stderr, "FBO erroneously incomplete: 0x%04x\n",
			status);
		piglit_report_result(PIGLIT_FAIL);
	}

	glClearColor(color[0], color[1], color[2], color[3]);
	glClear(GL_COLOR_BUFFER_BIT);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (!piglit_probe_texel_rect_rgba(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,
					  0, 0, 32, 32, color)) {
		fprintf(stderr, "FBO clear didn't work\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	piglit_report_result(PIGLIT_PASS);
}
static bool
test_with_format(GLenum internal_format, const char *name)
{
	GLuint rb, fb;
	GLenum status;
	bool pass = true;
	/* Storage for the values read.  The largest type is
	 * GLuint-sized, so this will be big enough for all types.
	 */
	GLuint values[BUF_WIDTH * BUF_HEIGHT];
	int i;

	printf("testing %s:\n", name);

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format,
				 BUF_WIDTH, BUF_HEIGHT);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
				     GL_DEPTH_ATTACHMENT_EXT,
				     GL_RENDERBUFFER_EXT,
				     rb);

	glDrawBuffer(GL_NONE);
	glReadBuffer(GL_NONE);

	status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		fprintf(stderr, "framebuffer incomplete\n");
		piglit_report_subtest_result(PIGLIT_SKIP, "%s", name);
		goto done;
	}

	glGetIntegerv(GL_DEPTH_BITS, &depth_bits);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_ALWAYS);
	glViewport(0, 0, BUF_WIDTH, BUF_HEIGHT);
	piglit_ortho_projection(BUF_WIDTH, BUF_HEIGHT, false);
	piglit_draw_rect_z(1.0, 0,     0, w,     BUF_HEIGHT);
	piglit_draw_rect_z(0.0, w,     0, w * 2, BUF_HEIGHT);
	piglit_draw_rect_z(-1.0, w * 2, 0, w * 3, BUF_HEIGHT);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	for (i = 0; i < ARRAY_SIZE(read_formats); i++) {
		int x, y;
		bool format_passed = true;

		glReadPixels(0, 0, BUF_WIDTH, BUF_HEIGHT,
			     GL_DEPTH_COMPONENT, read_formats[i].token, values);

		for (y = 0; y < BUF_HEIGHT; y++) {
			for (x = 0; x < BUF_WIDTH; x++) {
				if (!read_formats[i].test(x, y, values)) {
					format_passed = false;
					break;
				}
			}
			if (x != BUF_WIDTH)
				break;

		}

		piglit_report_subtest_result((format_passed ?
					      PIGLIT_PASS : PIGLIT_FAIL),
					     "%s/%s",
					     name,
					     read_formats[i].name);
		pass = format_passed && pass;
	}

done:
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
	glDeleteFramebuffersEXT(1, &fb);
	glDeleteRenderbuffersEXT(1, &rb);
	return pass;
}
Пример #26
0
void
piglit_init(int argc, char **argv)
{
	GLuint tex, view;
	GLuint buffer;
	int i, j;
	bool use_pbo = false;
	bool pass = true;

#ifdef PIGLIT_USE_OPENGL
	piglit_require_extension("GL_ARB_texture_view");
#else
	piglit_require_extension("GL_OES_texture_view");
#endif

	for (i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "pbo") == 0) {
			piglit_require_extension("GL_ARB_pixel_buffer_object");
			use_pbo = true;
		}
	}

	/* build a texture with full miptree */
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexStorage2D(GL_TEXTURE_2D, NUM_LEVELS,
		       GL_RGBA8, TEX_SIZE, TEX_SIZE);

	if (use_pbo) {
		glGenBuffers(1, &buffer);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
	}

	for (i=0; i < NUM_LEVELS; i++) {
		int dim = TEX_SIZE >> i;
		GLubyte *pixels = create_solid_image(dim, dim, 1, 4, i);
		if (!pixels) {
			printf("Failed to allocate image for level %d\n", i);
			piglit_report_result(PIGLIT_FAIL);
		}

		if (use_pbo) {
			glBufferData(GL_PIXEL_UNPACK_BUFFER, dim * dim * 4,
				     pixels, GL_STREAM_DRAW);
		}
		glTexSubImage2D(GL_TEXTURE_2D,
				i, 0, 0, dim, dim,
				GL_RGBA, GL_UNSIGNED_BYTE, use_pbo ? NULL : pixels);
		free(pixels);
	}

	/* create a view to a subset of the layers */
	glGenTextures(1, &view);
	glTextureView(view, GL_TEXTURE_2D, tex, GL_RGBA8,
		      VIEW_MIN_LEVEL, VIEW_NUM_LEVELS, 0, 1);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* upload through the view */
	glBindTexture(GL_TEXTURE_2D, view);
	for (i = 0; i < VIEW_NUM_LEVELS; i++) {
		int dim = TEX_SIZE >> (VIEW_MIN_LEVEL + i);
		GLubyte *pixels = create_solid_image(dim, dim,
						     1, 4, i + NUM_LEVELS);
		if (!pixels) {
			printf("Failed to allocate image for view level %d\n", i);
			piglit_report_result(PIGLIT_FAIL);
		}

		if (use_pbo) {
			glBufferData(GL_PIXEL_UNPACK_BUFFER, dim * dim * 4,
				     pixels, GL_STREAM_DRAW);
		}
		glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, dim, dim,
				GL_RGBA, GL_UNSIGNED_BYTE, use_pbo ? NULL : pixels);
		free(pixels);
	}

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* bind the underlying texture and readback */
	glBindTexture(GL_TEXTURE_2D, tex);
	for (i = 0; i < NUM_LEVELS; i++) {
		/* the levels inside the view should have been replaced.
		 * everything else should be untouched.
		 */

		float expected_color[4];
		int dim = TEX_SIZE >> i;
		int color_index = i;
		if (i >= VIEW_MIN_LEVEL &&
		    i < VIEW_MIN_LEVEL + VIEW_NUM_LEVELS) {
			color_index = i + NUM_LEVELS - VIEW_MIN_LEVEL;
		}

		printf("Testing level %d\n", i);

		for (j = 0; j < 4; j++)
			expected_color[j] = Colors[color_index][j] / 255.0f;

		pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D,
						    i, 0, 0, dim, dim,
						    expected_color) && pass;
	}

	if (use_pbo)
		glDeleteBuffers(1, &buffer);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Пример #27
0
static bool
test_get_object_label()
{
	#define numBuffers 4
	GLsizei length;
	GLuint buffers[numBuffers];
	GLuint invalidBufferName;
	GLchar label[TestLabelLen + 1];
	bool pass = true;

	enum test_object_indices {
		TEST_BUFSIZE_IDX, TEST_NO_LABEL_IDX, TEST_NULL_LABEL_IDX, TEST_NULL_LENGTH_IDX
	};

	puts("Test GetObjectLabel");

	glGenBuffers(numBuffers, buffers);

	/* The maximum number of characters that may
	 * be written into <label>, including the null terminator, is specified by
	 * <bufSize>.
	 */
	glBindBuffer(GL_ARRAY_BUFFER, buffers[TEST_BUFSIZE_IDX]);
	ObjectLabel(GL_BUFFER, buffers[TEST_BUFSIZE_IDX], -1, TestLabel);
	GetObjectLabel(GL_BUFFER, buffers[TEST_BUFSIZE_IDX], TestLabelLen, &length, label);

	if (length != 9 || (strcmp("Test Labe", label) != 0)) {
		fprintf(stderr, "BufSize should limit the maximum label length to 9\n");
		printf("  actual label: %s actual length: %i\n", label, length);
		pass = false;
	}

	/* If no debug label was specified for the object then <label>
	 * will contain a null-terminated empty string, and zero will be returned
	 * in <length>.
	 */
	glBindBuffer(GL_ARRAY_BUFFER, buffers[TEST_NO_LABEL_IDX]);
	GetObjectLabel(GL_BUFFER, buffers[TEST_NO_LABEL_IDX], TestLabelLen + 1, &length, label);

	if (length != 0 || (strcmp("", label) != 0)) {
		fprintf(stderr, "Label should be empty and length 0\n");
		printf("  actual label: %s actual length: %i\n", label, length);
		pass = false;
	}

	/* If <label> is NULL and <length> is non-NULL then no string
	 * will be returned and the length of the label will be returned in
	 * <length>.
	 */
	glBindBuffer(GL_ARRAY_BUFFER, buffers[TEST_NULL_LABEL_IDX]);
	ObjectLabel(GL_BUFFER, buffers[TEST_NULL_LABEL_IDX], -1, TestLabel);
	GetObjectLabel(GL_BUFFER, buffers[TEST_NULL_LABEL_IDX], TestLabelLen + 1, &length, NULL);

	if (length != TestLabelLen) {
		fprintf(stderr, "Label length should be %i\n", TestLabelLen);
		printf("  actual length: %i\n", length);
		pass = false;
	}

	/* If <length> is NULL, no length is returned.
	 */
	glBindBuffer(GL_ARRAY_BUFFER, buffers[TEST_NULL_LENGTH_IDX]);
	ObjectLabel(GL_BUFFER, buffers[TEST_NULL_LENGTH_IDX], -1, TestLabel);
	GetObjectLabel(GL_BUFFER, buffers[TEST_NULL_LENGTH_IDX], TestLabelLen + 1, NULL, label);

	if (strcmp(TestLabel, label) != 0) {
		fprintf(stderr, "Label doent match expected string when length NULL\n");
		printf("  label: %s expected: %s\n", label, TestLabel);
		pass = false;
	}

	/* An INVALID_ENUM error is generated by GetObjectLabel if identifier is not
	 * one of the valid object types
	 */
	GetObjectLabel(GL_ARRAY_BUFFER, buffers[TEST_NULL_LENGTH_IDX], TestLabelLen + 1, &length, label);

	if (!piglit_check_gl_error(GL_INVALID_ENUM)) {
		fprintf(stderr, "GL_INVALID_ENUM should be generated when GetObjectLabel identifier is invalid\n");
		pass = false;
	}

	/* An INVALID_VALUE error is generated by GetObjectLabel if <name> is not
	 * the name of a valid object of the type specified by <identifier>.
	 */
	invalidBufferName = buffers[TEST_NULL_LENGTH_IDX];
	glDeleteBuffers(numBuffers, buffers);
	GetObjectLabel(GL_BUFFER, invalidBufferName, TestLabelLen + 1, &length, label);

	if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
		fprintf(stderr, "GL_INVALID_VALUE should be generated when GetObjectLabel name is invalid\n");
		pass = false;
	}

	return pass;
}
Пример #28
0
static bool
test_object_label()
{
	GLsizei length;
	GLuint buffer;
	GLuint invalidBufferName;
	GLint maxLabelLength;
	GLchar label[TestLabelLen + 1];
	GLchar *bigLabel;
	bool pass = true;
	int maximumLabelLengthTest = 1024; /* Be defensive about the size label length test to avoid memory issues */

	puts("Test ObjectLabel");

	glGenBuffers(1, &buffer);

	/* An INVALID_VALUE error is generated if the number of characters in
	 * <label>, excluding the null terminator when <length> is negative, is not
	 * less than the value of MAX_LABEL_LENGTH.
	 */
	glGetIntegerv(GL_MAX_LABEL_LENGTH, &maxLabelLength);
	if (maxLabelLength <= maximumLabelLengthTest) {
		bigLabel = (char *) malloc(maxLabelLength + 1);
		if (bigLabel){
			memset(bigLabel,'a',maxLabelLength);
			bigLabel[maxLabelLength] = '\0';

			/* Test when length -1 */
			glBindBuffer(GL_ARRAY_BUFFER, buffer);
			ObjectLabel(GL_BUFFER, buffer, -1, bigLabel);

			if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
				fprintf(stderr, "GL_INVALID_VALUE should be generated when label >= MAX_LABEL_LENGTH\n");
				pass = false;
			}

			/* test with large client defined length */
			glBindBuffer(GL_ARRAY_BUFFER, buffer);
			ObjectLabel(GL_BUFFER, buffer, maxLabelLength, bigLabel);

			if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
				fprintf(stderr, "GL_INVALID_VALUE should be generated when label length >= MAX_LABEL_LENGTH\n");
				pass = false;
			}
		}
	}
	else {
		printf("MAX_LABEL_LENGTH test skipped as implementations MAX_LABEL_LENGTH=%i and max piglit test length=%i\n",
		       maxLabelLength, maximumLabelLengthTest);
	}

	/* If <label> is NULL, any debug label is effectively removed from the object.
	 */
	ObjectLabel(GL_BUFFER, buffer, -1, TestLabel);
	ObjectLabel(GL_BUFFER, buffer, -1, NULL);
	GetObjectLabel(GL_BUFFER, buffer, TestLabelLen + 1, &length, label);

	if (length != 0 || (strcmp("", label) != 0)) {
		fprintf(stderr, "Setting label to NULL should remove the label\n");
		printf("  actual label: %s actual length: %i\n", label, length);
		pass = false;
	}

	/* An INVALID_ENUM error is generated by ObjectLabel if <identifier> is not
	 * one of the object types.
	 */
	ObjectLabel(GL_ARRAY_BUFFER, buffer, -1, TestLabel);

	if (!piglit_check_gl_error(GL_INVALID_ENUM)) {
		fprintf(stderr, "GL_INVALID_ENUM should be generated when the ObjectLabel identifier is invalid\n");
		pass = false;
	}

	/* An INVALID_VALUE error is generated by ObjectLabel if <name> is not
	 * the name of a valid object of the type specified by <identifier>.
	 */
	invalidBufferName = buffer;
	glDeleteBuffers(1, &buffer);
	ObjectLabel(GL_BUFFER, invalidBufferName, -1, TestLabel);

	if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
		fprintf(stderr, "GL_INVALID_VALUE should be generated when the ObjectLabel name is invalid\n");
		pass = false;
	}

	return pass;
}
PIGLIT_GL_TEST_CONFIG_END

enum piglit_result
piglit_display(void)
{
	GLuint tex[3];
	GLint level;
	GLint num_level;

	/* The GL ES 3.0 spec says:
	 *
	 *     "The [initial] value of TEXTURE_IMMUTABLE_LEVELS is 0."
	 */
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		piglit_report_result(PIGLIT_FAIL);
	}
	if (level != 0) {
		printf("Expected 0 levels initially, but glGetTexParameteriv "
		       "returned %d for GL_TEXTURE_1D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glGenTextures(5, tex);

	glBindTexture(GL_TEXTURE_1D, tex[0]);
	glTexStorage1D(GL_TEXTURE_1D, 3, GL_RGBA8, 32);
	glGetTexParameteriv(GL_TEXTURE_1D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_1D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_1D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_2D, tex[1]);
	glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 32, 32);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_2D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_3D, tex[2]);
	glTexStorage3D(GL_TEXTURE_3D, 3, GL_RGBA8, 32, 32, 32);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameterfv returned "
		       "%d for GL_TEXTURE_3D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_2D, tex[3]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_FLOAT, NULL);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (level != 0) {
		printf("Expected 0 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_2D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_3D, tex[4]);
	glTexImage2D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, GL_RGBA, GL_FLOAT, NULL);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (level != 0) {
		printf("Expected 0 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_3D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glDeleteTextures(5, tex);

	piglit_report_result(PIGLIT_PASS);
	return 0;
}
Пример #30
0
void
piglit_init(int argc, char **argv)
{
	GLuint prog, shader;
	unsigned i;
	bool pass = true;

	piglit_require_extension("GL_ARB_program_interface_query");
	piglit_require_extension("GL_ARB_explicit_attrib_location");
	piglit_require_extension("GL_ARB_explicit_uniform_location");

	/* Test invalid program. */
	glGetProgramResourceLocation(42, GL_UNIFORM, "name");
	if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
		piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 1");
		pass = false;
	}

	/* Test passing a shader, not program. */
	shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_loc);
	glGetProgramResourceLocation(shader, GL_UNIFORM, "name");
	if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
		piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 2");
		pass = false;
	}

	prog = piglit_build_simple_program_unlinked(vs_loc, fs_loc);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* Test unlinked program. */
	glGetProgramResourceLocation(prog, GL_UNIFORM, "name");
	if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
		piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 3");
		pass = false;
	}

	if (pass)
		piglit_report_subtest_result(PIGLIT_PASS, "invalid program tests");

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* Test a linked program. */
	glLinkProgram(prog);
	glUseProgram(prog);

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

	/* Test invalid enum, there is no defined error by the spec. */
	glGetProgramResourceLocation(prog, GL_ATOMIC_COUNTER_BUFFER, "name");
	if (glGetError() == GL_NO_ERROR) {
		piglit_report_subtest_result(PIGLIT_FAIL, "invalid enum test");
		pass = false;
	} else {
		piglit_report_subtest_result(PIGLIT_PASS, "invalid enum test");
	}
	/* Test 3 illegal array cases referenced in the spec as 'bug 9254'. */
	if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[+1]") != -1) {
		piglit_report_subtest_result(PIGLIT_FAIL, "array case 1");
		pass = false;
	}

	if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[01]") != -1) {
		piglit_report_subtest_result(PIGLIT_FAIL, "array case 2");
		pass = false;
	}

	if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[ 0]") != -1) {
		piglit_report_subtest_result(PIGLIT_FAIL, "array case 3");
		pass = false;
	}

	if (pass)
		piglit_report_subtest_result(PIGLIT_PASS, "invalid array input");

	/* Valid inputs. */
	validate_location(prog, GL_UNIFORM,        "color",    9);
	validate_location(prog, GL_PROGRAM_INPUT,  "input0",   3);
	validate_location(prog, GL_PROGRAM_INPUT,  "input1",   6);
	validate_location(prog, GL_PROGRAM_OUTPUT, "output0",  1);
	validate_location(prog, GL_PROGRAM_OUTPUT, "output1",  0);

	/* Array indexing cases. */
	validate_location(prog, GL_UNIFORM,        "array",    1);
	validate_location(prog, GL_UNIFORM,        "array[0]", 1);
	validate_location(prog, GL_UNIFORM,        "array[1]", 2);

	/* All valid inputs succeeded if we got this far. */
	piglit_report_subtest_result(PIGLIT_PASS, "valid inputs");

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* Tests that require GL_ARB_shader_subroutine. */
	pass = test_subroutine_stages_vs_fs_gs() && pass;
	pass = test_subroutine_stages_tcs_tes() && pass;
	pass = test_subroutine_stages_compute() && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}