⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdfx_span.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
 */#define TILE_WIDTH_IN_BYTES		128#define TILE_WIDTH_IN_ZOXELS(bpz)	(TILE_WIDTH_IN_BYTES/(bpz))#define TILE_HEIGHT_IN_LINES		32typedef struct{   void *lfbPtr;   void *lfbWrapPtr;   FxU32 LFBStrideInElts;   GLint firstWrappedX;}LFBParameters;/* * We need information about the back buffer.  Note that * this function *cannot be called* while the aux buffer * is locked, or the caller will hang. * * Only Glide knows the LFB address of the back and depth * offsets.  The upper levels of Mesa know the depth offset, * but that is not in LFB space, it is tiled memory space, * and is not useable for us. */static voidGetBackBufferInfo(tdfxContextPtr fxMesa, GrLfbInfo_t * backBufferInfo){   READ_FB_SPAN_LOCK(fxMesa, *backBufferInfo, GR_BUFFER_BACKBUFFER);   READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_BACKBUFFER);}static voidGetFbParams(tdfxContextPtr fxMesa,            GrLfbInfo_t * info,            GrLfbInfo_t * backBufferInfo,            LFBParameters * ReadParamsp, FxU32 elementSize){   FxU32 physicalStrideInBytes, bufferOffset;   FxU32 strideInBytes = info->strideInBytes;   char *lfbPtr = (char *) (info->lfbPtr); /* For arithmetic, use char * */   /*    * These two come directly from the info structure.    */   ReadParamsp->lfbPtr = (void *) lfbPtr;   ReadParamsp->LFBStrideInElts = strideInBytes / elementSize;   /*    * Now, calculate the value of firstWrappedX.    *    * The physical stride is the screen width in bytes rounded up to    * the next highest multiple of 128 bytes.  Note that this fails    * when TILE_WIDTH_IN_BYTES is not a power of two.    *    * The buffer Offset is the distance between the beginning of    * the LFB space, which is the beginning of the back buffer,    * and the buffer we are gathering information about.    * We want to make this routine usable for operations on the    * back buffer, though we don't actually use it on the back    * buffer.  Note, then, that if bufferOffset == 0, the firstWrappedX    * is in the forbidden zone, and is therefore never reached.    *    * Note that if    *     physicalStrideInBytes    *             < bufferOffset&(info->strideInBytes-1)    * the buffer begins in the forbidden zone.  We assert for this.    */   bufferOffset = (FxU32)(lfbPtr - (char *) backBufferInfo->lfbPtr);   physicalStrideInBytes      = (fxMesa->screen_width * elementSize + TILE_WIDTH_IN_BYTES - 1)      & ~(TILE_WIDTH_IN_BYTES - 1);   assert(physicalStrideInBytes > (bufferOffset & (strideInBytes - 1)));   ReadParamsp->firstWrappedX      = (physicalStrideInBytes	 - (bufferOffset & (strideInBytes - 1))) / elementSize;   /*    * This is the address of the next physical line.    */   ReadParamsp->lfbWrapPtr      = (void *) ((char *) backBufferInfo->lfbPtr		  + (bufferOffset & ~(strideInBytes - 1))		  + (TILE_HEIGHT_IN_LINES) * strideInBytes);}/* * These macros fetch data from the frame buffer.  The type is * the type of data we want to fetch.  It should match the type * whose size was used with GetFbParams to fill in the structure * in *ReadParamsp.  We have a macro to read the ordinary * part, a second macro to read the wrapped part, and one which * will do either.  When we are reading a span, we will know * when the ordinary part ends, so there's no need to test for * it.  However, when reading and writing pixels, we don't * necessarily know.  I suppose it's a matter of taste whether * it's better in the macro or in the call. * * Recall that x and y are screen coordinates. */#define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y)               \    (((type *)((ReadParamsp)->lfbPtr))                              \                 [(y) * ((ReadParamsp)->LFBStrideInElts)            \                   + (x)])#define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y)                \    (((type *)((ReadParamsp)->lfbWrapPtr))                          \                 [((y)) * ((ReadParamsp)->LFBStrideInElts)          \                   + ((x) - (ReadParamsp)->firstWrappedX)])#define GET_FB_DATA(ReadParamsp, type, x, y)                        \   (((x) < (ReadParamsp)->firstWrappedX)                            \        ? GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y)             \        : GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y))#define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value)              \    (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value))#define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value)                \    (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value))#define PUT_FB_DATA(ReadParamsp, type, x, y, value)                 \    do {                                                            \        if ((x) < (ReadParamsp)->firstWrappedX)                     \            PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value);   \        else                                                        \            PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value);    \    } while (0)static voidtdfxDDWriteDepthSpan(GLcontext * ctx, struct gl_renderbuffer *rb,		     GLuint n, GLint x, GLint y, const void *values,		     const GLubyte mask[]){   const GLuint *depth = (const GLuint *) values;   tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;   GLint bottom = fxMesa->y_offset + fxMesa->height - 1;   GLuint depth_size = fxMesa->glCtx->Visual.depthBits;   GLuint stencil_size = fxMesa->glCtx->Visual.stencilBits;   GrLfbInfo_t info;   GLubyte visMask[MAX_WIDTH];   if (MESA_VERBOSE & VERBOSE_DRIVER) {      fprintf(stderr, "tdfxmesa: tdfxDDWriteDepthSpan(...)\n");   }   assert((depth_size == 16) || (depth_size == 24) || (depth_size == 32));   /*    * Convert x and y to screen coordinates.    */   x += fxMesa->x_offset;   y = bottom - y;   if (mask) {      GLint i;      GLushort d16;      GrLfbInfo_t backBufferInfo;      switch (depth_size) {      case 16:	 GetBackBufferInfo(fxMesa, &backBufferInfo);	 /*	  * Note that the _LOCK macro adds a curly brace,	  * and the UNLOCK macro removes it.	  */	 WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER,			    GR_LFBWRITEMODE_ANY);	 generate_vismask(fxMesa, x, y, n, visMask);	 {	    LFBParameters ReadParams;	    int wrappedPartStart;	    GetFbParams(fxMesa, &info, &backBufferInfo,			&ReadParams, sizeof(GLushort));	    if (ReadParams.firstWrappedX <= x) {	       wrappedPartStart = 0;	    }	    else if (n <= (ReadParams.firstWrappedX - x)) {	       wrappedPartStart = n;	    }	    else {	       wrappedPartStart = (ReadParams.firstWrappedX - x);	    }	    for (i = 0; i < wrappedPartStart; i++) {	       if (mask[i] && visMask[i]) {		  d16 = depth[i];		  PUT_ORDINARY_FB_DATA(&ReadParams, GLushort, x + i, y, d16);	       }	    }	    for (; i < n; i++) {	       if (mask[i] && visMask[i]) {		  d16 = depth[i];		  PUT_WRAPPED_FB_DATA(&ReadParams, GLushort, x + i, y, d16);	       }	    }	 }	 WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER);	 break;      case 24:      case 32:	 GetBackBufferInfo(fxMesa, &backBufferInfo);	 /*	  * Note that the _LOCK macro adds a curly brace,	  * and the UNLOCK macro removes it.	  */	 WRITE_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER,			    GR_LFBWRITEMODE_ANY);	 generate_vismask(fxMesa, x, y, n, visMask);	 {	    LFBParameters ReadParams;	    int wrappedPartStart;	    GetFbParams(fxMesa, &info, &backBufferInfo,			&ReadParams, sizeof(GLuint));	    if (ReadParams.firstWrappedX <= x) {	       wrappedPartStart = 0;	    }	    else if (n <= (ReadParams.firstWrappedX - x)) {	       wrappedPartStart = n;	    }	    else {	       wrappedPartStart = (ReadParams.firstWrappedX - x);	    }	    for (i = 0; i < wrappedPartStart; i++) {	       GLuint d32;	       if (mask[i] && visMask[i]) {		  if (stencil_size > 0) {		     d32 =			GET_ORDINARY_FB_DATA(&ReadParams, GLuint,					     x + i, y);		     d32 =			(d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF);		  }		  else {		     d32 = depth[i];		  }		  PUT_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y, d32);	       }	    }	    for (; i < n; i++) {	       GLuint d32;	       if (mask[i] && visMask[i]) {		  if (stencil_size > 0) {		     d32 =			GET_WRAPPED_FB_DATA(&ReadParams, GLuint,					    x + i, y);		     d32 =			(d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF);		  }		  else {		     d32 = depth[i];		  }		  PUT_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y, d32);	       }	    }	 }	 WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER);	 break;      }   }   else {      GLint i;      GLuint d32;      GLushort d16;      GrLfbInfo_t backBufferInfo;      switch (depth_size) {      case 16:	 GetBackBufferInfo(fxMesa, &backBufferInfo);	 /*	  * Note that the _LOCK macro adds a curly brace,	  * and the UNLOCK macro removes it.	  */	 WRITE_FB_SPAN_LOCK(fxMesa, info,			    GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY);	 generate_vismask(fxMesa, x, y, n, visMask);	 {	    LFBParameters ReadParams;	    GLuint wrappedPartStart;	    GetFbParams(fxMesa, &info, &backBufferInfo,			&ReadParams, sizeof(GLushort));	    if (ReadParams.firstWrappedX <= x) {	       wrappedPartStart = 0;	    }	    else if (n <= (ReadParams.firstWrappedX - x)) {	       wrappedPartStart = n;	    }	    else {	       wrappedPartStart = (ReadParams.firstWrappedX - x);	    }	    for (i = 0; i < wrappedPartStart; i++) {	       if (visMask[i]) {		  d16 = depth[i];		  PUT_ORDINARY_FB_DATA(&ReadParams,				       GLushort,				       x + i, y,				       d16);	       }	    }	    for (; i < n; i++) {	       if (visMask[i]) {		  d16 = depth[i];		  PUT_WRAPPED_FB_DATA(&ReadParams,				      GLushort,				      x + i, y,				      d16);	       }	    }	 }	 WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER);	 break;      case 24:      case 32:	 GetBackBufferInfo(fxMesa, &backBufferInfo);	 /*	  * Note that the _LOCK macro adds a curly brace,	  * and the UNLOCK macro removes it.	  */	 WRITE_FB_SPAN_LOCK(fxMesa, info,			    GR_BUFFER_AUXBUFFER, GR_LFBWRITEMODE_ANY);	 generate_vismask(fxMesa, x, y, n, visMask);	 {	    LFBParameters ReadParams;	    GLuint wrappedPartStart;	    GetFbParams(fxMesa, &info, &backBufferInfo,			&ReadParams, sizeof(GLuint));	    if (ReadParams.firstWrappedX <= x) {	       wrappedPartStart = 0;	    }	    else if (n <= (ReadParams.firstWrappedX - x)) {	       wrappedPartStart = n;	    }	    else {	       wrappedPartStart = (ReadParams.firstWrappedX - x);	    }	    for (i = 0; i < wrappedPartStart; i++) {	       if (visMask[i]) {		  if (stencil_size > 0) {		     d32 = GET_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y);		     d32 =			(d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF);		  }		  else {		     d32 = depth[i];		  }		  PUT_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y, d32);	       }	    }	    for (; i < n; i++) {	       if (visMask[i]) {		  if (stencil_size > 0) {		     d32 = GET_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y);		     d32 =			(d32 & 0xFF000000) | (depth[i] & 0x00FFFFFF);		  }		  else {		     d32 = depth[i];		  }		  PUT_WRAPPED_FB_DATA(&ReadParams, GLuint, x + i, y, d32);	       }	    }	 }	 WRITE_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER);	 break;      }   }}static voidtdfxDDWriteMonoDepthSpan(GLcontext * ctx, struct gl_renderbuffer *rb,                         GLuint n, GLint x, GLint y, const void *value,                         const GLubyte mask[]){   GLuint depthVal = *((GLuint *) value);   GLuint depths[MAX_WIDTH];   GLuint i;   for (i = 0; i < n; i++)      depths[i] = depthVal;   tdfxDDWriteDepthSpan(ctx, rb, n, x, y, depths, mask);}static voidtdfxDDReadDepthSpan(GLcontext * ctx, struct gl_renderbuffer *rb,		    GLuint n, GLint x, GLint y, void *values){   GLuint *depth = (GLuint *) values;   tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;   GLint bottom = fxMesa->height + fxMesa->y_offset - 1;   GLuint i;   GLuint depth_size = fxMesa->glCtx->Visual.depthBits;   GrLfbInfo_t info;   if (MESA_VERBOSE & VERBOSE_DRIVER) {      fprintf(stderr, "tdfxmesa: tdfxDDReadDepthSpan(...)\n");   }   /*    * Convert to screen coordinates.    */   x += fxMesa->x_offset;   y = bottom - y;   switch (depth_size) {   case 16:   {      LFBParameters ReadParams;      GrLfbInfo_t backBufferInfo;      int wrappedPartStart;      GetBackBufferInfo(fxMesa, &backBufferInfo);      /*       * Note that the _LOCK macro adds a curly brace,       * and the UNLOCK macro removes it.       */      READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER);      GetFbParams(fxMesa, &info, &backBufferInfo,		  &ReadParams, sizeof(GLushort));      if (ReadParams.firstWrappedX <= x) {	 wrappedPartStart = 0;      }      else if (n <= (ReadParams.firstWrappedX - x)) {	 wrappedPartStart = n;      }      else {	 wrappedPartStart = (ReadParams.firstWrappedX - x);      }      /*       * Read the line.       */      for (i = 0; i < wrappedPartStart; i++) {	 depth[i] =	    GET_ORDINARY_FB_DATA(&ReadParams, GLushort, x + i, y);      }      for (; i < n; i++) {	 depth[i] = GET_WRAPPED_FB_DATA(&ReadParams, GLushort,					x + i, y);      }      READ_FB_SPAN_UNLOCK(fxMesa, GR_BUFFER_AUXBUFFER);      break;   }   case 24:   case 32:   {      LFBParameters ReadParams;      GrLfbInfo_t backBufferInfo;      int wrappedPartStart;      GLuint stencil_size = fxMesa->glCtx->Visual.stencilBits;      GetBackBufferInfo(fxMesa, &backBufferInfo);      /*       * Note that the _LOCK macro adds a curly brace,       * and the UNLOCK macro removes it.       */      READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER);      GetFbParams(fxMesa, &info, &backBufferInfo,		  &ReadParams, sizeof(GLuint));      if (ReadParams.firstWrappedX <= x) {	 wrappedPartStart = 0;      }      else if (n <= (ReadParams.firstWrappedX - x)) {	 wrappedPartStart = n;      }      else {	 wrappedPartStart = (ReadParams.firstWrappedX - x);      }      /*       * Read the line.       */      for (i = 0; i < wrappedPartStart; i++) {	 const GLuint mask =	    (stencil_size > 0) ? 0x00FFFFFF : 0xFFFFFFFF;	 depth[i] =	    GET_ORDINARY_FB_DATA(&ReadParams, GLuint, x + i, y);	 depth[i] &= mask;      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -