~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c,v 1.3 2003/02/23 23:59:01 dawes Exp $ */
 
2
/*
 
3
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
4
 
 
5
The Weather Channel (TM) funded Tungsten Graphics to develop the
 
6
initial release of the Radeon 8500 driver under the XFree86 license.
 
7
This notice must be preserved.
 
8
 
 
9
Permission is hereby granted, free of charge, to any person obtaining
 
10
a copy of this software and associated documentation files (the
 
11
"Software"), to deal in the Software without restriction, including
 
12
without limitation the rights to use, copy, modify, merge, publish,
 
13
distribute, sublicense, and/or sell copies of the Software, and to
 
14
permit persons to whom the Software is furnished to do so, subject to
 
15
the following conditions:
 
16
 
 
17
The above copyright notice and this permission notice (including the
 
18
next paragraph) shall be included in all copies or substantial
 
19
portions of the Software.
 
20
 
 
21
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
22
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
23
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
24
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 
25
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
26
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
27
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
28
*/
 
29
 
 
30
/*
 
31
 * Authors:
 
32
 *   Keith Whitwell <keith@tungstengraphics.com>
 
33
 */
 
34
 
 
35
#include "glheader.h"
 
36
#include "mtypes.h"
 
37
#include "colormac.h"
 
38
#include "mem.h"
 
39
#include "mmath.h"
 
40
#include "macros.h"
 
41
 
 
42
#include "swrast_setup/swrast_setup.h"
 
43
#include "math/m_translate.h"
 
44
#include "tnl/tnl.h"
 
45
#include "tnl/t_context.h"
 
46
#include "tnl/t_imm_debug.h"
 
47
 
 
48
#include "r200_context.h"
 
49
#include "r200_ioctl.h"
 
50
#include "r200_state.h"
 
51
#include "r200_swtcl.h"
 
52
#include "r200_maos.h"
 
53
 
 
54
/* Usage:
 
55
 *   - from r200_tcl_render
 
56
 *   - call r200EmitArrays to ensure uptodate arrays in dma
 
57
 *   - emit primitives (new type?) which reference the data
 
58
 *       -- need to use elts for lineloop, quads, quadstrip/flat
 
59
 *       -- other primitives are all well-formed (need tristrip-1,fake-poly)
 
60
 *
 
61
 */
 
62
static void emit_ubyte_rgba3( GLcontext *ctx,
 
63
                       struct r200_dma_region *rvb,
 
64
                       char *data,
 
65
                       int stride,
 
66
                       int count )
 
67
{
 
68
   int i;
 
69
   r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);
 
70
 
 
71
   if (R200_DEBUG & DEBUG_VERTS)
 
72
      fprintf(stderr, "%s count %d stride %d out %p\n",
 
73
              __FUNCTION__, count, stride, out);
 
74
 
 
75
   for (i = 0; i < count; i++) {
 
76
      out->red   = *data;
 
77
      out->green = *(data+1);
 
78
      out->blue  = *(data+2);
 
79
      out->alpha = 0xFF;
 
80
      out++;
 
81
      data += stride;
 
82
   }
 
83
}
 
84
 
 
85
 
 
86
#if defined(USE_X86_ASM)
 
87
#define COPY_DWORDS( dst, src, nr )                                     \
 
88
do {                                                                    \
 
89
        int __tmp;                                                      \
 
90
        __asm__ __volatile__( "rep ; movsl"                             \
 
91
                              : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
 
92
                              : "0" (nr),                               \
 
93
                                "D" ((long)dst),                        \
 
94
                                "S" ((long)src) );                      \
 
95
} while (0)
 
96
#else
 
97
#define COPY_DWORDS( dst, src, nr )             \
 
98
do {                                            \
 
99
   int j;                                       \
 
100
   for ( j = 0 ; j < nr ; j++ )                 \
 
101
      dst[j] = ((int *)src)[j];                 \
 
102
   dst += nr;                                   \
 
103
} while (0)
 
104
#endif
 
105
 
 
106
 
 
107
 
 
108
static void emit_ubyte_rgba4( GLcontext *ctx,
 
109
                              struct r200_dma_region *rvb,
 
110
                              char *data,
 
111
                              int stride,
 
112
                              int count )
 
