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.

subtexrate.c 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Measure glTexSubImage and glCopyTexSubImage speed
  3. *
  4. * Brian Paul
  5. * 26 Jan 2006
  6. */
  7. #define GL_GLEXT_PROTOTYPES
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>
  12. #include <GL/glut.h>
  13. static GLint WinWidth = 1024, WinHeight = 512;
  14. static GLint TexWidth = 512, TexHeight = 512;
  15. static GLuint TexObj = 1;
  16. static GLenum IntFormat = GL_RGBA8;
  17. static GLenum ReadFormat = GL_RGBA; /* for glReadPixels */
  18. static GLboolean DrawQuad = GL_TRUE;
  19. /**
  20. * draw teapot image, size TexWidth by TexHeight
  21. */
  22. static void
  23. DrawTestImage(void)
  24. {
  25. GLfloat ar;
  26. glViewport(0, 0, TexWidth, TexHeight);
  27. glScissor(0, 0, TexWidth, TexHeight);
  28. glEnable(GL_SCISSOR_TEST);
  29. glClearColor(0.5, 0.5, 0.5, 0.0);
  30. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  31. ar = (float) TexWidth / TexHeight;
  32. glMatrixMode(GL_PROJECTION);
  33. glLoadIdentity();
  34. glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
  35. glMatrixMode(GL_MODELVIEW);
  36. glEnable(GL_LIGHTING);
  37. glEnable(GL_LIGHT0);
  38. glEnable(GL_DEPTH_TEST);
  39. glFrontFace(GL_CW);
  40. glPushMatrix();
  41. glRotatef(45, 1, 0, 0);
  42. glRotatef(45, 0, 1, 0);
  43. glutSolidTeapot(2.3);
  44. glPopMatrix();
  45. glFrontFace(GL_CCW);
  46. glDisable(GL_DEPTH_TEST);
  47. glDisable(GL_LIGHTING);
  48. glDisable(GL_SCISSOR_TEST);
  49. glViewport(0, 0, WinWidth, WinHeight);
  50. glFinish();
  51. }
  52. /**
  53. * Do glCopyTexSubImage2D call (update texture with framebuffer data)
  54. * If doSubRect is true, do the copy in four pieces instead of all at once.
  55. */
  56. static void
  57. DoCopyTex(GLboolean doSubRect)
  58. {
  59. if (doSubRect) {
  60. /* copy in four parts */
  61. int w = TexWidth / 2, h = TexHeight / 2;
  62. int x0 = 0, y0 = 0;
  63. int x1 = w, y1 = h;
  64. #if 1
  65. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x0, y0, w, h);
  66. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x1, y0, w, h);
  67. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x0, y1, w, h);
  68. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x1, y1, w, h);
  69. #else
  70. /* scramble */
  71. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x1, y1, w, h);
  72. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x0, y1, w, h);
  73. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x1, y0, w, h);
  74. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x0, y0, w, h);
  75. #endif
  76. }
  77. else {
  78. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight);
  79. }
  80. }
  81. /**
  82. * Do glTexSubImage2D (update texture w/ user data)
  83. * If doSubRect, do update in four pieces, else all at once.
  84. */
  85. static void
  86. SubTex(GLboolean doSubRect, const GLubyte *image)
  87. {
  88. if (doSubRect) {
  89. /* four pieces */
  90. int w = TexWidth / 2, h = TexHeight / 2;
  91. int x0 = 0, y0 = 0;
  92. int x1 = w, y1 = h;
  93. glPixelStorei(GL_UNPACK_ROW_LENGTH, TexWidth);
  94. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  95. glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
  96. glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
  97. glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, w, h,
  98. ReadFormat, GL_UNSIGNED_BYTE, image);
  99. glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
  100. glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  101. glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, w, h,
  102. ReadFormat, GL_UNSIGNED_BYTE, image);
  103. glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
  104. glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
  105. glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, w, h,
  106. ReadFormat, GL_UNSIGNED_BYTE, image);
  107. glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
  108. glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  109. glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, w, h,
  110. ReadFormat, GL_UNSIGNED_BYTE, image);
  111. }
  112. else {
  113. /* all at once */
  114. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexWidth, TexHeight,
  115. ReadFormat, GL_UNSIGNED_BYTE, image);
  116. }
  117. }
  118. /**
  119. * Measure gl[Copy]TexSubImage rate.
  120. * This actually also includes time to render a quad and SwapBuffers.
  121. */
  122. static void
  123. RunTest(GLboolean copyTex, GLboolean doSubRect)
  124. {
  125. double t0, t1;
  126. int iters = 0;
  127. float copyRate, mbRate;
  128. float rot = 0.0;
  129. int bpp, r, g, b, a;
  130. int w, h;
  131. GLubyte *image = NULL;
  132. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
  133. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
  134. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
  135. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
  136. bpp = (r + g + b + a) / 8;
  137. if (!copyTex) {
  138. /* read image from frame buffer */
  139. image = (GLubyte *) malloc(TexWidth * TexHeight * bpp);
  140. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  141. glReadPixels(0, 0, TexWidth, TexHeight,
  142. ReadFormat, GL_UNSIGNED_BYTE, image);
  143. }
  144. glEnable(GL_TEXTURE_2D);
  145. glViewport(WinWidth / 2, 0, WinWidth / 2, WinHeight);
  146. t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  147. do {
  148. if (copyTex)
  149. /* Framebuffer -> Texture */
  150. DoCopyTex(doSubRect);
  151. else {
  152. /* Main Mem -> Texture */
  153. SubTex(doSubRect, image);
  154. }
  155. /* draw textured quad */
  156. if (DrawQuad) {
  157. glPushMatrix();
  158. glRotatef(rot, 0, 0, 1);
  159. glTranslatef(1, 0, 0);
  160. glBegin(GL_POLYGON);
  161. glTexCoord2f(0, 0); glVertex2f(-1, -1);
  162. glTexCoord2f(1, 0); glVertex2f( 1, -1);
  163. glTexCoord2f(1, 1); glVertex2f( 1, 1);
  164. glTexCoord2f(0, 1); glVertex2f(-1, 1);
  165. glEnd();
  166. glPopMatrix();
  167. }
  168. iters++;
  169. rot += 2.0;
  170. t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  171. if (DrawQuad) {
  172. glutSwapBuffers();
  173. }
  174. } while (t1 - t0 < 5.0);
  175. glDisable(GL_TEXTURE_2D);
  176. if (image)
  177. free(image);
  178. if (doSubRect) {
  179. w = TexWidth / 2;
  180. h = TexHeight / 2;
  181. iters *= 4;
  182. }
  183. else {
  184. w = TexWidth;
  185. h = TexHeight;
  186. }
  187. copyRate = iters / (t1 - t0);
  188. mbRate = w * h * bpp * copyRate / (1024 * 1024);
  189. if (copyTex)
  190. printf("glCopyTexSubImage: %d x %d, %d Bpp:\n", w, h, bpp);
  191. else
  192. printf("glTexSubImage: %d x %d, %d Bpp:\n", w, h, bpp);
  193. printf(" %d calls in %.2f = %.2f calls/sec, %.2f MB/s\n",
  194. iters, t1-t0, copyRate, mbRate);
  195. }
  196. static void
  197. Draw(void)
  198. {
  199. glClearColor(0.2, 0.2, 0.8, 0);
  200. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  201. DrawTestImage();
  202. if (!DrawQuad) {
  203. glutSwapBuffers();
  204. }
  205. RunTest(GL_FALSE, GL_FALSE);
  206. RunTest(GL_FALSE, GL_TRUE);
  207. RunTest(GL_TRUE, GL_FALSE);
  208. RunTest(GL_TRUE, GL_TRUE);
  209. glutSwapBuffers();
  210. printf("exiting\n");
  211. exit(0);
  212. }
  213. static void
  214. Reshape(int width, int height)
  215. {
  216. glViewport(0, 0, width, height);
  217. glMatrixMode(GL_PROJECTION);
  218. glLoadIdentity();
  219. glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  220. glMatrixMode(GL_MODELVIEW);
  221. glLoadIdentity();
  222. glTranslatef(0.0, 0.0, -15.0);
  223. }
  224. static void
  225. Key(unsigned char key, int x, int y)
  226. {
  227. (void) x;
  228. (void) y;
  229. switch (key) {
  230. case 27:
  231. exit(0);
  232. break;
  233. }
  234. glutPostRedisplay();
  235. }
  236. static void
  237. SpecialKey(int key, int x, int y)
  238. {
  239. (void) x;
  240. (void) y;
  241. switch (key) {
  242. case GLUT_KEY_UP:
  243. break;
  244. case GLUT_KEY_DOWN:
  245. break;
  246. case GLUT_KEY_LEFT:
  247. break;
  248. case GLUT_KEY_RIGHT:
  249. break;
  250. }
  251. glutPostRedisplay();
  252. }
  253. static void
  254. Init(void)
  255. {
  256. /* create initial, empty teximage */
  257. glBindTexture(GL_TEXTURE_2D, TexObj);
  258. glTexImage2D(GL_TEXTURE_2D, 0, IntFormat, TexWidth, TexHeight, 0,
  259. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  260. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  261. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  262. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  263. }
  264. static void
  265. ParseArgs(int argc, char *argv[])
  266. {
  267. int i;
  268. for (i = 1; i < argc; i++) {
  269. if (strcmp(argv[i], "-nodraw") == 0)
  270. DrawQuad = GL_FALSE;
  271. }
  272. }
  273. int
  274. main(int argc, char *argv[])
  275. {
  276. GLint mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH;
  277. glutInit(&argc, argv);
  278. ParseArgs(argc, argv);
  279. glutInitWindowPosition(0, 0);
  280. glutInitWindowSize(WinWidth, WinHeight);
  281. glutInitDisplayMode(mode);
  282. glutCreateWindow(argv[0]);
  283. glutReshapeFunc(Reshape);
  284. glutKeyboardFunc(Key);
  285. glutSpecialFunc(SpecialKey);
  286. glutDisplayFunc(Draw);
  287. printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
  288. Init();
  289. glutMainLoop();
  290. return 0;
  291. }