Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

readrate.c 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * Test glReadPixels speed
  3. * Brian Paul
  4. * 9 April 2004
  5. *
  6. * Compile:
  7. * gcc readrate.c -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -o readrate
  8. */
  9. #define GL_GLEXT_PROTOTYPES
  10. #include <assert.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14. #include <GL/glut.h>
  15. /* Hack, to test drawing instead of reading */
  16. #define DRAW 0
  17. #define MAX_WIDTH 1280
  18. #define MAX_HEIGHT 1024
  19. #define NUM_WIDTHS 4
  20. #define NUM_HEIGHTS 4
  21. static const GLint Widths[] = {256, 512, 1024, 1280};
  22. static const GLint Heights[] = {4, 32, 256, 512, 768, 1024};
  23. static int WidthIndex = 1, HeightIndex = 3;
  24. static GLubyte *Buffer = NULL;
  25. static GLboolean Benchmark = GL_TRUE;
  26. #define NUM_PBO 2
  27. static GLuint PBObjects[4];
  28. static GLboolean HavePBO = GL_FALSE;
  29. struct format_type {
  30. const char *Name;
  31. GLuint Bytes;
  32. GLenum Format;
  33. GLenum Type;
  34. };
  35. static struct format_type Formats[] = {
  36. { "GL_RGB, GLubyte", 3, GL_RGB, GL_UNSIGNED_BYTE },
  37. { "GL_BGR, GLubyte", 3, GL_BGR, GL_UNSIGNED_BYTE },
  38. { "GL_RGBA, GLubyte", 4, GL_RGBA, GL_UNSIGNED_BYTE },
  39. { "GL_BGRA, GLubyte", 4, GL_BGRA, GL_UNSIGNED_BYTE },
  40. { "GL_ABGR, GLubyte", 4, GL_ABGR_EXT, GL_UNSIGNED_BYTE },
  41. { "GL_RGBA, GLuint_8_8_8_8", 4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8 },
  42. { "GL_BGRA, GLuint_8_8_8_8", 4, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8 },
  43. { "GL_BGRA, GLuint_8_8_8_8_rev", 4, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV },
  44. #ifdef GL_EXT_packed_depth_stencil
  45. { "GL_DEPTH_STENCIL_EXT, GLuint24+8", 4, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT },
  46. #endif
  47. { "GL_DEPTH_COMPONENT, GLfloat", 4, GL_DEPTH_COMPONENT, GL_FLOAT },
  48. { "GL_DEPTH_COMPONENT, GLuint", 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }
  49. };
  50. #define NUM_FORMATS (sizeof(Formats) / sizeof(struct format_type))
  51. static void
  52. PrintString(const char *s)
  53. {
  54. while (*s) {
  55. glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
  56. s++;
  57. }
  58. }
  59. static void
  60. MeasureFormat(struct format_type *fmt, GLint width, GLint height, GLuint pbo)
  61. {
  62. double t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  63. double t1;
  64. int j;
  65. for (j = 0; ; j++) {
  66. glBegin(GL_POINTS);
  67. glVertex2f(1,1);
  68. glEnd();
  69. #if DRAW
  70. glWindowPos2iARB(0,0);
  71. glDrawPixels(width, height,
  72. fmt->Format, fmt->Type, Buffer);
  73. glFinish();
  74. #else
  75. if (pbo) {
  76. glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, PBObjects[j % NUM_PBO]);
  77. glReadPixels(0, 0, width, height,
  78. fmt->Format, fmt->Type, 0);
  79. }
  80. else {
  81. glReadPixels(0, 0, width, height,
  82. fmt->Format, fmt->Type, Buffer);
  83. }
  84. #endif
  85. t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  86. if (t1 - t0 > 2.0) {
  87. GLdouble rate = width * height / (1024.0 * 1024.0) * j / (t1 - t0);
  88. #if DRAW
  89. printf("%-32s %.2f draws/sec %.2f MPixels/sec %.2f MBytes/sec\n",
  90. fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes);
  91. #else
  92. printf("%-32s %.2f reads/sec %.2f MPixels/sec %.2f MBytes/sec\n",
  93. fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes);
  94. #endif
  95. break;
  96. }
  97. if (j == 0) {
  98. /* check for error */
  99. GLenum err = glGetError();
  100. if (err) {
  101. printf("GL Error 0x%x for %s\n", err, fmt->Name);
  102. return;
  103. }
  104. }
  105. }
  106. }
  107. static void
  108. Draw(void)
  109. {
  110. char str[1000];
  111. int width = Widths[WidthIndex];
  112. int height = Heights[HeightIndex];
  113. int y = MAX_HEIGHT - 50;
  114. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  115. glWindowPos2iARB(10, y);
  116. sprintf(str, "ReadPixels size: %d x %d", width, height);
  117. PrintString(str);
  118. y -= 14;
  119. glWindowPos2iARB(10, y);
  120. PrintString("Press up/down/left/right to change image size.");
  121. y -= 14;
  122. glWindowPos2iARB(10, y);
  123. PrintString("Press 'b' to run benchmark test.");
  124. y -= 14;
  125. if (Benchmark) {
  126. glWindowPos2iARB(10, y);
  127. PrintString("Testing...");
  128. }
  129. glutSwapBuffers();
  130. if (Benchmark) {
  131. GLuint i, pbo;
  132. #if DRAW
  133. printf("Draw size: Width=%d Height=%d\n", width, height);
  134. #else
  135. printf("Read size: Width=%d Height=%d\n", width, height);
  136. #endif
  137. for (pbo = 0; pbo <= HavePBO; pbo++) {
  138. printf("Pixel Buffer Object: %d\n", pbo);
  139. if (pbo == 0) {
  140. glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
  141. }
  142. for (i = 0; i < NUM_FORMATS; i++) {
  143. MeasureFormat(Formats + i, width, height, pbo);
  144. }
  145. }
  146. Benchmark = GL_FALSE;
  147. /* redraw window text */
  148. glutPostRedisplay();
  149. }
  150. }
  151. static void
  152. Reshape(int width, int height)
  153. {
  154. glViewport(0, 0, width, height);
  155. glMatrixMode(GL_PROJECTION);
  156. glLoadIdentity();
  157. glOrtho(-1, 1, -1, 1, -1, 1);
  158. glMatrixMode(GL_MODELVIEW);
  159. glLoadIdentity();
  160. }
  161. static void
  162. Key(unsigned char key, int x, int y)
  163. {
  164. (void) x;
  165. (void) y;
  166. switch (key) {
  167. case 'b':
  168. Benchmark = 1;
  169. break;
  170. case 27:
  171. exit(0);
  172. break;
  173. }
  174. glutPostRedisplay();
  175. }
  176. static void
  177. SpecialKey(int key, int x, int y)
  178. {
  179. (void) x;
  180. (void) y;
  181. switch (key) {
  182. case GLUT_KEY_UP:
  183. if (HeightIndex + 1 < NUM_WIDTHS)
  184. HeightIndex++;
  185. break;
  186. case GLUT_KEY_DOWN:
  187. if (HeightIndex > 0)
  188. HeightIndex--;
  189. break;
  190. case GLUT_KEY_LEFT:
  191. if (WidthIndex > 0)
  192. WidthIndex--;
  193. break;
  194. case GLUT_KEY_RIGHT:
  195. if (WidthIndex + 1 < NUM_HEIGHTS)
  196. WidthIndex++;
  197. break;
  198. }
  199. glutPostRedisplay();
  200. }
  201. static void
  202. Init(void)
  203. {
  204. Buffer = malloc(MAX_WIDTH * MAX_HEIGHT * 4);
  205. assert(Buffer);
  206. #if DRAW
  207. printf("glDrawPixels test report:\n");
  208. #else
  209. printf("glReadPixels test report:\n");
  210. #endif
  211. printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
  212. printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
  213. if (glutExtensionSupported("GL_ARB_pixel_buffer_object")) {
  214. int i;
  215. HavePBO = 1;
  216. glGenBuffersARB(NUM_PBO, PBObjects);
  217. for (i = 0; i < NUM_PBO; i++) {
  218. glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, PBObjects[i]);
  219. glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
  220. MAX_WIDTH * MAX_HEIGHT * 4, NULL, GL_STREAM_READ);
  221. }
  222. }
  223. }
  224. int
  225. main(int argc, char *argv[])
  226. {
  227. glutInit(&argc, argv);
  228. glutInitWindowPosition(0, 0);
  229. glutInitWindowSize(MAX_WIDTH, MAX_HEIGHT);
  230. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
  231. glutCreateWindow(argv[0]);
  232. glutReshapeFunc(Reshape);
  233. glutKeyboardFunc(Key);
  234. glutSpecialFunc(SpecialKey);
  235. glutDisplayFunc(Draw);
  236. Init();
  237. glutMainLoop();
  238. return 0;
  239. }