~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to progs/demos/texdown.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <GL/glut.h>
39
39
 
40
40
 
41
 
static GLsizei MaxSize = 1024;
42
 
static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0;
 
41
static GLsizei MaxSize = 2048;
 
42
static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0;
43
43
static GLboolean ScaleAndBias = GL_FALSE;
44
44
static GLboolean SubImage = GL_FALSE;
45
45
static GLdouble DownloadRate = 0.0;  /* texels/sec */
47
47
static GLuint Mode = 0;
48
48
 
49
49
 
 
50
/* Try and avoid L2 cache effects by cycling through a small number of
 
51
 * textures.
 
52
 * 
 
53
 * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will
 
54
 * keep us out of most caches at 32mb total.
 
55
 *
 
56
 * This turns into a fairly interesting question of what exactly you
 
57
 * expect to be in cache in normal usage, and what you think should be
 
58
 * outside.  There's no rules for this, no reason to favour one usage
 
59
 * over another except what the application you care about happens to
 
60
 * resemble most closely.
 
61
 *
 
62
 * - Should the client texture image be in L2 cache?  Has it just been
 
63
 *   generated or read from disk?
 
64
 * - Does the application really use >1 texture, or is it constantly 
 
65
 *   updating one image in-place?
 
66
 *
 
67
 * Different answers will favour different texture upload mechanisms.
 
68
 * To upload an image that is purely outside of cache, a DMA-based
 
69
 * upload will probably win, whereas for small, in-cache textures,
 
70
 * copying looks good.
 
71
 */
 
72
#define NR_TEXOBJ 4
 
73
static GLuint TexObj[NR_TEXOBJ];
 
74
 
 
75
 
50
76
struct FormatRec {
51
77
   GLenum Format;
52
78
   GLenum Type;
116
142
   }
117
143
}
118
144
 
 
145
/* On x86, there is a performance cliff for memcpy to texture memory
 
146
 * for sources below 64 byte alignment.  We do our best with this in
 
147
 * the driver, but it is better if the images are correctly aligned to
 
148
 * start with:
 
149
 */
 
150
#define ALIGN (1<<12)
 
151
 
 
152
static unsigned align(unsigned value, unsigned a)
 
153
{
 
154
   return (value + a - 1) & ~(a-1);
 
155
}
 
156
 
 
157
static int MIN2(int a, int b)
 
158
{
 
159
   return a < b ? a : b;
 
160
}
119
161
 
120
162
static void
121
163
MeasureDownloadRate(void)
122
164
{
123
165
   const int w = TexWidth + 2 * TexBorder;
124
166
   const int h = TexHeight + 2 * TexBorder;
125
 
   const int bytes = w * h * BytesPerTexel(Format);
 
167
   const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN);
 
168
   const int bytes = image_bytes * NR_TEXOBJ;
 
169
   GLubyte *orig_texImage, *orig_getImage;
126
170
   GLubyte *texImage, *getImage;
127
171
   GLdouble t0, t1, time;
128
172
   int count;
129
173
   int i;
130
 
 
131
 
   texImage = (GLubyte *) malloc(bytes);
132
 
   getImage = (GLubyte *) malloc(bytes);
133
 
   if (!texImage || !getImage) {
 
174
   int offset = 0;
 
175
   GLdouble total = 0;          /* ints will tend to overflow */
 
176
 
 
177
   printf("allocating %d bytes for %d %dx%d images\n",
 
178
          bytes, NR_TEXOBJ, w, h);
 
179
 
 
180
   orig_texImage = (GLubyte *) malloc(bytes + ALIGN);
 
181
   orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN);
 
182
   if (!orig_texImage || !orig_getImage) {
134
183
      DownloadRate = 0.0;
135
184
      return;
136
185
   }
137
186
 
 
187
   printf("alloc %p %p\n", orig_texImage, orig_getImage);
 
188
 
 
189
   texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN);
 
190
   getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN);   
 
191
 
 
192
   for (i = 1; !(((unsigned)texImage) & i); i<<=1)
 
193
      ;
 
194
   printf("texture image alignment: %d bytes (%p)\n", i, texImage);
 
195
      
138
196
   for (i = 0; i < bytes; i++) {
139
197
      texImage[i] = i & 0xff;
140
198
   }
166
224
   count = 0;
167
225
   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
168
226
   do {
 
227
      int img = count%NR_TEXOBJ;
 
228
      GLubyte *img_ptr = texImage + img * image_bytes;
 
229
 
 
230
      glBindTexture(GL_TEXTURE_2D, TexObj[img]);
 
231
 
169
232
      if (SubImage && count > 0) {
170
 
         glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
 
233
         /* Only update a portion of the image each iteration.  This
 
234
          * is presumably why you'd want to use texsubimage, otherwise
 
235
          * you may as well just call teximage again.
 
236
          *
 
237
          * A bigger question is whether to use a pointer that moves
 
238
          * with each call, ie does the incoming data come from L2
 
239
          * cache under normal circumstances, or is it pulled from
 
240
          * uncached memory?  
 
241
          * 
 
242
          * There's a good argument to say L2 cache, ie you'd expect
 
243
          * the data to have been recently generated.  It's possible
 
244
          * that it could have come from a file read, which may or may
 
245
          * not have gone through the cpu.
 
246
          */
 
247
         glTexSubImage2D(GL_TEXTURE_2D, 0, 
 
248
                         -TexBorder, 
 
249
                         -TexBorder + offset * h/8, 
 
250
                         w, 
 
251
                         h/8,
171
252
                         FormatTable[Format].Format,
172
 
                         FormatTable[Format].Type, texImage);
 
253
                         FormatTable[Format].Type, 
 
254
#if 1
 
255
                         texImage /* likely in L2$ */
 
256
#else
 
257
                         img_ptr + offset * bytes/8 /* unlikely in L2$ */
 
258
#endif
 
259
            );
 
260
         offset += 1;
 
261
         offset %= 8;
 
262
         total += w * h / 8;
173
263
      }
174
264
      else {
175
265
         glTexImage2D(GL_TEXTURE_2D, 0,
176
266
                      FormatTable[Format].IntFormat, w, h, TexBorder,
177
267
                      FormatTable[Format].Format,
178
 
                      FormatTable[Format].Type, texImage);
 
268
                      FormatTable[Format].Type, 
 
269
                      img_ptr);
 
270
         total += w*h;
179
271
      }
180
272
 
181
273
      /* draw a tiny polygon to force texture into texram */
192
284
 
193
285
   glDisable(GL_TEXTURE_2D);
194
286
 
195
 
   printf("w*h=%d  count=%d  time=%f\n", w*h, count, time);
196
 
   DownloadRate = w * h * count / time;
197
 
 
198
 
#if 0
199
 
   if (!ScaleAndBias) {
200
 
      /* verify texture readback */
201
 
      glGetTexImage(GL_TEXTURE_2D, 0,
202
 
                    FormatTable[Format].Format,
203
 
                    FormatTable[Format].Type, getImage);
204
 
      for (i = 0; i < w * h; i++) {
205
 
         if (texImage[i] != getImage[i]) {
206
 
            printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
207
 
         }
208
 
      }
209
 
   }
210
 
#endif
211
 
 
212
 
   free(texImage);
213
 
   free(getImage);
 
287
   printf("total texels=%f  time=%f\n", total, time);
 
288
   DownloadRate = total / time;
 
289
 
 
290
 
 
291
   free(orig_texImage); 
 
292
   free(orig_getImage); 
214
293
 
215
294
   {
216
295
      GLint err = glGetError();