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

« back to all changes in this revision

Viewing changes to unix/xc/lib/GL/mesa/src/drv/sis/sis_alloc.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
/**************************************************************************
 
2
 
 
3
Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
 
4
All Rights Reserved.
 
5
 
 
6
Permission is hereby granted, free of charge, to any person obtaining a
 
7
copy of this software and associated documentation files (the
 
8
"Software"), to deal in the Software without restriction, including
 
9
without limitation the rights to use, copy, modify, merge, publish,
 
10
distribute, sub license, and/or sell copies of the Software, and to
 
11
permit persons to whom the Software is furnished to do so, subject to
 
12
the following conditions:
 
13
 
 
14
The above copyright notice and this permission notice (including the
 
15
next paragraph) shall be included in all copies or substantial portions
 
16
of the Software.
 
17
 
 
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 
 
26
**************************************************************************/
 
27
/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.7 2001/01/08 01:07:29 martin Exp $ */
 
28
 
 
29
/*
 
30
 * Authors:
 
31
 *    Sung-Ching Lin <sclin@sis.com.tw>
 
32
 *
 
33
 */
 
34
 
 
35
#include <assert.h>
 
36
 
 
37
#include "sis_ctx.h"
 
38
#include "sis_mesa.h"
 
39
 
 
40
#if defined(XFree86Server) && !defined(XF86DRI)
 
41
# include "xf86fbman.h"
 
42
#else
 
43
# define CONFIG_DRM_SIS
 
44
# include "drm.h"
 
45
# undef CONFIG_DRM_SIS
 
46
# include "sis_drm.h"
 
47
# include <sys/ioctl.h>
 
48
#endif
 
49
 
 
50
#define Z_BUFFER_HW_ALIGNMENT 16
 
51
#define Z_BUFFER_HW_PLUS (16 + 4)
 
52
 
 
53
/* 3D engine uses 2, and bitblt uses 4 */
 
54
#define DRAW_BUFFER_HW_ALIGNMENT 16
 
55
#define DRAW_BUFFER_HW_PLUS (16 + 4)
 
56
 
 
57
#define TEXTURE_HW_ALIGNMENT 4
 
58
#define TEXTURE_HW_PLUS (4 + 4)
 
59
 
 
60
#ifdef ROUNDUP
 
61
#undef ROUNDUP
 
62
#endif
 
63
#define ROUNDUP(nbytes, pad) (((nbytes)+(pad-1))/(pad))
 
64
 
 
65
#ifdef ALIGNMENT
 
66
#undef ALIGNMENT
 
67
#endif
 
68
#define ALIGNMENT(value, align) (ROUNDUP((value),(align))*(align))
 
69
 
 
70
#if defined(XFree86Server) && !defined(XF86DRI)
 
71
 
 
72
static void *
 
73
sis_alloc_fb (__GLSiScontext * hwcx, GLuint size, void **free)
 
74
{
 
75
  GLcontext *ctx = hwcx->gc;
 
76
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
77
 
 
78
  ScreenPtr pScreen = xmesa->display;
 
79
 
 
80
  GLuint offset;
 
81
  BoxPtr pBox;
 
82
 
 
83
  size = ROUNDUP (size, GET_DEPTH (hwcx));
 
84
  *free = xf86AllocateLinearOffscreenArea (pScreen, size, 1,
 
85
                                           NULL, NULL, NULL);
 
86
 
 
87
  if (!*free)
 
88
    return NULL;
 
89
 
 
90
  pBox = &((FBAreaPtr) (*free))->box;
 
91
  offset = pBox->y1 * GET_PITCH (hwcx) + pBox->x1 * GET_DEPTH (hwcx);
 
92
 
 
93
  return GET_FbBase (hwcx) + offset;
 
94
}
 
95
 
 
96
static void
 
97
sis_free_fb (int hHWContext, void *free)
 
