void
piglit_init(int argc, char **argv)
{
	static const char *varyings[] = { "valOut1", "valOut2" };
	GLint inAttrib;

	/* Check the driver. */
	piglit_require_extension("GL_ARB_transform_feedback3");
	piglit_require_extension("GL_ARB_direct_state_access");

	/* Create shaders. */
	prog = piglit_build_simple_program_unlinked(vstext, NULL);
	glTransformFeedbackVaryings(prog, 2, varyings,
					GL_SEPARATE_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		glDeleteProgram(prog);
		piglit_report_result(PIGLIT_FAIL);
	}
	glUseProgram(prog);

	/* Set up the Vertex Array Buffer */
	glEnable(GL_VERTEX_ARRAY);
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	/* Set up the input data buffer */
	glGenBuffers(1, &input_buf);
	glBindBuffer(GL_ARRAY_BUFFER, input_buf);
	glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW);
	inAttrib = glGetAttribLocation(prog, "valIn");
	piglit_check_gl_error(GL_NO_ERROR);
	glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(inAttrib);
}
예제 #2
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	const GLint *readback;
	GLuint buf;
	void *initial_data;
	int i;
	GLuint prog = piglit_build_simple_program_unlinked(vs_text, NULL);
	glTransformFeedbackVaryings(prog, ARRAY_SIZE(varyings), varyings,
				    GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog) ||
	    !piglit_check_gl_error(GL_NO_ERROR)) {
		piglit_report_result(PIGLIT_FAIL);
	}
	glUseProgram(prog);

	/* Create transform feedback buffer and pre-load it with
	 * garbage.
	 */
	glGenBuffers(1, &buf);
	initial_data = malloc(sizeof(expected_xfb_result));
	memset(initial_data, 0xcc, sizeof(expected_xfb_result));
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_xfb_result),
		     initial_data, GL_STREAM_READ);
	free(initial_data);

	/* Run the test */
	glEnable(GL_RASTERIZER_DISCARD);
	glBeginTransformFeedback(GL_POINTS);
	glDrawArrays(GL_POINTS, 0, 1);
	glEndTransformFeedback();

	/* Check output */
	readback = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
				    sizeof(expected_xfb_result),
				    GL_MAP_READ_BIT);
	for (i = 0; i < ARRAY_SIZE(expected_xfb_result); i++) {
		if (readback[i] != expected_xfb_result[i]) {
			printf("XFB[%i] == %i, expected %i\n", i, readback[i],
			       expected_xfb_result[i]);
			pass = false;
		}
	}
	glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void
piglit_init(int argc, char **argv)
{
    piglit_require_gl_version(30);
    piglit_require_extension("GL_ARB_uniform_buffer_object");

    prog = piglit_build_simple_program_unlinked(vstext, fstext);
    glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);
    glLinkProgram(prog);
    if (!piglit_link_check_status(prog)) {
        glDeleteProgram(prog);
        piglit_report_result(PIGLIT_FAIL);
    }

    glGenBuffers(2, bufs);
}
예제 #4
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);
}
void
compile_shader(void)
{
	GLuint element_buf;
	unsigned int indices[6] = { 0, 1, 2, 0, 2, 3 };
	float vertex_data[4][11] = {
		/* vertex     color0:green    color1:blue     color2:yellow */
		{-1.0, -1.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0,  1.0, 1.0, 0.0},
		{-1.0,  1.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0,  1.0, 1.0, 0.0},
		{ 1.0,  1.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0,  1.0, 1.0, 0.0},
		{ 1.0, -1.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0,  1.0, 1.0, 0.0}};

	static const char *vert_template =
		"#version 130\n"
		"%s\n"
		"out vec4 color;\n"
		"uniform int x;\n"
		"void main()\n"
		"{\n"
		"  gl_Position =vec4(vertex, 0, 1);\n"
		"  switch(x) {\n"
		"  case 0:\n"
		"    color =vec4(color0, 1.0);\n"
		"    break;\n"
		"  case 1:\n"
		"    color = vec4(color1, 1.0);\n"
		"    break;\n"
		"  case 2:\n"
		"    color = vec4(color2, 1.0);\n"
		"    break;\n"
		"  default:\n"
		"    color = vec4(1.0);;\n"
		"  }\n"
		"}\n";

	static const char *frag =
		"#version 130\n"
		"in vec4 color;\n"
		"out vec4 out_color;\n"
		"void main()\n"
		"{\n"
		"    out_color = color;\n"
		"}\n";

	char *vert;
	(void)!asprintf(&vert, vert_template, locations_in_shader ?
		 "#extension GL_ARB_explicit_attrib_location : require\n"
		 "layout (location = 0) in vec2 vertex;\n"
		 "layout (location = 1) in vec3 color0;\n"
		 "layout (location = 1) in vec3 color1;\n"
		 "layout (location = 1) in vec3 color2;\n" :
		 "in vec2 vertex;\n"
		 "in vec3 color0;\n"
		 "in vec3 color1;\n"
		 "in vec3 color2;\n");

	prog = piglit_build_simple_program_unlinked(vert, frag);
	if (!locations_in_shader) {
		glBindAttribLocation(prog, 0, "vertex");
		glBindAttribLocation(prog, 1, "color0");
		glBindAttribLocation(prog, 1, "color1");
		glBindAttribLocation(prog, 1, "color2");
	}
	glLinkProgram(prog);

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

	/* Set up vertex array object */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	/* Set up vertex input buffer */
	glGenBuffers(1, &vertex_buf);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
		     GL_STREAM_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 11*sizeof(float),
			      (void *) 0);
	glEnableVertexAttribArray(1);

	/* Set up element input buffer to tessellate a quad into
	 * triangles
	 */
	glGenBuffers(1, &element_buf);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,
		     GL_STATIC_DRAW);
}
예제 #6
0
void
load_compare_program(struct texture_format *format)
{
	static struct {
		GLuint prog;
		GLuint tex1;
		GLuint tex2;
		GLuint tex_size;
		GLuint samples;
	} comp, ucomp, icomp, *compare;
	char *fs_src, *gtype;

	switch (format->format) {
	case GL_RED_INTEGER:
	case GL_RG_INTEGER:
	case GL_RGB_INTEGER:
	case GL_RGBA_INTEGER:
	case GL_BGRA_INTEGER:
	case GL_STENCIL_INDEX:
		switch (format->data_type) {
		case GL_BYTE:
		case GL_SHORT:
		case GL_INT:
			compare = &icomp;
			break;
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT:
		case GL_UNSIGNED_INT:
			compare = &ucomp;
			break;
		default:
			assert(!"Invalid data type");
		}
		break;
	case GL_RED:
	case GL_RG:
	case GL_RGB:
	case GL_RGBA:
	case GL_BGRA:
	case GL_ALPHA:
	case GL_LUMINANCE:
	case GL_LUMINANCE_ALPHA:
	case GL_INTENSITY:
	case GL_DEPTH_COMPONENT:
		compare = &comp;
		break;
	default:
		assert(!"Invalid Format");
	}

	if (!compare->prog) {
		if (compare == &comp) {
			gtype = "";
		} else if (compare == &ucomp) {
			gtype = "u";
		} else if (compare == &icomp) {
			gtype = "i";
		} else {
			assert(!"Invalid comparison fucntion");
			gtype = "";
		}

		/* The generated source will be shorter because we replace
		 * a bunch of "%s" with "u", "i", or ""
		 */
		fs_src = malloc(sizeof(ms_compare_fs_source));
		snprintf(fs_src, sizeof(ms_compare_fs_source),
			 ms_compare_fs_source, gtype, gtype, gtype, gtype);

		compare->prog = piglit_build_simple_program_unlinked(
			ms_compare_vs_source, fs_src);
		glBindAttribLocation(compare->prog, 0, "vertex");
		glLinkProgram(compare->prog);
		piglit_link_check_status(compare->prog);

		compare->tex1 = glGetUniformLocation(compare->prog, "tex1");
		compare->tex2 = glGetUniformLocation(compare->prog, "tex2");
		compare->tex_size = glGetUniformLocation(compare->prog, "tex_size");
		compare->samples = glGetUniformLocation(compare->prog, "samples");
	}

	glUseProgram(compare->prog);
	glUniform1i(compare->tex1, 0);
	glUniform1i(compare->tex2, 1);
	glUniform2i(compare->tex_size, TEX_SIZE, TEX_SIZE);
	glUniform1i(compare->samples, samples);
}
예제 #7
0
void piglit_init(int argc, char **argv)
{
	unsigned glsl_version;
	GLuint vs_prog_3_out;
	GLuint vs_prog_1_out;
	GLuint fs_prog_3_in;
	GLuint fs_prog_1_in;
	GLuint vs_fs_prog_separate_inactive;
	char *vs_source;
	char *fs_source;
	GLint max_varying;
	bool pass = true;

	piglit_require_vertex_shader();
	piglit_require_fragment_shader();
	piglit_require_GLSL_version(130); /* Support layout index on output color */
	piglit_require_extension("GL_ARB_separate_shader_objects");
	piglit_require_extension("GL_ARB_explicit_attrib_location");
	piglit_require_extension("GL_ARB_blend_func_extended");

	glsl_version = pick_a_glsl_version();

	glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varying);
	max_varying = (max_varying / 4u) - 1u;

	/*
	 * Program compilation and link
	 */
	printf("Compile vs_prog_3_out\n");
	vs_prog_3_out = format_and_link_program(GL_VERTEX_SHADER,
			vs_code_3_out_template, glsl_version);

	printf("Compile vs_prog_1_out\n");
	vs_prog_1_out = format_and_link_program(GL_VERTEX_SHADER,
			vs_code_1_out_template, glsl_version);

	printf("Compile fs_prog_3_in\n");
	fs_prog_3_in = format_and_link_program(GL_FRAGMENT_SHADER,
			fs_code_3_in_template, glsl_version);

	printf("Compile fs_prog_1_in\n");
	fs_prog_1_in = format_and_link_program(GL_FRAGMENT_SHADER,
			fs_code_1_in_template, glsl_version);

	(void)!asprintf(&vs_source, vs_code_inactive_template, glsl_version, max_varying);
	(void)!asprintf(&fs_source, fs_code_inactive_template, glsl_version, max_varying);

	pass &= piglit_check_gl_error(0);

	printf("Compile vs_fs_prog_separate_inactive\n");
	vs_fs_prog_separate_inactive = piglit_build_simple_program_unlinked(vs_source, fs_source);
	/* Manual linking so we can pack 2 separate-aware shaders into a single program */
	glProgramParameteri(vs_fs_prog_separate_inactive, GL_PROGRAM_SEPARABLE, GL_TRUE);
	glLinkProgram(vs_fs_prog_separate_inactive);

	if (!piglit_link_check_status(vs_fs_prog_separate_inactive)) {
		piglit_report_subtest_result(PIGLIT_SKIP,
				"Unactive varying optimization in multi-shade separated program");
		vs_fs_prog_separate_inactive = 0; // Skip program
		piglit_reset_gl_error(); // Clear pending error
	}

	free(vs_source);
	free(fs_source);

	/*
	 * Pipeline creation
	 */
	glGenProgramPipelines(1, &pipeline_3_out_1_in);
	glGenProgramPipelines(1, &pipeline_1_out_3_in);
	glBindProgramPipeline(pipeline_3_out_1_in);
	glUseProgramStages(pipeline_3_out_1_in,
			GL_VERTEX_SHADER_BIT, vs_prog_3_out);
	glUseProgramStages(pipeline_3_out_1_in,
			GL_FRAGMENT_SHADER_BIT, fs_prog_1_in);

	glBindProgramPipeline(pipeline_1_out_3_in);
	glUseProgramStages(pipeline_1_out_3_in,
			GL_VERTEX_SHADER_BIT, vs_prog_1_out);
	glUseProgramStages(pipeline_1_out_3_in,
			GL_FRAGMENT_SHADER_BIT, fs_prog_3_in);

	if (vs_fs_prog_separate_inactive) {
		glGenProgramPipelines(1, &pipeline_inactive);
		glBindProgramPipeline(pipeline_inactive);
		glUseProgramStages(pipeline_inactive,
				GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT,
				vs_fs_prog_separate_inactive);
	} else {
		pipeline_inactive = 0; // Skip the test
	}

	if (!piglit_check_gl_error(0) || !pass)
		piglit_report_result(PIGLIT_FAIL);
}
예제 #8
0
void
piglit_init(int argc, char **argv)
{
	GLuint buf;
	void *initial_data;
	bool pass = true;
	enum test_mode_enum test_mode;
	GLuint prog;
	GLuint vao, vbo_attrs, vbo_indices;
	GLuint query;

	if (argc != 2)
		print_usage_and_exit(argv[0]);
	if (strcmp(argv[1], "generated") == 0)
		test_mode = TEST_MODE_GENERATED;
	else if (strcmp(argv[1], "written") == 0)
		test_mode = TEST_MODE_WRITTEN;
	else if (strcmp(argv[1], "flush") == 0)
		test_mode = TEST_MODE_FLUSH;
	else
		print_usage_and_exit(argv[0]);

	prog = piglit_build_simple_program_unlinked(vs_text, NULL);
	glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);
	glBindAttribLocation(prog, 0, "x_in");
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog) ||
	    !piglit_check_gl_error(GL_NO_ERROR)) {
		piglit_report_result(PIGLIT_FAIL);
	}
	glUseProgram(prog);

	/* Create transform feedback buffer and pre-load it with
	 * garbage.
	 */
	glGenBuffers(1, &buf);
	initial_data = malloc(sizeof(expected_xfb_result));
	memset(initial_data, 0xcc, sizeof(expected_xfb_result));
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_xfb_result),
		     initial_data, GL_STREAM_READ);
	free(initial_data);

	/* Set up VAO/VBO */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glGenBuffers(1, &vbo_attrs);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_attrs);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attrs), vertex_attrs,
		     GL_STREAM_DRAW);
	glVertexAttribIPointer(0, 1, GL_INT, 0, NULL);
	glEnableVertexAttribArray(0);
	glGenBuffers(1, &vbo_indices);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,
		     GL_STREAM_DRAW);

	/* Misc setup */
	glEnable(GL_RASTERIZER_DISCARD);
	glEnable(GL_PRIMITIVE_RESTART);
	glPrimitiveRestartIndex(0xff);
	glGenQueries(1, &query);

	switch (test_mode) {
	case TEST_MODE_GENERATED:
		glBeginQuery(GL_PRIMITIVES_GENERATED, query);
		glBeginTransformFeedback(GL_TRIANGLES);
		glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
		glEndTransformFeedback();
		glEndQuery(GL_PRIMITIVES_GENERATED);
		pass = check_query_result(query, 4);
		break;
	case TEST_MODE_WRITTEN:
		glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
		glBeginTransformFeedback(GL_TRIANGLES);
		glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
		glEndTransformFeedback();
		glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
		pass = check_query_result(query, 4);
		break;
	case TEST_MODE_FLUSH:
		glBeginTransformFeedback(GL_TRIANGLES);
		glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL);
		glFlush();
		glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE,
			       (void *) (9 * sizeof(GLubyte)));
		glEndTransformFeedback();
		pass = check_xfb_result();
		break;
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
예제 #9
0
void
piglit_init(int argc, char **argv)
{
	static const char *varyings[] = { "valOut1", "valOut2" };
	GLuint size, start;
	GLint inAttrib;
	int i;

	/* Check the driver. */
	piglit_require_extension("GL_ARB_transform_feedback3");
	piglit_require_extension("GL_ARB_direct_state_access");

	/* Create shaders. */
	prog = piglit_build_simple_program_unlinked(vstext, NULL);
	glTransformFeedbackVaryings(prog, 2, varyings,
					GL_SEPARATE_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		glDeleteProgram(prog);
		piglit_report_result(PIGLIT_FAIL);
	}
	glUseProgram(prog);

	/* Set up the Vertex Array Buffer */
	glEnable(GL_VERTEX_ARRAY);
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	/* Set up the input data buffer */
	glGenBuffers(1, &input_buf);
	glBindBuffer(GL_ARRAY_BUFFER, input_buf);
	glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW);
	inAttrib = glGetAttribLocation(prog, "valIn");
	piglit_check_gl_error(GL_NO_ERROR);
	glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(inAttrib);

	/* set the initial state */
	ctx.active = false;
	ctx.paused = false;
	for (i = 0; i < 3; i++) {
		ctx.bo_state[i].binding = 0;
		ctx.bo_state[i].start = 0;
		ctx.bo_state[i].size = 0;
	}
	check_active_paused_state("initial state");
	check_binding_state("initial state");

	/* Set up the transform feedback buffer */
	glGenBuffers(3, xfb_buf);
	for (i = 0; i < 2; i++) {
		start = rand() & 0xFC;
		size = 0x100 + (rand() & 0xFFC);

		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[i]);
		piglit_check_gl_error(GL_NO_ERROR);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
				 size, NULL, GL_STREAM_READ);
		piglit_check_gl_error(GL_NO_ERROR);
		glTransformFeedbackBufferRange(0, i, xfb_buf[i], start, size);
		piglit_check_gl_error(GL_NO_ERROR);

		ctx.bo_state[i].binding = xfb_buf[i];
		ctx.bo_state[i].start = start;
		ctx.bo_state[i].size = size;
	}

	check_binding_state("post-binding state");
}
예제 #10
0
void piglit_init(int argc, char **argv)
{
	static const char *varyings[] = {"x"};
	GLuint buffers[3];
	GLuint vao;
	GLuint prog;
	GLuint queries[4];
	GLuint xfb[2];
	bool pass = true;

#ifdef PIGLIT_USE_OPENGL
	piglit_require_transform_feedback();
	piglit_require_GLSL_version(130);
	piglit_require_extension("GL_ARB_vertex_array_object");
	piglit_require_extension("GL_ARB_transform_feedback2");
#endif

	/* This is all just the boot-strap work for the test.
	 */
	glGenTransformFeedbacks(ARRAY_SIZE(xfb), xfb);
	glGenBuffers(ARRAY_SIZE(buffers), buffers);

	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffers[0]);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STREAM_READ);

	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffers[1]);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STREAM_READ);

	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 1 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(0);

	glGenQueries(ARRAY_SIZE(queries), queries);

	prog = piglit_build_simple_program_unlinked(vstext, fstext);

	glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		pass = false;
		goto done;
	}

	glUseProgram(prog);
	glEnable(GL_RASTERIZER_DISCARD);

	/* Here's the actual test.
	 */
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[0]);
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffers[0]);
	glBeginTransformFeedback(GL_POINTS);

	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[0]);
	glDrawArrays(GL_POINTS, 0, 4);
	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

	glPauseTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[1]);
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffers[1]);
	glBeginTransformFeedback(GL_POINTS);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[1]);
	glDrawArrays(GL_POINTS, 4, 2);
	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

	glPauseTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[0]);
	glResumeTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[2]);
	glDrawArrays(GL_POINTS, 6, 4);
	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

	glEndTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[1]);
	glResumeTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[3]);
	glDrawArrays(GL_POINTS, 10, 2);
	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

	glEndTransformFeedback();

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
	glBindVertexArray(0);

	/* The first XFB should have 8 primitives generated, and the buffer
	 * object should contain the values {1.0, 2.0, 3.0, 4.0, 7.0, 8.0,
	 * 9.0, 10.0}.
	 */
	{
		static const float expected_xfb_data[] = {
			1.0, 2.0, 3.0, 4.0, 7.0, 8.0, 9.0, 10.0
		};

		glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
		pass = check_results(1, ARRAY_SIZE(expected_xfb_data),
				     expected_xfb_data,
				     queries[0], queries[2])
			&& pass;
	}

	/* The second XFB should have 4 primitives generated, and the buffer
	 * object should contain the values {5.0, 6.0, 11.0, 12.0}.
	 */
	{
		static const float expected_xfb_data[] = {
			5.0, 6.0, 11.0, 12.0
		};

		glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
		pass = check_results(2, ARRAY_SIZE(expected_xfb_data),
				     expected_xfb_data,
				     queries[1], queries[3])
			&& pass;
	}

	glBindBuffer(GL_ARRAY_BUFFER, 0);

done:
	glBindVertexArray(0);
	glDeleteVertexArrays(1, &vao);
	glDeleteBuffers(ARRAY_SIZE(buffers), buffers);
	glDeleteQueries(ARRAY_SIZE(queries), queries);
	glDeleteTransformFeedbacks(ARRAY_SIZE(xfb), xfb);

	glUseProgram(0);
	glDeleteProgram(prog);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}