diff options
Diffstat (limited to 'progs/tests/readrate.c')
-rw-r--r-- | progs/tests/readrate.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/progs/tests/readrate.c b/progs/tests/readrate.c new file mode 100644 index 00000000000..42ae62d48a9 --- /dev/null +++ b/progs/tests/readrate.c @@ -0,0 +1,285 @@ +/* + * Test glReadPixels speed + * Brian Paul + * 9 April 2004 + * + * Compile: + * gcc readrate.c -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -o readrate + */ + +#define GL_GLEXT_PROTOTYPES +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + +/* Hack, to test drawing instead of reading */ +#define DRAW 0 + +#define MAX_WIDTH 1280 +#define MAX_HEIGHT 1024 + +#define NUM_WIDTHS 4 +#define NUM_HEIGHTS 4 +static const GLint Widths[] = {256, 512, 1024, 1280}; +static const GLint Heights[] = {4, 32, 256, 512, 768, 1024}; +static int WidthIndex = 1, HeightIndex = 3; +static GLubyte *Buffer = NULL; +static GLboolean Benchmark = GL_TRUE; + +#define NUM_PBO 2 + +static GLuint PBObjects[4]; + +static GLboolean HavePBO = GL_FALSE; + + +struct format_type { + const char *Name; + GLuint Bytes; + GLenum Format; + GLenum Type; +}; + +static struct format_type Formats[] = { + { "GL_RGB, GLubyte", 3, GL_RGB, GL_UNSIGNED_BYTE }, + { "GL_BGR, GLubyte", 3, GL_BGR, GL_UNSIGNED_BYTE }, + { "GL_RGBA, GLubyte", 4, GL_RGBA, GL_UNSIGNED_BYTE }, + { "GL_BGRA, GLubyte", 4, GL_BGRA, GL_UNSIGNED_BYTE }, + { "GL_ABGR, GLubyte", 4, GL_ABGR_EXT, GL_UNSIGNED_BYTE }, + { "GL_RGBA, GLuint_8_8_8_8", 4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8 }, + { "GL_BGRA, GLuint_8_8_8_8", 4, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8 }, + { "GL_BGRA, GLuint_8_8_8_8_rev", 4, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV }, +#ifdef GL_EXT_packed_depth_stencil + { "GL_DEPTH_STENCIL_EXT, GLuint24+8", 4, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT }, +#endif + { "GL_DEPTH_COMPONENT, GLfloat", 4, GL_DEPTH_COMPONENT, GL_FLOAT }, + { "GL_DEPTH_COMPONENT, GLuint", 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT } +}; + +#define NUM_FORMATS (sizeof(Formats) / sizeof(struct format_type)) + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +MeasureFormat(struct format_type *fmt, GLint width, GLint height, GLuint pbo) +{ + double t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; + double t1; + int j; + + for (j = 0; ; j++) { + + glBegin(GL_POINTS); + glVertex2f(1,1); + glEnd(); + +#if DRAW + glWindowPos2iARB(0,0); + glDrawPixels(width, height, + fmt->Format, fmt->Type, Buffer); + glFinish(); +#else + if (pbo) { + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, PBObjects[j % NUM_PBO]); + glReadPixels(0, 0, width, height, + fmt->Format, fmt->Type, 0); + } + else { + glReadPixels(0, 0, width, height, + fmt->Format, fmt->Type, Buffer); + } +#endif + + t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001; + if (t1 - t0 > 2.0) { + GLdouble rate = width * height / (1024.0 * 1024.0) * j / (t1 - t0); +#if DRAW + printf("%-32s %.2f draws/sec %.2f MPixels/sec %.2f MBytes/sec\n", + fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes); +#else + printf("%-32s %.2f reads/sec %.2f MPixels/sec %.2f MBytes/sec\n", + fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes); +#endif + break; + } + + if (j == 0) { + /* check for error */ + GLenum err = glGetError(); + if (err) { + printf("GL Error 0x%x for %s\n", err, fmt->Name); + return; + } + } + } +} + + + +static void +Draw(void) +{ + char str[1000]; + int width = Widths[WidthIndex]; + int height = Heights[HeightIndex]; + int y = MAX_HEIGHT - 50; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glWindowPos2iARB(10, y); + sprintf(str, "ReadPixels size: %d x %d", width, height); + PrintString(str); + y -= 14; + + glWindowPos2iARB(10, y); + PrintString("Press up/down/left/right to change image size."); + y -= 14; + + glWindowPos2iARB(10, y); + PrintString("Press 'b' to run benchmark test."); + y -= 14; + + if (Benchmark) { + glWindowPos2iARB(10, y); + PrintString("Testing..."); + } + + glutSwapBuffers(); + + if (Benchmark) { + GLuint i, pbo; +#if DRAW + printf("Draw size: Width=%d Height=%d\n", width, height); +#else + printf("Read size: Width=%d Height=%d\n", width, height); +#endif + for (pbo = 0; pbo <= HavePBO; pbo++) { + printf("Pixel Buffer Object: %d\n", pbo); + + if (pbo == 0) { + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + } + + for (i = 0; i < NUM_FORMATS; i++) { + MeasureFormat(Formats + i, width, height, pbo); + } + } + + Benchmark = GL_FALSE; + + /* redraw window text */ + glutPostRedisplay(); + } + +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'b': + Benchmark = 1; + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + if (HeightIndex + 1 < NUM_WIDTHS) + HeightIndex++; + break; + case GLUT_KEY_DOWN: + if (HeightIndex > 0) + HeightIndex--; + break; + case GLUT_KEY_LEFT: + if (WidthIndex > 0) + WidthIndex--; + break; + case GLUT_KEY_RIGHT: + if (WidthIndex + 1 < NUM_HEIGHTS) + WidthIndex++; + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + Buffer = malloc(MAX_WIDTH * MAX_HEIGHT * 4); + assert(Buffer); +#if DRAW + printf("glDrawPixels test report:\n"); +#else + printf("glReadPixels test report:\n"); +#endif + printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION)); + + if (glutExtensionSupported("GL_ARB_pixel_buffer_object")) { + int i; + HavePBO = 1; + glGenBuffersARB(NUM_PBO, PBObjects); + for (i = 0; i < NUM_PBO; i++) { + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, PBObjects[i]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + MAX_WIDTH * MAX_HEIGHT * 4, NULL, GL_STREAM_READ); + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(MAX_WIDTH, MAX_HEIGHT); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); + glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + Init(); + glutMainLoop(); + return 0; +} |