98
{
 
99
  xf86FreeOffscreenArea ((FBAreaPtr) free);
 
100
}
 
101
 
 
102
#else
 
103
 
 
104
int gDRMSubFD = -1;
 
105
 
 
106
/* debug */
 
107
#if 1
 
108
 
 
109
static int _total_video_memory_used = 0;
 
110
static int _total_video_memory_count = 0;
 
111
 
 
112
static void *
 
113
sis_alloc_fb (__GLSiScontext * hwcx, GLuint size, void **free)
 
114
{
 
115
  GLcontext *ctx = hwcx->gc;
 
116
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
117
 
 
118
  drm_sis_mem_t fb;
 
119
 
 
120
  _total_video_memory_used += size;
 
121
 
 
122
  fb.context = xmesa->driContextPriv->hHWContext;
 
123
  fb.size = size;
 
124
  if(ioctl(hwcx->drmSubFD, SIS_IOCTL_FB_ALLOC, &fb) || !fb.offset)
 
125
    return NULL;
 
126
  *free = (void *)fb.free;
 
127
 
 
128
  /* debug */
 
129
  /* memset(fb.offset + GET_FbBase(hwcx), 0xff, size); */
 
130
 
 
131
  if (SIS_VERBOSE&VERBOSE_SIS_MEMORY)
 
132
  {
 
133
    fprintf(stderr, "sis_alloc_fb: size=%u, offset=%lu, pid=%lu, count=%d\n", 
 
134
           size, (DWORD)fb.offset, (DWORD)getpid(), 
 
135
           ++_total_video_memory_count);
 
136
  }
 
137
 
 
138
  return (void *)(fb.offset + GET_FbBase(hwcx));
 
139
}
 
140
 
 
141
static void
 
142
sis_free_fb (int hHWContext, void *free)
 
143
{
 
144
  drm_sis_mem_t fb;
 
145
 
 
146
  if (SIS_VERBOSE&VERBOSE_SIS_MEMORY)
 
147
  {
 
148
    fprintf(stderr, "sis_free_fb: free=%lu, pid=%lu, count=%d\n", 
 
149
            (DWORD)free, (DWORD)getpid(), --_total_video_memory_count);
 
150
  }
 
151
  
 
152
  fb.context = hHWContext;
 
153
  fb.free = (unsigned long)free;
 
154
  ioctl(gDRMSubFD, SIS_IOCTL_FB_FREE, &fb);
 
155
}
 
156
 
 
157
#else
 
158
 
 
159
static void *
 
160
sis_alloc_fb (__GLSiScontext * hwcx, GLuint size, void **free)
 
161
{
 
162
  static char *vidmem_base = 0x400000;
 
163
  char *rval = vidmem_base;
 
164
 
 
165
  vidmem_base += size;
 
166
  if(vidmem_base >= 31*0x100000)
 
167
    return NULL;
 
168
  
 
169
  *free = rval + (DWORD)hwcx->FbBase;
 
170
 
 
171
  return rval + (DWORD)hwcx->FbBase;
 
172
}
 
173
 
 
174
static void
 
175
sis_free_fb (int hHWContext, void *free)
 
176
{
 
177
  return;
 
178
}
 
179
 
 
180
#endif
 
181
 
 
182
#endif
 
183
 
 
184
static void *
 
185
sis_alloc_agp (__GLSiScontext * hwcx, GLuint size, void **free)
 
186
{
 
187
  GLcontext *ctx = hwcx->gc;
 
188
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
189
 
 
190
  drm_sis_mem_t agp;
 
191
  
 
192
  if(!hwcx->AGPSize)
 
193
    return NULL;
 
194
 
 
195
  agp.context = xmesa->driContextPriv->hHWContext;
 
196
  agp.size = size;
 
197
  if(ioctl(hwcx->drmSubFD, SIS_IOCTL_AGP_ALLOC, &agp) || !agp.offset)
 
198
    return NULL;
 
199
  *free = (void *)agp.free;
 
200
 
 
201
  if (SIS_VERBOSE&VERBOSE_SIS_MEMORY)
 
202
  {
 
203
    fprintf(stderr, "sis_alloc_agp: size=%u, offset=%lu, pid=%lu, count=%d\n", 
 
204
           size, (DWORD)agp.offset, (DWORD)getpid(), 
 
205
           ++_total_video_memory_count);
 
206
  }
 
207
 
 
208
  return (void *)(agp.offset + GET_AGPBase(hwcx));
 
209
}
 
210
 
 
211
static void
 
212
sis_free_agp (int hHWContext, void *free)
 
213
{
 
214
  drm_sis_mem_t agp;
 
215
 
 
216
  if (SIS_VERBOSE&VERBOSE_SIS_MEMORY)
 
217
  {
 
218
    fprintf(stderr, "sis_free_agp: free=%lu, pid=%lu, count=%d\n", 
 
219
            (DWORD)free, (DWORD)getpid(), --_total_video_memory_count);
 
220
  }
 
221
  
 
222
  agp.context = hHWContext;
 
223
  agp.free = (unsigned long)free;
 
224
  ioctl(gDRMSubFD, SIS_IOCTL_AGP_FREE, &agp);
 
225
}
 
226
 
 
227
/* debug */
 
228
static unsigned int Total_Real_Textures_Used = 0;
 
229
static unsigned int Total_Textures_Used = 0;
 
230
 
 
231
void
 
232
sis_alloc_z_stencil_buffer (GLcontext * ctx)
 
233
{
 
234
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
235
  __GLSiScontext *hwcx = (__GLSiScontext *) xmesa->private;
 
236
 
 
237
  XMesaBuffer xm_buffer = xmesa->xm_buffer;
 
238
  sisBufferInfo *priv = (sisBufferInfo *) xm_buffer->private;
 
239
 
 
240
  GLuint z_depth;
 
241
  GLuint totalBytes;
 
242
  int width2;
 
243
 
 
244
  GLubyte *addr;
 
245
 
 
246
  z_depth = (ctx->Visual->DepthBits + ctx->Visual->StencilBits) / 8;
 
247
 
 
248
  width2 = ALIGNMENT (xm_buffer->width * z_depth, 4);
 
249
 
 
250
  totalBytes = xm_buffer->height * width2 + Z_BUFFER_HW_PLUS;
 
251
 
 
252
  if (xm_buffer->depthbuffer)
 
253
    {
 
254
      sis_free_z_stencil_buffer (xm_buffer);
 
255
    }
 
256
 
 
257
  addr = sis_alloc_fb (hwcx, totalBytes, &priv->zbFree);
 
258
  if (!addr)
 
259
    {
 
260
      fprintf (stderr, "SIS driver : out of video memory\n");
 
261
      sis_fatal_error ();
 
262
    }
 
263
 
 
264
  if (SIS_VERBOSE&VERBOSE_SIS_BUFFER)
 
265
  {
 
266
    fprintf(stderr, "sis_alloc_z_stencil_buffer: addr=%lu\n", (DWORD)addr);
 
267
  }
 
268
 
 
269
  addr = (GLubyte *) ALIGNMENT ((unsigned long) addr, Z_BUFFER_HW_ALIGNMENT);
 
270
 
 
271
  xm_buffer->depthbuffer = (void *) addr;
 
272
 
 
273
  /* software render */
 
274
  hwcx->swZBase = addr;
 
275
  hwcx->swZPitch = width2;
 
276
 
 
277
  /* set pZClearPacket */
 
278
  memset (priv->pZClearPacket, 0, sizeof (ENGPACKET));
 
279
 
 
280
  priv->pZClearPacket->dwSrcPitch = (z_depth == 2) ? 0x80000000 : 0xf0000000;
 
281
  priv->pZClearPacket->dwDestBaseAddr =
 
282
    (DWORD) addr - (DWORD) GET_FbBase (hwcx);
 
283
  priv->pZClearPacket->wDestPitch = width2;
 
284
  priv->pZClearPacket->stdwDestPos.wY = 0;
 
285
  priv->pZClearPacket->stdwDestPos.wX = 0;
 
286
 
 
287
  priv->pZClearPacket->wDestHeight = hwcx->virtualY;
 
288
  priv->pZClearPacket->stdwDim.wWidth = (WORD) width2 / z_depth;
 
289
  priv->pZClearPacket->stdwDim.wHeight = (WORD) xm_buffer->height;
 
290
  priv->pZClearPacket->stdwCmd.cRop = 0xf0;
 
291
 
 
292
  if (hwcx->blockWrite)
 
293
    {
 
294
      priv->pZClearPacket->stdwCmd.cCmd0 = (BYTE) (CMD0_PAT_FG_COLOR);
 
295
      priv->pZClearPacket->stdwCmd.cCmd1 =
 
296
        (BYTE) (CMD1_DIR_X_INC | CMD1_DIR_Y_INC);
 
297
    }
 
298
  else
 
299
    {
 
300
      priv->pZClearPacket->stdwCmd.cCmd0 = 0;
 
301
      priv->pZClearPacket->stdwCmd.cCmd1 =
 
302
        (BYTE) (CMD1_DIR_X_INC | CMD1_DIR_Y_INC);
 
303
    }
 
304
}
 
305
 
 
306
void
 
307
sis_free_z_stencil_buffer (XMesaBuffer buf)
 
308
{
 
309
  sisBufferInfo *priv = (sisBufferInfo *) buf->private;
 
310
  XMesaContext xmesa = buf->xm_context;
 
311
 
 
312
  sis_free_fb (xmesa->driContextPriv->hHWContext, priv->zbFree);
 
313
  priv->zbFree = NULL;
 
314
  buf->depthbuffer = NULL;
 
315
}
 
316
 
 
317
void
 
318
sis_alloc_back_image (GLcontext * ctx, XMesaImage *image, void **free,
 
319
                      ENGPACKET *packet)
 
320
{
 
321
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
322
  __GLSiScontext *hwcx = (__GLSiScontext *) xmesa->private;
 
323
 
 
324
  XMesaBuffer xm_buffer = xmesa->xm_buffer;
 
325
 
 
326
  GLuint depth = GET_DEPTH (hwcx);
 
327
  GLuint size, width2;
 
328
 
 
329
  GLbyte *addr;
 
330
 
 
331
  if (image->data)
 
332
    {
 
333
      sis_free_back_image (xm_buffer, image, *free);
 
334
      *free = NULL;
 
335
    }
 
336
 
 
337
  width2 = (depth == 2) ? ALIGNMENT (xm_buffer->width, 2) : xm_buffer->width;
 
338
  size = width2 * xm_buffer->height * depth + DRAW_BUFFER_HW_PLUS;
 
339
 
 
340
  /* Fixme: unique context alloc/free back-buffer? */
 
341
  addr = sis_alloc_fb (hwcx, size, free);
 
342
  if (!addr)
 
343
    {
 
344
      fprintf (stderr, "SIS driver : out of video memory\n");
 
345
      sis_fatal_error ();
 
346
    }
 
347
 
 
348
  addr = (GLbyte *) ALIGNMENT ((unsigned long) addr, DRAW_BUFFER_HW_ALIGNMENT);
 
349
 
 
350
  image->data = (char *)addr;
 
351
 
 
352
  image->bytes_per_line = width2 * depth;
 
353
  image->bits_per_pixel = depth * 8;
 
354
 
 
355
  memset (packet, 0, sizeof (ENGPACKET));
 
356
 
 
357
  packet->dwSrcPitch = (depth == 2) ? 0x80000000 : 0xf0000000;
 
358
  packet->dwDestBaseAddr =
 
359
    (DWORD) addr - (DWORD) GET_FbBase (hwcx);
 
360
  packet->wDestPitch = image->bytes_per_line;
 
361
  packet->stdwDestPos.wY = 0;
 
362
  packet->stdwDestPos.wX = 0;
 
363
 
 
364
  packet->wDestHeight = hwcx->virtualY;
 
365
  packet->stdwDim.wWidth = (WORD) width2;
 
366
  packet->stdwDim.wHeight = (WORD) xm_buffer->height;
 
367
  packet->stdwCmd.cRop = 0xf0;
 
368
 
 
369
  if (hwcx->blockWrite)
 
370
    {
 
371
      packet->stdwCmd.cCmd0 = (BYTE) (CMD0_PAT_FG_COLOR);
 
372
      packet->stdwCmd.cCmd1 =
 
373
        (BYTE) (CMD1_DIR_X_INC | CMD1_DIR_Y_INC);
 
374
    }
 
375
  else
 
376
    {
 
377
      packet->stdwCmd.cCmd0 = 0;
 
378
      packet->stdwCmd.cCmd1 = (BYTE) (CMD1_DIR_X_INC | CMD1_DIR_Y_INC);
 
379
    }
 
380
}
 
381
 
 
382
void
 
383
sis_free_back_image (XMesaBuffer buf, XMesaImage *image, void *free)
 
384
{
 
385
  XMesaContext xmesa = buf->xm_context;
 
386
 
 
387
  sis_free_fb (xmesa->driContextPriv->hHWContext, free);
 
388
  image->data = NULL; 
 
389
}
 
390
 
 
391
void
 
392
sis_alloc_texture_image (GLcontext * ctx, GLtextureImage * image)
 
393
{
 
394
  XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
 
395
  __GLSiScontext *hwcx = (__GLSiScontext *) xmesa->private;
 
396
 
 
397
  GLuint size;
 
398
 
 
399
  SIStextureArea *area = image->DriverData;
 
400
  char *addr;
 
401
 
 
402
  GLuint texel_size;
 
403
  GLenum driver_format;
 
404
 
 
405
  if (area)
 
406
    sis_free_texture_image (image);
 
407
 
 
408
  area = calloc (1, sizeof (SIStextureArea));
 
409
  if (!area){
 
410
    fprintf (stderr, "SIS Driver : allocating context fails\n");
 
411
    sis_fatal_error ();
 
412
    return;
 
413
  }
 
414
 
 
415
  switch (image->IntFormat)
 
416
    {
 
417
    case GL_ALPHA:
 
418
    case GL_ALPHA4:
 
419
    case GL_ALPHA8:
 
420
    case GL_ALPHA12:
 
421
    case GL_ALPHA16:
 
422
      texel_size = 1;
 
423
      driver_format = GL_ALPHA8;
 
424
      break;
 
425
    case 1:
 
426
    case GL_LUMINANCE:
 
427
    case GL_LUMINANCE4:
 
428
    case GL_LUMINANCE8:
 
429
    case GL_LUMINANCE12:
 
430
    case GL_LUMINANCE16:
 
431
      texel_size = 1;
 
432
      driver_format = GL_LUMINANCE8;
 
433
      break;
 
434
    case 2:
 
435
    case GL_LUMINANCE_ALPHA:
 
436
    case GL_LUMINANCE4_ALPHA4:
 
437
    case GL_LUMINANCE6_ALPHA2:
 
438
    case GL_LUMINANCE8_ALPHA8:
 
439
    case GL_LUMINANCE12_ALPHA4:
 
440
    case GL_LUMINANCE12_ALPHA12:
 
441
    case GL_LUMINANCE16_ALPHA16:
 
442
      texel_size = 2;
 
443
      driver_format = GL_LUMINANCE8_ALPHA8;
 
444
      break;
 
445
    case GL_INTENSITY:
 
446
    case GL_INTENSITY4:
 
447
    case GL_INTENSITY8:
 
448
    case GL_INTENSITY12:
 
449
    case GL_INTENSITY16:
 
450
      texel_size = 1;
 
451
      driver_format = GL_INTENSITY8;
 
452
      break;
 
453
    case 3:
 
454
    case GL_RGB:
 
455
    case GL_R3_G3_B2:
 
456
    case GL_RGB4:
 
457
    case GL_RGB5:
 
458
    case GL_RGB8:
 
459
    case GL_RGB10:
 
460
    case GL_RGB12:
 
461
    case GL_RGB16:
 
462
      texel_size = 4;
 
463
      driver_format = GL_RGB8;
 
464
      break;
 
465
    case 4:
 
466
    case GL_RGBA:
 
467
    case GL_RGBA2:
 
468
    case GL_RGBA4:
 
469
    case GL_RGB5_A1:
 
470
    case GL_RGBA8:
 
471
    case GL_RGB10_A2:
 
472
    case GL_RGBA12:
 
473
    case GL_RGBA16:
 
474
      texel_size = 4;
 
475
      driver_format = GL_RGBA8;
 
476
      break;
 
477
    default:
 
478
      assert(0);
 
479
      return;
 
480
    }
 
481
 
 
482
  size = image->Width * image->Height * texel_size + TEXTURE_HW_PLUS;
 
483
 
 
484
  do{
 
485
    addr = sis_alloc_fb (hwcx, size, &area->free);
 
486
    area->memType = VIDEO_TYPE;
 
487
    if(addr) break;
 
488
    
 
489
    /* TODO: swap to agp memory*/
 
490
    /* video memory allocation fails */
 
491
    addr = sis_alloc_agp(hwcx, size, &area->free);
 
492
    area->memType = AGP_TYPE;
 
493
    if(addr) break;
 
494
    
 
495
    /* TODO: swap to system memory */
 
496
  }  
 
497
  while(0);
 
498
 
 
499
  if (!addr){
 
500
    fprintf (stderr, "SIS driver : out of video/agp memory\n");
 
501
    sis_fatal_error ();
 
502
    return;
 
503
  }
 
504
 
 
505
  area->Data =
 
506
    (GLbyte *) ALIGNMENT ((unsigned long) addr, TEXTURE_HW_ALIGNMENT);
 
507
  area->Pitch = image->Width * texel_size;
 
508
  area->Format = driver_format;
 
509
  area->Size = image->Width * image->Height * texel_size;
 
510
  area->texelSize = texel_size;
 
511
  area->hHWContext = xmesa->driContextPriv->hHWContext;
 
512
 
 
513
  /* debug */
 
514
  area->realSize = area->Size;
 
515
  Total_Real_Textures_Used += area->realSize;
 
516
  Total_Textures_Used++;
 
517
 
 
518
  image->DriverData = area;
 
519
}
 
520
 
 
521
void
 
522
sis_free_texture_image (GLtextureImage * image)
 
523
{
 
524
  SIStextureArea *area = (SIStextureArea *) image->DriverData;
 
525
 
 
526
  /* debug */
 
527
  Total_Real_Textures_Used -= area->realSize;
 
528
  Total_Textures_Used--;
 
529
 
 
530
  if (!area)
 
531
    return;
 
532
  
 
533
  if (area->Data)
 
534
    switch(area->memType){
 
535
    case VIDEO_TYPE:  
 
536
      sis_free_fb (area->hHWContext, area->free);
 
537
      break;
 
538
    case AGP_TYPE:  
 
539
      sis_free_agp (area->hHWContext, area->free);
 
540
      break;
 
541
    default:
 
542
      assert(0);
 
543
    }
 
544
 
 
545
  free (area);
 
546
  image->DriverData = NULL;
 
547
}