| /* |
| * Copyright 2000 Compaq Computer Inc. and VA Linux Systems, Inc. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * on the rights to use, copy, modify, merge, publish, distribute, sub |
| * license, and/or sell copies of the Software, and to permit persons to whom |
| * the Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
| * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| /** |
| * \file mgapixel.c |
| * Implement framebuffer pixel operations for MGA. |
| * |
| * \todo |
| * Someday the accelerated \c glReadPixels and \c glDrawPixels paths need to |
| * be resurrected. They are currently ifdef'ed out because they don't seem |
| * to work and they only get activated some very rare circumstances. |
| * |
| * \author Keith Whitwell <keith@tungstengraphics.com> |
| * \author Gareth Hughes <gareth@valinux.com> |
| */ |
| /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.9 2002/11/05 17:46:08 tsi Exp $ */ |
| |
| #include "mtypes.h" |
| #include "macros.h" |
| #include "mgadd.h" |
| #include "mgacontext.h" |
| #include "mgaioctl.h" |
| #include "mgapixel.h" |
| #include "mgastate.h" |
| |
| #include "swrast/swrast.h" |
| #include "imports.h" |
| |
| #if 0 |
| #define IS_AGP_MEM( mmesa, p ) \ |
| ((unsigned long)mmesa->mgaScreen->buffers.map <= ((unsigned long)p) && \ |
| (unsigned long)mmesa->mgaScreen->buffers.map + \ |
| (unsigned long)mmesa->mgaScreen->buffers.size > ((unsigned long)p)) |
| #define AGP_OFFSET( mmesa, p ) \ |
| (((unsigned long)p) - (unsigned long)mmesa->mgaScreen->buffers.map) |
| |
| |
| #if defined(MESA_packed_depth_stencil) |
| static GLboolean |
| check_depth_stencil_24_8( const GLcontext *ctx, GLenum type, |
| const struct gl_pixelstore_attrib *packing, |
| const void *pixels, GLint sz, |
| GLint pitch ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| |
| return ( type == GL_UNSIGNED_INT_24_8_MESA && |
| ctx->Visual->DepthBits == 24 && |
| ctx->Visual->StencilBits == 8 && |
| mmesa->mgaScreen->cpp == 4 && |
| mmesa->hw_stencil && |
| !ctx->Pixel.IndexShift && |
| !ctx->Pixel.IndexOffset && |
| !ctx->Pixel.MapStencilFlag && |
| ctx->Pixel.DepthBias == 0.0 && |
| ctx->Pixel.DepthScale == 1.0 && |
| !packing->SwapBytes && |
| pitch % 32 == 0 && |
| pitch < 4096 ); |
| } |
| #endif |
| |
| |
| static GLboolean |
| check_depth( const GLcontext *ctx, GLenum type, |
| const struct gl_pixelstore_attrib *packing, |
| const void *pixels, GLint sz, GLint pitch ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| |
| if ( IS_AGP_MEM( mmesa, pixels ) && |
| !( ( type == GL_UNSIGNED_INT && mmesa->mgaScreen->cpp == 4 ) || |
| ( type == GL_UNSIGNED_SHORT && mmesa->mgaScreen->cpp == 2 ) ) ) |
| return GL_FALSE; |
| |
| return ( ctx->Pixel.DepthBias == 0.0 && |
| ctx->Pixel.DepthScale == 1.0 && |
| !packing->SwapBytes && |
| pitch % 32 == 0 && |
| pitch < 4096 ); |
| } |
| |
| |
| static GLboolean |
| check_color( const GLcontext *ctx, GLenum type, GLenum format, |
| const struct gl_pixelstore_attrib *packing, |
| const void *pixels, GLint sz, GLint pitch ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| GLuint cpp = mmesa->mgaScreen->cpp; |
| |
| /* Can't do conversions on agp reads/draws. |
| */ |
| if ( IS_AGP_MEM( mmesa, pixels ) && |
| !( pitch % 32 == 0 && pitch < 4096 && |
| ( ( type == GL_UNSIGNED_BYTE && |
| cpp == 4 && format == GL_BGRA ) || |
| ( type == GL_UNSIGNED_INT_8_8_8_8 && |
| cpp == 4 && format == GL_BGRA ) || |
| ( type == GL_UNSIGNED_SHORT_5_6_5_REV && |
| cpp == 2 && format == GL_RGB ) ) ) ) |
| return GL_FALSE; |
| |
| return (!ctx->_ImageTransferState && |
| !packing->SwapBytes && |
| !packing->LsbFirst); |
| } |
| |
| static GLboolean |
| check_color_per_fragment_ops( const GLcontext *ctx ) |
| { |
| return (!( ctx->Color.AlphaEnabled || |
| ctx->Depth.Test || |
| ctx->Fog.Enabled || |
| ctx->Scissor.Enabled || |
| ctx->Stencil.Enabled || |
| !ctx->Color.ColorMask[0] || |
| !ctx->Color.ColorMask[1] || |
| !ctx->Color.ColorMask[2] || |
| !ctx->Color.ColorMask[3] || |
| ctx->Color.ColorLogicOpEnabled || |
| ctx->Texture._EnabledUnits |
| ) && |
| ctx->Current.RasterPosValid && |
| ctx->Pixel.ZoomX == 1.0F && |
| (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)); |
| } |
| |
| static GLboolean |
| check_depth_per_fragment_ops( const GLcontext *ctx ) |
| { |
| return ( ctx->Current.RasterPosValid && |
| ctx->Color.ColorMask[RCOMP] == 0 && |
| ctx->Color.ColorMask[BCOMP] == 0 && |
| ctx->Color.ColorMask[GCOMP] == 0 && |
| ctx->Color.ColorMask[ACOMP] == 0 && |
| ctx->Pixel.ZoomX == 1.0F && |
| ( ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F ) ); |
| } |
| |
| /* In addition to the requirements for depth: |
| */ |
| #if defined(MESA_packed_depth_stencil) |
| static GLboolean |
| check_stencil_per_fragment_ops( const GLcontext *ctx ) |
| { |
| return ( !ctx->Pixel.IndexShift && |
| !ctx->Pixel.IndexOffset ); |
| } |
| #endif |
| |
| |
| static GLboolean |
| clip_pixelrect( const GLcontext *ctx, |
| const GLframebuffer *buffer, |
| GLint *x, GLint *y, |
| GLsizei *width, GLsizei *height, |
| GLint *skipPixels, GLint *skipRows, |
| GLint *size ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| |
| *width = MIN2(*width, MAX_WIDTH); /* redundant? */ |
| |
| /* left clipping */ |
| if (*x < buffer->_Xmin) { |
| *skipPixels += (buffer->_Xmin - *x); |
| *width -= (buffer->_Xmin - *x); |
| *x = buffer->_Xmin; |
| } |
| |
| /* right clipping */ |
| if (*x + *width > buffer->_Xmax) |
| *width -= (*x + *width - buffer->_Xmax - 1); |
| |
| if (*width <= 0) |
| return GL_FALSE; |
| |
| /* bottom clipping */ |
| if (*y < buffer->_Ymin) { |
| *skipRows += (buffer->_Ymin - *y); |
| *height -= (buffer->_Ymin - *y); |
| *y = buffer->_Ymin; |
| } |
| |
| /* top clipping */ |
| if (*y + *height > buffer->_Ymax) |
| *height -= (*y + *height - buffer->_Ymax - 1); |
| |
| if (*height <= 0) |
| return GL_FALSE; |
| |
| *size = ((*y + *height - 1) * mmesa->mgaScreen->frontPitch + |
| (*x + *width - 1) * mmesa->mgaScreen->cpp); |
| |
| return GL_TRUE; |
| } |
| |
| static GLboolean |
| mgaTryReadPixels( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height, |
| GLenum format, GLenum type, |
| const struct gl_pixelstore_attrib *pack, |
| GLvoid *pixels ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| GLint size, skipPixels, skipRows; |
| GLint pitch = pack->RowLength ? pack->RowLength : width; |
| GLboolean ok; |
| |
| GLuint planemask; |
| GLuint source; |
| #if 0 |
| drmMGABlit blit; |
| GLuint dest; |
| GLint source_pitch, dest_pitch; |
| GLint delta_sx, delta_sy; |
| GLint delta_dx, delta_dy; |
| GLint blit_height, ydir; |
| #endif |
| |
| if (!clip_pixelrect(ctx, ctx->ReadBuffer, |
| &x, &y, &width, &height, |
| &skipPixels, &skipRows, &size)) { |
| return GL_TRUE; |
| } |
| |
| /* Only accelerate reading to agp buffers. |
| */ |
| if ( !IS_AGP_MEM(mmesa, (char *)pixels) || |
| !IS_AGP_MEM(mmesa, (char *)pixels + size) ) |
| return GL_FALSE; |
| |
| switch (format) { |
| #if defined(MESA_packed_depth_stencil) |
| case GL_DEPTH_STENCIL_MESA: |
| ok = check_depth_stencil_24_8(ctx, type, pack, pixels, size, pitch); |
| planemask = ~0; |
| source = mmesa->mgaScreen->depthOffset; |
| break; |
| #endif |
| |
| case GL_DEPTH_COMPONENT: |
| ok = check_depth(ctx, type, pack, pixels, size, pitch); |
| |
| /* Can't accelerate at this depth -- planemask does the wrong |
| * thing; it doesn't clear the low order bits in the |
| * destination, instead it leaves them untouched. |
| * |
| * Could get the acclerator to solid fill the destination with |
| * zeros first... Or get the cpu to do it... |
| */ |
| if (ctx->Visual.depthBits == 24) |
| return GL_FALSE; |
| |
| planemask = ~0; |
| source = mmesa->mgaScreen->depthOffset; |
| break; |
| |
| case GL_RGB: |
| case GL_BGRA: |
| ok = check_color(ctx, type, format, pack, pixels, size, pitch); |
| planemask = ~0; |
| source = (mmesa->draw_buffer == MGA_FRONT ? |
| mmesa->mgaScreen->frontOffset : |
| mmesa->mgaScreen->backOffset); |
| break; |
| |
| default: |
| return GL_FALSE; |
| } |
| |
| if (!ok) { |
| return GL_FALSE; |
| } |
| |
| |
| LOCK_HARDWARE( mmesa ); |
| |
| #if 0 |
| { |
| __DRIdrawablePrivate *dPriv = mmesa->driDrawable; |
| int nbox, retcode, i; |
| |
| UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); |
| |
| if (mmesa->dirty_cliprects & MGA_FRONT) |
| mgaUpdateRects( mmesa, MGA_FRONT ); |
| |
| nbox = dPriv->numClipRects; |
| |
| y = dPriv->h - y - height; |
| x += mmesa->drawX; |
| y += mmesa->drawY; |
| |
| dest = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) | |
| DO_dstmap_sys | DO_dstacc_agp); |
| source_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; |
| dest_pitch = pitch; |
| delta_sx = 0; |
| delta_sy = 0; |
| delta_dx = -x; |
| delta_dy = -y; |
| blit_height = 2*y + height; |
| ydir = -1; |
| |
| if (0) fprintf(stderr, "XX doing readpixel blit src_pitch %d dst_pitch %d\n", |
| source_pitch, dest_pitch); |
| |
| |
| |
| for (i = 0 ; i < nbox ; ) |
| { |
| int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); |
| drm_clip_rect_t *box = dPriv->pClipRects; |
| drm_clip_rect_t *b = mmesa->sarea->boxes; |
| int n = 0; |
| |
| for ( ; i < nr ; i++) { |
| GLint bx = box[i].x1; |
| GLint by = box[i].y1; |
| GLint bw = box[i].x2 - bx; |
| GLint bh = box[i].y2 - by; |
| |
| if (bx < x) bw -= x - bx, bx = x; |
| if (by < y) bh -= y - by, by = y; |
| if (bx + bw > x + width) bw = x + width - bx; |
| if (by + bh > y + height) bh = y + height - by; |
| if (bw <= 0) continue; |
| if (bh <= 0) continue; |
| |
| b->x1 = bx; |
| b->y1 = by; |
| b->x2 = bx + bw; |
| b->y2 = by + bh; |
| b++; |
| n++; |
| } |
| |
| mmesa->sarea->nbox = n; |
| |
| if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, |
| &blit, sizeof(drmMGABlit)))) { |
| fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); |
| UNLOCK_HARDWARE( mmesa ); |
| exit(1); |
| } |
| } |
| |
| UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); |
| } |
| #endif |
| |
| UNLOCK_HARDWARE( mmesa ); |
| |
| return GL_TRUE; |
| } |
| |
| static void |
| mgaDDReadPixels( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height, |
| GLenum format, GLenum type, |
| const struct gl_pixelstore_attrib *pack, |
| GLvoid *pixels ) |
| { |
| if (!mgaTryReadPixels( ctx, x, y, width, height, format, type, pack, pixels)) |
| _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels); |
| } |
| |
| |
| |
| |
| static void do_draw_pix( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height, |
| GLint pitch, |
| const void *pixels, |
| GLuint dest, GLuint planemask) |
| { |
| #if 0 |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| drmMGABlit blit; |
| __DRIdrawablePrivate *dPriv = mmesa->driDrawable; |
| drm_clip_rect_t pbox = dPriv->pClipRects; |
| int nbox = dPriv->numClipRects; |
| int retcode, i; |
| |
| y = dPriv->h - y - height; |
| x += mmesa->drawX; |
| y += mmesa->drawY; |
| |
| blit.dest = dest; |
| blit.planemask = planemask; |
| blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) |
| | SO_srcmap_sys | SO_srcacc_agp); |
| blit.dest_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; |
| blit.source_pitch = pitch; |
| blit.delta_sx = -x; |
| blit.delta_sy = -y; |
| blit.delta_dx = 0; |
| blit.delta_dy = 0; |
| if (ctx->Pixel.ZoomY == -1) { |
| blit.height = height; |
| blit.ydir = 1; |
| } else { |
| blit.height = height; |
| blit.ydir = -1; |
| } |
| |
| if (0) fprintf(stderr, |
| "doing drawpixel blit src_pitch %d dst_pitch %d\n", |
| blit.source_pitch, blit.dest_pitch); |
| |
| for (i = 0 ; i < nbox ; ) |
| { |
| int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); |
| drm_clip_rect_t *box = mmesa->pClipRects; |
| drm_clip_rect_t *b = mmesa->sarea->boxes; |
| int n = 0; |
| |
| for ( ; i < nr ; i++) { |
| GLint bx = box[i].x1; |
| GLint by = box[i].y1; |
| GLint bw = box[i].x2 - bx; |
| GLint bh = box[i].y2 - by; |
| |
| if (bx < x) bw -= x - bx, bx = x; |
| if (by < y) bh -= y - by, by = y; |
| if (bx + bw > x + width) bw = x + width - bx; |
| if (by + bh > y + height) bh = y + height - by; |
| if (bw <= 0) continue; |
| if (bh <= 0) continue; |
| |
| b->x1 = bx; |
| b->y1 = by; |
| b->x2 = bx + bw; |
| b->y2 = by + bh; |
| b++; |
| n++; |
| } |
| |
| mmesa->sarea->nbox = n; |
| |
| if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, |
| &blit, sizeof(drmMGABlit)))) { |
| fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); |
| UNLOCK_HARDWARE( mmesa ); |
| exit(1); |
| } |
| } |
| #endif |
| } |
| |
| |
| |
| |
| static GLboolean |
| mgaTryDrawPixels( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height, |
| GLenum format, GLenum type, |
| const struct gl_pixelstore_attrib *unpack, |
| const GLvoid *pixels ) |
| { |
| mgaContextPtr mmesa = MGA_CONTEXT(ctx); |
| GLint size, skipPixels, skipRows; |
| GLint pitch = unpack->RowLength ? unpack->RowLength : width; |
| GLuint dest, planemask; |
| GLuint cpp = mmesa->mgaScreen->cpp; |
| |
| if (!clip_pixelrect(ctx, ctx->DrawBuffer, |
| &x, &y, &width, &height, |
| &skipPixels, &skipRows, &size)) { |
| return GL_TRUE; |
| } |
| |
| |
| switch (format) { |
| #if defined(MESA_packed_depth_stencil) |
| case GL_DEPTH_STENCIL_MESA: |
| dest = mmesa->mgaScreen->depthOffset; |
| planemask = ~0; |
| if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) || |
| !check_depth_per_fragment_ops(ctx) || |
| !check_stencil_per_fragment_ops(ctx)) |
| return GL_FALSE; |
| break; |
| #endif |
| |
| case GL_DEPTH_COMPONENT: |
| dest = mmesa->mgaScreen->depthOffset; |
| |
| if (ctx->Visual.depthBits == 24) |
| planemask = ~0xff; |
| else |
| planemask = ~0; |
| |
| if (!check_depth(ctx, type, unpack, pixels, size, pitch) || |
| !check_depth_per_fragment_ops(ctx)) |
| return GL_FALSE; |
| break; |
| |
| case GL_RGB: |
| case GL_BGRA: |
| dest = (mmesa->draw_buffer == MGA_FRONT ? |
| mmesa->mgaScreen->frontOffset : |
| mmesa->mgaScreen->backOffset); |
| |
| planemask = mgaPackColor(cpp, |
| ctx->Color.ColorMask[RCOMP], |
| ctx->Color.ColorMask[GCOMP], |
| ctx->Color.ColorMask[BCOMP], |
| ctx->Color.ColorMask[ACOMP]); |
| |
| if (cpp == 2) |
| planemask |= planemask << 16; |
| |
| if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { |
| return GL_FALSE; |
| } |
| if (!check_color_per_fragment_ops(ctx)) { |
| return GL_FALSE; |
| } |
| break; |
| |
| default: |
| return GL_FALSE; |
| } |
| |
| LOCK_HARDWARE_QUIESCENT( mmesa ); |
| |
| if (mmesa->dirty_cliprects & MGA_FRONT) |
| mgaUpdateRects( mmesa, MGA_FRONT ); |
| |
| if ( IS_AGP_MEM(mmesa, (char *)pixels) && |
| IS_AGP_MEM(mmesa, (char *)pixels + size) ) |
| { |
| do_draw_pix( ctx, x, y, width, height, pitch, pixels, |
| dest, planemask ); |
| UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); |
| } |
| else |
| { |
| /* Pixels is in regular memory -- get dma buffers and perform |
| * upload through them. |
| */ |
| /* drmBufPtr buf = mgaGetBufferLocked(mmesa); */ |
| GLuint bufferpitch = (width*cpp+31)&~31; |
| |
| char *address = 0; /* mmesa->mgaScreen->agp.map; */ |
| |
| do { |
| /* GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */ |
| GLuint rows = height; |
| |
| |
| if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n", |
| rows, bufferpitch); |
| |
| /* The texture conversion code is so slow that there is only |
| * negligble speedup when the buffers/images don't exactly |
| * match: |
| */ |
| #if 0 |
| if (cpp == 2) { |
| if (!_mesa_convert_texsubimage2d( MESA_FORMAT_RGB565, |
| 0, 0, width, rows, |
| bufferpitch, format, type, |
| unpack, pixels, address )) { |
| /* mgaReleaseBufLocked( mmesa, buf ); */ |
| UNLOCK_HARDWARE(mmesa); |
| return GL_FALSE; |
| } |
| } else { |
| if (!_mesa_convert_texsubimage2d( MESA_FORMAT_ARGB8888, |
| 0, 0, width, rows, |
| bufferpitch, format, type, |
| unpack, pixels, address )) { |
| /* mgaReleaseBufLocked( mmesa, buf ); */ |
| UNLOCK_HARDWARE(mmesa); |
| return GL_FALSE; |
| } |
| } |
| #else |
| MEMCPY( address, pixels, rows*bufferpitch ); |
| #endif |
| |
| do_draw_pix( ctx, x, y, width, rows, |
| bufferpitch/cpp, address, dest, planemask ); |
| |
| /* Fix me -- use multiple buffers to avoid flush. |
| */ |
| UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); |
| |
| pixels = (void *)((char *) pixels + rows * pitch); |
| height -= rows; |
| y += rows; |
| } while (height); |
| |
| /* mgaReleaseBufLocked( mmesa, buf ); */ |
| } |
| |
| UNLOCK_HARDWARE( mmesa ); |
| mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; |
| |
| return GL_TRUE; |
| } |
| |
| static void |
| mgaDDDrawPixels( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height, |
| GLenum format, GLenum type, |
| const struct gl_pixelstore_attrib *unpack, |
| const GLvoid *pixels ) |
| { |
| if (!mgaTryDrawPixels( ctx, x, y, width, height, format, type, |
| unpack, pixels )) |
| _swrast_DrawPixels( ctx, x, y, width, height, format, type, |
| unpack, pixels ); |
| } |
| #endif |
| |
| |
| /* Stub functions - not a real allocator, always returns pointer to |
| * the same block of agp space which isn't used for anything else at |
| * present. |
| */ |
| void mgaDDInitPixelFuncs( GLcontext *ctx ) |
| { |
| #if 0 |
| /* evidently, these functions don't always work */ |
| if (getenv("MGA_BLIT_PIXELS")) { |
| ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */ |
| ctx->Driver.DrawPixels = mgaDDDrawPixels; /* works with agp/normal mem */ |
| } |
| #endif |
| } |