113
{
 
114
   int i;
 
115
   int *out = (int *)(rvb->address + rvb->start);
 
116
 
 
117
   if (R200_DEBUG & DEBUG_VERTS)
 
118
      fprintf(stderr, "%s count %d stride %d\n",
 
119
              __FUNCTION__, count, stride);
 
120
 
 
121
   if (stride == 4) {
 
122
      for (i = 0; i < count; i++)
 
123
         ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
 
124
   } else {
 
125
      for (i = 0; i < count; i++) {
 
126
         *(int *)out++ = LE32_TO_CPU(*(int *)data);
 
127
         data += stride;
 
128
      }
 
129
   }
 
130
}
 
131
 
 
132
 
 
133
static void emit_ubyte_rgba( GLcontext *ctx,
 
134
                             struct r200_dma_region *rvb,
 
135
                             char *data,
 
136
                             int size,
 
137
                             int stride,
 
138
                             int count )
 
139
{
 
140
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
141
 
 
142
   if (R200_DEBUG & DEBUG_VERTS)
 
143
      fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
 
144
 
 
145
   assert (!rvb->buf);
 
146
 
 
147
   if (stride == 0) {
 
148
      r200AllocDmaRegion( rmesa, rvb, 4, 4 );
 
149
      count = 1;
 
150
      rvb->aos_start = GET_START(rvb);
 
151
      rvb->aos_stride = 0;
 
152
      rvb->aos_size = 1;
 
153
   }
 
154
   else {
 
155
      r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 );   /* alignment? */
 
156
      rvb->aos_start = GET_START(rvb);
 
157
      rvb->aos_stride = 1;
 
158
      rvb->aos_size = 1;
 
159
   }
 
160
 
 
161
   /* Emit the data
 
162
    */
 
163
   switch (size) {
 
164
   case 3:
 
165
      emit_ubyte_rgba3( ctx, rvb, data, stride, count );
 
166
      break;
 
167
   case 4:
 
168
      emit_ubyte_rgba4( ctx, rvb, data, stride, count );
 
169
      break;
 
170
   default:
 
171
      assert(0);
 
172
      exit(1);
 
173
      break;
 
174
   }
 
175
}
 
176
 
 
177
 
 
178
 
 
179
 
 
180
static void emit_vec8( GLcontext *ctx,
 
181
                       struct r200_dma_region *rvb,
 
182
                       char *data,
 
183
                       int stride,
 
184
                       int count )
 
185
{
 
186
   int i;
 
187
   int *out = (int *)(rvb->address + rvb->start);
 
188
 
 
189
   if (R200_DEBUG & DEBUG_VERTS)
 
190
      fprintf(stderr, "%s count %d stride %d\n",
 
191
              __FUNCTION__, count, stride);
 
192
 
 
193
   if (stride == 8)
 
194
      COPY_DWORDS( out, data, count*2 );
 
195
   else
 
196
      for (i = 0; i < count; i++) {
 
197
         out[0] = *(int *)data;
 
198
         out[1] = *(int *)(data+4);
 
199
         out += 2;
 
200
         data += stride;
 
201
      }
 
202
}
 
203
 
 
204
static void emit_vec12( GLcontext *ctx,
 
205
                       struct r200_dma_region *rvb,
 
206
                       char *data,
 
207
                       int stride,
 
208
                       int count )
 
209
{
 
210
   int i;
 
211
   int *out = (int *)(rvb->address + rvb->start);
 
212
 
 
213
   if (R200_DEBUG & DEBUG_VERTS)
 
214
      fprintf(stderr, "%s count %d stride %d out %p data %p\n",
 
215
              __FUNCTION__, count, stride, out, data);
 
216
 
 
217
   if (stride == 12)
 
218
      COPY_DWORDS( out, data, count*3 );
 
219
   else
 
220
      for (i = 0; i < count; i++) {
 
221
         out[0] = *(int *)data;
 
222
         out[1] = *(int *)(data+4);
 
223
         out[2] = *(int *)(data+8);
 
224
         out += 3;
 
225
         data += stride;
 
226
      }
 
227
}
 
228
 
 
229
static void emit_vec16( GLcontext *ctx,
 
230
                        struct r200_dma_region *rvb,
 
231
                        char *data,
 
232
                        int stride,
 
233
                        int count )
 
234
{
 
235
   int i;
 
236
   int *out = (int *)(rvb->address + rvb->start);
 
237
 
 
238
   if (R200_DEBUG & DEBUG_VERTS)
 
239
      fprintf(stderr, "%s count %d stride %d\n",
 
240
              __FUNCTION__, count, stride);
 
241
 
 
242
   if (stride == 16)
 
243
      COPY_DWORDS( out, data, count*4 );
 
244
   else
 
245
      for (i = 0; i < count; i++) {
 
246
         out[0] = *(int *)data;
 
247
         out[1] = *(int *)(data+4);
 
248
         out[2] = *(int *)(data+8);
 
249
         out[3] = *(int *)(data+12);
 
250
         out += 4;
 
251
         data += stride;
 
252
      }
 
253
}
 
