📄 mgapixel.c
字号:
/* * 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 GLbooleancheck_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 );}#endifstatic GLbooleancheck_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 GLbooleancheck_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 GLbooleancheck_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 GLbooleancheck_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 GLbooleancheck_stencil_per_fragment_ops( const GLcontext *ctx ){ return ( !ctx->Pixel.IndexShift && !ctx->Pixel.IndexOffset );}#endifstatic GLbooleanclip_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 GLbooleanmgaTryReadPixels( 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -