Example #1
0
static void
draw()
{
	static const GLenum bo_modes[] = {
		GL_STREAM_DRAW,
		GL_STREAM_READ,
		GL_STREAM_COPY,
		GL_STATIC_DRAW,
		GL_STATIC_READ,
		GL_STATIC_COPY,
		GL_DYNAMIC_DRAW,
		GL_DYNAMIC_READ,
		GL_DYNAMIC_COPY,
	};
	int i;
	bool pass = true;

	glEnable(GL_RASTERIZER_DISCARD);

	for (i = 0; i < ARRAY_SIZE(bo_modes); i++) {
		static GLuint xfb_buf;
		float *readback;

		/* Make a new TFB output buffer with the chosen usage
		 * mode.  Note, from ARB_vertex_buffer_object:
		 *
		 *     "The specified usage value does not constrain
		 *      the actual usage pattern of the data store."
		 */
		glGenBuffers(1, &xfb_buf);
		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
			     sizeof(float), NULL, bo_modes[i]);
		piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf);

		/* Do the draw call.  Here's where we segfaulted before. */
		piglit_BeginTransformFeedback(GL_POINTS);
		glDrawArrays(GL_POINTS, 0, 1);
		piglit_EndTransformFeedback();

		/* Test the output, just to be sure. */
		readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
				       GL_READ_ONLY);

		if (readback[0] != 1.0) {
			fprintf(stderr, "Readback found %f, expected 1.0\n",
				readback[0]);
			pass = false;
		}
		glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

		glDeleteBuffers(1, &xfb_buf);
	}

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Example #2
0
enum piglit_result piglit_display(void)
{
	GLint input_index = glGetAttribLocation(prog, "input_uint");
	GLuint *readback;
	GLuint buffer[BUFFER_SIZE];
	GLuint expected[BUFFER_SIZE];
	int i;
	GLboolean pass = GL_TRUE;

	piglit_UseProgram(prog);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glVertexAttribIPointer(input_index, 1, GL_UNSIGNED_INT,
			       sizeof(GLuint), &verts);
	glEnableVertexAttribArray(input_index);
	pass = piglit_check_gl_error(0) && pass;

	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
	memset(buffer, 0xffffffff, sizeof(buffer));
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer), buffer,
		     GL_STREAM_READ);
	piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf,
			       additional_offset,
			       sizeof(buffer) - additional_offset);
	piglit_BeginTransformFeedback(GL_POINTS);
	glDrawArrays(GL_POINTS, 0, 4);
	piglit_EndTransformFeedback();
	pass = piglit_check_gl_error(0) && pass;

	readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
	pass = piglit_check_gl_error(0) && pass;

	/* Figure out expected output */
	memset(expected, 0xffffffff, sizeof(expected));
	for (i = 0; i < EXPECTED_NUM_OUTPUTS; ++i) {
		expected[i + additional_offset / 4] =
			0x00010203 + 0x04040404 * i;
	}

	/* Check output */
	for (i = 0; i < BUFFER_SIZE; ++i) {
		if (expected[i] != readback[i]) {
			printf("readback[%u]: %u, expected: %u\n", i,
			       readback[i], expected[i]);
			pass = GL_FALSE;
		}
	}

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Example #3
0
enum piglit_result piglit_display(void)
{
	GLboolean pass = GL_TRUE;
	static const float verts[] = {
		10, 10,
		10, 20,
		20, 20,
		20, 10
	};
	static const float v3[] = {0.55, 0.66, 0.77};
	static const float frontcolor[] = {1.0, 0.9, 0.8, 0.7};
	static const float v2[] = {0.2, 0.7};
	static const float texcoord1[] = {0.6, 0.0, 0.1, 0.6};

	glClear(GL_COLOR_BUFFER_BIT);

	/* Render into TFBO. */
	glLoadIdentity();
	piglit_UseProgram(prog);
	glEnable(GL_RASTERIZER_DISCARD);
	piglit_BeginTransformFeedback(GL_TRIANGLES);
	glVertexPointer(2, GL_FLOAT, 0, verts);
	glDrawArrays(GL_QUADS, 0, 4);
	piglit_EndTransformFeedback();
	glDisable(GL_RASTERIZER_DISCARD);