254
 
 
255
 
 
256
static void emit_vector( GLcontext *ctx,
 
257
                         struct r200_dma_region *rvb,
 
258
                         char *data,
 
259
                         int size,
 
260
                         int stride,
 
261
                         int count )
 
262
{
 
263
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
264
 
 
265
   if (R200_DEBUG & DEBUG_VERTS)
 
266
      fprintf(stderr, "%s count %d size %d stride %d\n",
 
267
              __FUNCTION__, count, size, stride);
 
268
 
 
269
   assert (!rvb->buf);
 
270
 
 
271
   if (stride == 0) {
 
272
      r200AllocDmaRegion( rmesa, rvb, size * 4, 4 );
 
273
      count = 1;
 
274
      rvb->aos_start = GET_START(rvb);
 
275
      rvb->aos_stride = 0;
 
276
      rvb->aos_size = size;
 
277
   }
 
278
   else {
 
279
      r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 );    /* alignment? */
 
280
      rvb->aos_start = GET_START(rvb);
 
281
      rvb->aos_stride = size;
 
282
      rvb->aos_size = size;
 
283
   }
 
284
 
 
285
   /* Emit the data
 
286
    */
 
287
   switch (size) {
 
288
   case 2:
 
289
      emit_vec8( ctx, rvb, data, stride, count );
 
290
      break;
 
291
   case 3:
 
292
      emit_vec12( ctx, rvb, data, stride, count );
 
293
      break;
 
294
   case 4:
 
295
      emit_vec16( ctx, rvb, data, stride, count );
 
296
      break;
 
297
   default:
 
298
      assert(0);
 
299
      exit(1);
 
300
      break;
 
301
   }
 
302
 
 
303
}
 
304
 
 
305
 
 
306
 
 
307
/* Emit any changed arrays to new agp memory, re-emit a packet to
 
308
 * update the arrays.  
 
309
 */
 
310
void r200EmitArrays( GLcontext *ctx, GLuint inputs )
 
