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.

teximage.c 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. /**
  22. * Measure glTex[Sub]Image2D() and glGetTexImage() rate
  23. *
  24. * Brian Paul
  25. * 16 Sep 2009
  26. */
  27. #include "glmain.h"
  28. #include "common.h"
  29. int WinWidth = 100, WinHeight = 100;
  30. static GLuint VBO;
  31. static GLuint TexObj = 0;
  32. static GLubyte *TexImage = NULL;
  33. static GLsizei TexSize;
  34. static GLenum TexIntFormat, TexSrcFormat, TexSrcType;
  35. static const GLboolean DrawPoint = GL_TRUE;
  36. static const GLboolean TexSubImage4 = GL_FALSE;
  37. enum {
  38. MODE_CREATE_TEXIMAGE,
  39. MODE_TEXIMAGE,
  40. MODE_TEXSUBIMAGE,
  41. MODE_GETTEXIMAGE,
  42. MODE_COUNT
  43. };
  44. static const char *mode_name[MODE_COUNT] =
  45. {
  46. "Create_TexImage",
  47. "TexImage",
  48. "TexSubImage",
  49. "GetTexImage"
  50. };
  51. struct vertex
  52. {
  53. GLfloat x, y, s, t;
  54. };
  55. static const struct vertex vertices[1] = {
  56. { 0.0, 0.0, 0.5, 0.5 },
  57. };
  58. #define VOFFSET(F) ((void *) offsetof(struct vertex, F))
  59. /** Called from test harness/main */
  60. void
  61. PerfInit(void)
  62. {
  63. /* setup VBO w/ vertex data */
  64. glGenBuffersARB(1, &VBO);
  65. glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
  66. glBufferDataARB(GL_ARRAY_BUFFER_ARB,
  67. sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
  68. glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
  69. glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
  70. glEnableClientState(GL_VERTEX_ARRAY);
  71. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  72. /* texture */
  73. glGenTextures(1, &TexObj);
  74. glBindTexture(GL_TEXTURE_2D, TexObj);
  75. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  76. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  77. glEnable(GL_TEXTURE_2D);
  78. }
  79. static void
  80. CreateUploadTexImage2D(unsigned count)
  81. {
  82. unsigned i;
  83. for (i = 0; i < count; i++) {
  84. if (TexObj)
  85. glDeleteTextures(1, &TexObj);
  86. glGenTextures(1, &TexObj);
  87. glBindTexture(GL_TEXTURE_2D, TexObj);
  88. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  89. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  90. glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
  91. TexSize, TexSize, 0,
  92. TexSrcFormat, TexSrcType, TexImage);
  93. if (DrawPoint)
  94. glDrawArrays(GL_POINTS, 0, 1);
  95. }
  96. glFinish();
  97. }
  98. static void
  99. UploadTexImage2D(unsigned count)
  100. {
  101. unsigned i;
  102. for (i = 0; i < count; i++) {
  103. /* XXX is this equivalent to a glTexSubImage call since we're
  104. * always specifying the same image size? That case isn't optimized
  105. * in Mesa but may be optimized in other drivers. Note sure how
  106. * much difference that might make.
  107. */
  108. glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
  109. TexSize, TexSize, 0,
  110. TexSrcFormat, TexSrcType, TexImage);
  111. if (DrawPoint)
  112. glDrawArrays(GL_POINTS, 0, 1);
  113. }
  114. glFinish();
  115. }
  116. static void
  117. UploadTexSubImage2D(unsigned count)
  118. {
  119. unsigned i;
  120. for (i = 0; i < count; i++) {
  121. if (TexSubImage4) {
  122. GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
  123. GLsizei halfPos = TexSize - halfSize;
  124. /* do glTexSubImage2D in four pieces */
  125. /* lower-left */
  126. glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
  127. glTexSubImage2D(GL_TEXTURE_2D, 0,
  128. 0, 0, halfSize, halfSize,
  129. TexSrcFormat, TexSrcType, TexImage);
  130. /* lower-right */
  131. glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
  132. glTexSubImage2D(GL_TEXTURE_2D, 0,
  133. halfPos, 0, halfSize, halfSize,
  134. TexSrcFormat, TexSrcType, TexImage);
  135. /* upper-left */
  136. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  137. glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
  138. glTexSubImage2D(GL_TEXTURE_2D, 0,
  139. 0, halfPos, halfSize, halfSize,
  140. TexSrcFormat, TexSrcType, TexImage);
  141. /* upper-right */
  142. glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
  143. glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
  144. glTexSubImage2D(GL_TEXTURE_2D, 0,
  145. halfPos, halfPos, halfSize, halfSize,
  146. TexSrcFormat, TexSrcType, TexImage);
  147. /* reset the unpacking state */
  148. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  149. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  150. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  151. }
  152. else {
  153. /* replace whole texture image at once */
  154. glTexSubImage2D(GL_TEXTURE_2D, 0,
  155. 0, 0, TexSize, TexSize,
  156. TexSrcFormat, TexSrcType, TexImage);
  157. }
  158. if (DrawPoint)
  159. glDrawArrays(GL_POINTS, 0, 1);
  160. }
  161. glFinish();
  162. }
  163. static void
  164. GetTexImage2D(unsigned count)
  165. {
  166. unsigned i;
  167. GLubyte *buf = (GLubyte *) malloc(TexSize * TexSize * 4);
  168. for (i = 0; i < count; i++) {
  169. glGetTexImage(GL_TEXTURE_2D, 0,
  170. TexSrcFormat, TexSrcType, buf);
  171. }
  172. glFinish();
  173. free(buf);
  174. }
  175. /* XXX any other formats to measure? */
  176. static const struct {
  177. GLenum format, type;
  178. GLenum internal_format;
  179. const char *name;
  180. GLuint texel_size;
  181. GLboolean full_test;
  182. } SrcFormats[] = {
  183. { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, "RGBA/ubyte", 4, GL_TRUE },
  184. { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, "RGB/ubyte", 3, GL_FALSE },
  185. { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, "RGB/565", 2, GL_FALSE },
  186. { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, "BGRA/ubyte", 4, GL_FALSE },
  187. { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, "L/ubyte", 1, GL_FALSE },
  188. { 0, 0, 0, NULL, 0, 0 }
  189. };
  190. /** Called from test harness/main */
  191. void
  192. PerfNextRound(void)
  193. {
  194. }
  195. /** Called from test harness/main */
  196. void
  197. PerfDraw(void)
  198. {
  199. GLint maxSize;
  200. double rate;
  201. GLint fmt, mode;
  202. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
  203. /* loop over source data formats */
  204. for (fmt = 0; SrcFormats[fmt].format; fmt++) {
  205. TexIntFormat = SrcFormats[fmt].internal_format;
  206. TexSrcFormat = SrcFormats[fmt].format;
  207. TexSrcType = SrcFormats[fmt].type;
  208. /* loop over glTexImage, glTexSubImage */
  209. for (mode = 0; mode < MODE_COUNT; mode++) {
  210. GLuint minsz, maxsz;
  211. if (SrcFormats[fmt].full_test) {
  212. minsz = 16;
  213. maxsz = 4096;
  214. }
  215. else {
  216. minsz = maxsz = 256;
  217. if (mode == MODE_CREATE_TEXIMAGE)
  218. continue;
  219. }
  220. /* loop over a defined range of texture sizes, test only the
  221. * ones which are legal for this driver.
  222. */
  223. for (TexSize = minsz; TexSize <= maxsz; TexSize *= 4) {
  224. double mbPerSec;
  225. if (TexSize <= maxSize) {
  226. GLint bytesPerImage;
  227. bytesPerImage = TexSize * TexSize * SrcFormats[fmt].texel_size;
  228. TexImage = malloc(bytesPerImage);
  229. switch (mode) {
  230. case MODE_TEXIMAGE:
  231. rate = PerfMeasureRate(UploadTexImage2D);
  232. break;
  233. case MODE_CREATE_TEXIMAGE:
  234. rate = PerfMeasureRate(CreateUploadTexImage2D);
  235. break;
  236. case MODE_TEXSUBIMAGE:
  237. /* create initial, empty texture */
  238. glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
  239. TexSize, TexSize, 0,
  240. TexSrcFormat, TexSrcType, NULL);
  241. rate = PerfMeasureRate(UploadTexSubImage2D);
  242. break;
  243. case MODE_GETTEXIMAGE:
  244. glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
  245. TexSize, TexSize, 0,
  246. TexSrcFormat, TexSrcType, TexImage);
  247. rate = PerfMeasureRate(GetTexImage2D);
  248. break;
  249. default:
  250. exit(1);
  251. }
  252. mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
  253. free(TexImage);
  254. {
  255. unsigned err;
  256. err = glGetError();
  257. if (err) {
  258. perf_printf("non-zero glGetError() %d\n", err);
  259. exit(1);
  260. }
  261. }
  262. }
  263. else {
  264. rate = 0;
  265. mbPerSec = 0;
  266. }
  267. perf_printf(" %s(%s %d x %d): "
  268. "%.1f images/sec, %.1f MB/sec\n",
  269. mode_name[mode],
  270. SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
  271. }
  272. if (SrcFormats[fmt].full_test)
  273. perf_printf("\n");
  274. }
  275. }
  276. exit(0);
  277. }