	assert(glGetError() == 0);

	pass = probe_buffer(buf[0], 0, 3, v3) && pass;
	pass = probe_buffer(buf[1], 1, 4, frontcolor) && pass;
	pass = probe_buffer(buf[2], 2, 2, v2) && pass;
	pass = probe_buffer(buf[3], 3, 4, texcoord1) && pass;

	assert(glGetError() == 0);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Example #4
0
static GLboolean
test(int bind_size, int num_varyings, int num_primitives, int mode_index)
{
	float initial_xfb_buf[XFB_BUFFER_SIZE];
	float vertex_data[MAX_VERTICES];
	int i, j;
	int vertices_per_prim = mode_vertices_per_prim[mode_index];
	int expected_primitives_written =
		MIN2(num_primitives,
		     bind_size / num_varyings / vertices_per_prim);
	int expected_vertices_written =
		expected_primitives_written * vertices_per_prim;
	GLuint query_result;
	GLboolean pass = GL_TRUE;
	float expected_xfb_results[XFB_BUFFER_SIZE];
	float *readback;

	printf("size=%d, num_varyings=%d, num_primitives=%d, mode=%s: ",
	       bind_size, num_varyings, num_primitives,
	       mode_names[mode_index]);

	/* Setup program and initial buffer contents */
	piglit_UseProgram(progs[num_varyings - 1]);
	for (i = 0; i < MAX_VERTICES; ++i)
		vertex_data[i] = i;
	glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float),
			      &vertex_data);
	glEnableVertexAttribArray(0);
	for (i = 0; i < XFB_BUFFER_SIZE; ++i)
		initial_xfb_buf[i] = 0.0;
	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buf),
		     initial_xfb_buf, GL_STREAM_READ);
	piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0,
			       sizeof(float) * bind_size);

	/* Start queries and XFB */
	glBeginQuery(GL_PRIMITIVES_GENERATED, query_prims_generated);
	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
		     query_prims_written);
	piglit_BeginTransformFeedback(modes[mode_index]);

	/* Draw */
	glDrawArrays(modes[mode_index], 0, num_primitives * vertices_per_prim);

	/* Stop XFB and check queries */
	piglit_EndTransformFeedback();
	glEndQuery(GL_PRIMITIVES_GENERATED);
	glGetQueryObjectuiv(query_prims_generated, GL_QUERY_RESULT,
			    &query_result);
	if (query_result != num_primitives) {
		printf("\n  Expected %u primitives generated, got %u\n",
		       (unsigned) num_primitives, query_result);
		pass = GL_FALSE;
	}
	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
	glGetQueryObjectuiv(query_prims_written, GL_QUERY_RESULT,
			    &query_result);
	if (query_result != expected_primitives_written) {
		printf("\n  Expected %u primitives written, got %u",
		       (unsigned) expected_primitives_written, query_result);
		pass = GL_FALSE;
	}

	/* Check transform feedback buffer */
	memcpy(expected_xfb_results, initial_xfb_buf, sizeof(initial_xfb_buf));
	for (i = 0; i < expected_vertices_written; ++i) {
		for (j = 0; j < num_varyings; ++j) {
			expected_xfb_results[i * num_varyings + j] =
				100.0 * (j + 1) + i;
		}
	}
	readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
			       GL_READ_ONLY);
	for (i = 0; i < XFB_BUFFER_SIZE; ++i) {
		if (expected_xfb_results[i] != readback[i]) {
			printf("\n  Expected buf[%i] = %f, got %f",
			       i, expected_xfb_results[i], readback[i]);
			pass = GL_FALSE;
		}
	}

	if (pass)
		printf("PASS\n");
	else
		printf("  FAIL\n");

	return pass;
}
Example #5
0
enum piglit_result piglit_display(void)
{
	GLboolean pass = GL_TRUE;
	GLuint q;
	float *ptr;
	unsigned i, qresult;
	static const float verts[] = {
		10, 10,
		10, 20,
		20, 20,
		20, 10
	};
	static const float expected[] = {
		-0.687500, -0.375000, 0.000000, 1.000000,
		-0.687500, 0.250000, 0.000000, 1.000000,
		-0.375000, -0.375000, 0.000000, 1.000000,
		-0.687500, 0.250000, 0.000000, 1.000000,
		-0.375000, 0.250000, 0.000000, 1.000000,
		-0.375000, -0.375000, 0.000000, 1.000000,
	};
	static const unsigned indices[] = {
		0, 1, 3, 1, 2, 3
	};
	static const float clearcolor[] = {0.2, 0.2, 0.2};
	static const float white[] = {1, 1, 1};
	static const float red[] = {1, 0, 0};