311
{
 
312
   r200ContextPtr rmesa = R200_CONTEXT( ctx );
 
313
   struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
 
314
   struct r200_dma_region **component = rmesa->tcl.aos_components;
 
315
   GLuint nr = 0;
 
316
   GLuint vfmt0 = 0, vfmt1 = 0;
 
317
   GLuint count = VB->Count;
 
318
   
 
319
   if (R200_DEBUG & DEBUG_VERTS) 
 
320
      _tnl_print_vert_flags( __FUNCTION__, inputs );
 
321
 
 
322
   if (1) {
 
323
      if (!rmesa->tcl.obj.buf) 
 
324
         emit_vector( ctx, 
 
325
                      &rmesa->tcl.obj, 
 
326
                      (char *)VB->ObjPtr->data,
 
327
                      VB->ObjPtr->size,
 
328
                      VB->ObjPtr->stride,
 
329
                      count);
 
330
 
 
331
      switch( VB->ObjPtr->size ) {
 
332
      case 4: vfmt0 |= R200_VTX_W0;
 
333
      case 3: vfmt0 |= R200_VTX_Z0;
 
334
      case 2: 
 
335
      default:
 
336
        break;
 
337
      }
 
338
      component[nr++] = &rmesa->tcl.obj;
 
339
   }
 
340
   
 
341
 
 
342
   if (inputs & VERT_NORM) {
 
343
      if (!rmesa->tcl.norm.buf)
 
344
         emit_vector( ctx, 
 
345
                      &(rmesa->tcl.norm), 
 
346
                      (char *)VB->NormalPtr->data,
 
347
                      3,
 
348
                      VB->NormalPtr->stride,
 
349
                      count);
 
350
 
 
351
      vfmt0 |= R200_VTX_N0;
 
352
      component[nr++] = &rmesa->tcl.norm;
 
353
   }
 
354
 
 
355
   if (inputs & VERT_RGBA) {
 
356
      if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
 
357
         if (!rmesa->tcl.rgba.buf)
 
358
            emit_ubyte_rgba( ctx, 
 
359
                             &rmesa->tcl.rgba, 
 
360
                             (char *)VB->ColorPtr[0]->Ptr,
 
361
                             VB->ColorPtr[0]->Size,
 
362
                             VB->ColorPtr[0]->StrideB,
 
363
                             count);
 
364
 
 
365
         vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; 
 
366
      }
 
367
      else {
 
368
         int emitsize;
 
369
 
 
370
         if (VB->ColorPtr[0]->Size == 4 &&
 
371
             (VB->ColorPtr[0]->StrideB != 0 ||
 
372
              ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) { 
 
373
            vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; 
 
374
            emitsize = 4;
 
375
         }
 
376
         else { 
 
377
            vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; 
 
378
            emitsize = 3;
 
379
         }
 
380
 
 
381
         if (!rmesa->tcl.rgba.buf)
 
382
            emit_vector( ctx, 
 
383
                         &(rmesa->tcl.rgba), 
 
384
                         (char *)VB->ColorPtr[0]->Ptr,
 
385
                         emitsize,
 
386
                         VB->ColorPtr[0]->StrideB,
 
387
                         count);
 
388
      }
 
389
 
 
390
      component[nr++] = &rmesa->tcl.rgba;
 
391
   }
 
392
 
 
393
 
 
394
   if (inputs & VERT_SPEC_RGB) {
 
395
      if (!rmesa->tcl.spec.buf) {
 
396
         if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
 
397
            r200_import_float_spec_colors( ctx );
 
398
 
 
399
         emit_ubyte_rgba( ctx, 
 
400
                          &rmesa->tcl.spec, 
 
401
                          (char *)VB->SecondaryColorPtr[0]->Ptr,
 
402
                          3,
 
403
                          VB->SecondaryColorPtr[0]->StrideB,
 
404
                          count);
 
405
      }
 
406
 
 
407
      /* How does this work?
 
408
       */
 
409
      vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; 
 
410
      component[nr++] = &rmesa->tcl.spec;
 
411
   }
 
412
 
 
413
/*    vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
 
414
/*        ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */
 
415
      
 
416
   if (inputs & VERT_TEX0) {
 
417
      if (!rmesa->tcl.tex[0].buf)
 
418
         emit_vector( ctx, 
 
419
                      &(rmesa->tcl.tex[0]), 
 
420
                      (char *)VB->TexCoordPtr[0]->data,
 
421
                      VB->TexCoordPtr[0]->size,
 
422
                      VB->TexCoordPtr[0]->stride,
 
423
                      count );
 
424
 
 
425
      vfmt1 |= VB->TexCoordPtr[0]->size << R200_VTX_TEX0_COMP_CNT_SHIFT;
 
426
      component[nr++] = &rmesa->tcl.tex[0];
 
427
   }
 
428
 
 
429
   if (inputs & VERT_TEX1) {
 
430
      if (!rmesa->tcl.tex[1].buf)
 
431
         emit_vector( ctx, 
 
432
                      &(rmesa->tcl.tex[1]), 
 
433
                      (char *)VB->TexCoordPtr[1]->data,
 
434
                      VB->TexCoordPtr[1]->size,
 
435
                      VB->TexCoordPtr[1]->stride,
 
436
                      count );
 
437
         
 
438
      vfmt1 |= VB->TexCoordPtr[1]->size << R200_VTX_TEX1_COMP_CNT_SHIFT;
 
439
      component[nr++] = &rmesa->tcl.tex[1];
 
440
   }
 
441
 
 
442
   if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
 
443
       vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { 
 
444
      R200_STATECHANGE( rmesa, vtx ); 
 
445
      rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
 
446
      rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
 
447
   } 
 
448
 
 
449
 
 
450
/*    fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */
 
451
    
 
452
   rmesa->tcl.nr_aos_components = nr;
 
453
   rmesa->tcl.vertex_format = vfmt0;
 
454
}
 
455
 
 
456
 
 
457
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
 
458
{
 
459
   r200ContextPtr rmesa = R200_CONTEXT( ctx );
 
460
 
 
461
   if (R200_DEBUG & DEBUG_VERTS) 
 
462
      _tnl_print_vert_flags( __FUNCTION__, newinputs );
 
463
 
 
464
   if (newinputs & VERT_OBJ) 
 
465
     r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
 
466
 
 
467
   if (newinputs & VERT_NORM) 
 
468
      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
 
469
 
 
470
   if (newinputs & VERT_RGBA) 
 
471
      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
 
472
 
 
473
   if (newinputs & VERT_SPEC_RGB) 
 
474
      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
 
475
 
 
476
   if (newinputs & VERT_TEX0)
 
477
      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
 
478
 
 
479
   if (newinputs & VERT_TEX1)
 
480
      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
 
481
}