	glClear(GL_COLOR_BUFFER_BIT);

	/* Set up queries. */
	switch (test) {
	case PRIMGEN:
		glGenQueries(1, &q);
		glBeginQuery(GL_PRIMITIVES_GENERATED_EXT, q);
		break;
	case PRIMWRITTEN:
		glGenQueries(1, &q);
		glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT, q);
		break;
	}

	/* Render into TFBO. */
	glLoadIdentity();
	piglit_UseProgram(prog);
	if (discard)
		glEnable(GL_RASTERIZER_DISCARD_EXT);
	piglit_BeginTransformFeedback(GL_TRIANGLES);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glVertexPointer(2, GL_FLOAT, 0, verts);
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
	piglit_EndTransformFeedback();
	if (discard)
		glDisable(GL_RASTERIZER_DISCARD_EXT);

	assert(glGetError() == 0);

	switch (test) {
	case READBACK:
		puts("Testing readback.");
		ptr = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_READ_ONLY);
		for (i = 0; i < BUF_FLOATS; i++) {
			float value = i >= offset && i < offset+range ? expected[i-offset] : DEFAULT_VALUE;
			//printf("%f, ", ptr[i]);

			if (fabs(ptr[i] - value) > 0.01) {
				printf("Buffer[%i]: %f,  Expected: %f\n", i, ptr[i], value);
				pass = GL_FALSE;
			}
		}
		glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT);
		break;

	case RENDER:
		puts("Testing rendering.");
		piglit_UseProgram(prog_passthrough);
		glBindBuffer(GL_ARRAY_BUFFER, buf);
		glVertexPointer(4, GL_FLOAT, 0, (void*)(intptr_t)(offset * sizeof(float)));
		glDrawArrays(GL_TRIANGLES, 0, range == MAX_RANGE ? 6 : 3);

		pass = piglit_probe_pixel_rgb(33, 18, range == MAX_RANGE ? red : clearcolor) && pass;
		pass = piglit_probe_pixel_rgb(28, 12, red) && pass;
		break;

	case PRIMGEN:
		puts("Testing a primitives-generated query.");
		glEndQuery(GL_PRIMITIVES_GENERATED_EXT);
		glGetQueryObjectuiv(q, GL_QUERY_RESULT, &qresult);
		{
			int expected = 2; /* RASTERIZER_DISCARD should not affect this. */
			if (qresult != expected) {
				printf("Primitives generated: %i,  Expected: %i\n", qresult, expected);
				pass = GL_FALSE;
			}
		}
		break;

	case PRIMWRITTEN:
		puts("Testing a primitives-written query.");
		glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT);
		glGetQueryObjectuiv(q, GL_QUERY_RESULT, &qresult);
		{
			int expected = range == MAX_RANGE ? 2 : 1;
			if (qresult != expected) {
				printf("Primitives written: %i,  Expected: %i\n", qresult, expected);
				pass = GL_FALSE;
			}
		}
		break;

	default:
		piglit_report_result(PIGLIT_SKIP);
	}

	pass = piglit_probe_pixel_rgb(5, 5, clearcolor) && pass;
	pass = piglit_probe_pixel_rgb(15, 15, discard ? clearcolor : white) && pass;

	assert(glGetError() == 0);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}