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

📄 texmem.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
{   unsigned   heap;   unsigned   log2_size;   /* Determine the largest texture size such that a texture of that size    * can be bound to each texture unit at the same time.  Some hardware    * may require that all textures be in the same texture heap for    * multitexturing.    */   for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) {      unsigned   total = 0;      for ( heap = 0 ; heap < nr_heaps ; heap++ )      {	 total += max_textures[ heap ].c[ log2_size ];	 if ( 0 ) {	    fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] = %u, "		     "total = %u\n", __FILE__, __LINE__, heap, log2_size,		     max_textures[ heap ].c[ log2_size ], total );	 }	 if ( (max_textures[ heap ].c[ log2_size ] >= texture_units)	      || (!all_textures_one_heap && (total >= texture_units)) ) {	    /* The number of mipmap levels is the log-base-2 of the	     * maximum texture size plus 1.  If the maximum texture size	     * is 1x1, the log-base-2 is 0 and 1 mipmap level (the base	     * level) is available.	     */	    return log2_size + 1;	 }      }   }   /* This should NEVER happen.  It should always be possible to have at    * *least* a 1x1 texture in memory!    */   assert( log2_size != 0 );   return 0;}#define SET_MAX(f,v) \    do { if ( max_sizes[v] != 0 ) { limits-> f = max_sizes[v]; } } while( 0 )#define SET_MAX_RECT(f,v) \    do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << (max_sizes[v] - 1); } } while( 0 )/** * Given the amount of texture memory, the number of texture units, and the * maximum size of a texel, calculate the maximum texture size the driver can * advertise. *  * \param heaps Texture heaps for this card * \param nr_heap Number of texture heaps * \param limits OpenGL contants.  MaxTextureUnits must be set. * \param max_bytes_per_texel Maximum size of a single texel, in bytes * \param max_2D_size \f$\log_2\f$ of the maximum 2D texture size (i.e., *     1024x1024 textures, this would be 10) * \param max_3D_size \f$\log_2\f$ of the maximum 3D texture size (i.e., *     1024x1024x1024 textures, this would be 10) * \param max_cube_size \f$\log_2\f$ of the maximum cube texture size (i.e., *     1024x1024 textures, this would be 10) * \param max_rect_size \f$\log_2\f$ of the maximum texture rectangle size *     (i.e., 1024x1024 textures, this would be 10).  This is a power-of-2 *     even though texture rectangles need not be a power-of-2. * \param mipmaps_at_once Total number of mipmaps that can be used *     at one time.  For most hardware this will be \f$\c max_size + 1\f$. *     For hardware that does not support mipmapping, this will be 1. * \param all_textures_one_heap True if the hardware requires that all *     textures be in a single texture heap for multitexturing. * \param allow_larger_textures 0 conservative, 1 calculate limits *     so at least one worst-case texture can fit, 2 just use hw limits. */voiddriCalculateMaxTextureLevels( driTexHeap * const * heaps,			      unsigned nr_heaps,			      struct gl_constants * limits,			      unsigned max_bytes_per_texel,			      unsigned max_2D_size,			      unsigned max_3D_size,			      unsigned max_cube_size,			      unsigned max_rect_size,			      unsigned mipmaps_at_once,			      int all_textures_one_heap,			      int allow_larger_textures ){   struct maps_per_heap  max_textures[8];   unsigned         i;   const unsigned   dimensions[4] = { 2, 3, 2, 2 };   const unsigned   faces[4]      = { 1, 1, 6, 1 };   unsigned         max_sizes[4];   unsigned         mipmaps[4];   max_sizes[0] = max_2D_size;   max_sizes[1] = max_3D_size;   max_sizes[2] = max_cube_size;   max_sizes[3] = max_rect_size;   mipmaps[0] = mipmaps_at_once;   mipmaps[1] = mipmaps_at_once;   mipmaps[2] = mipmaps_at_once;   mipmaps[3] = 1;   /* Calculate the maximum number of texture levels in two passes.  The    * first pass determines how many textures of each power-of-two size    * (including all mipmap levels for that size) can fit in each texture    * heap.  The second pass finds the largest texture size that allows    * a texture of that size to be bound to every texture unit.    */   for ( i = 0 ; i < 4 ; i++ ) {      if ( (allow_larger_textures != 2) && (max_sizes[ i ] != 0) ) {	 fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel,			   max_sizes[ i ], mipmaps[ i ],			   dimensions[ i ], faces[ i ],			   max_textures );	 max_sizes[ i ] = get_max_size( nr_heaps,					allow_larger_textures == 1 ?					1 : limits->MaxTextureUnits,					max_sizes[ i ],					all_textures_one_heap,					max_textures );      }      else if (max_sizes[ i ] != 0) {	 max_sizes[ i ] += 1;      }   }   SET_MAX( MaxTextureLevels,        0 );   SET_MAX( Max3DTextureLevels,      1 );   SET_MAX( MaxCubeTextureLevels,    2 );   SET_MAX_RECT( MaxTextureRectSize, 3 );}/** * Perform initial binding of default textures objects on a per unit, per * texture target basis. * * \param ctx Current OpenGL context * \param swapped List of swapped-out textures * \param targets Bit-mask of value texture targets */void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped,			    GLuint targets ){   struct gl_texture_object *texObj;   GLuint tmp = ctx->Texture.CurrentUnit;   unsigned   i;   for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {      ctx->Texture.CurrentUnit = i;      if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) {	 texObj = ctx->Texture.Unit[i].Current1D;	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj );	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData );      }      if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) {	 texObj = ctx->Texture.Unit[i].Current2D;	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj );	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData );      }      if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) {	 texObj = ctx->Texture.Unit[i].Current3D;	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj );	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData );      }      if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) {	 texObj = ctx->Texture.Unit[i].CurrentCubeMap;	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj );	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData );      }      if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) {	 texObj = ctx->Texture.Unit[i].CurrentRect;	 ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj );	 move_to_tail( swapped, (driTextureObject *) texObj->DriverData );      }   }   ctx->Texture.CurrentUnit = tmp;}/** * Verify that the specified texture is in the specificed heap. *  * \param tex   Texture to be tested. * \param heap  Texture memory heap to be tested. * \return True if the texture is in the heap, false otherwise. */static GLbooleancheck_in_heap( const driTextureObject * tex, const driTexHeap * heap ){#if 1   return tex->heap == heap;#else   driTextureObject * curr;   foreach( curr, & heap->texture_objects ) {      if ( curr == tex ) {	 break;      }   }   return curr == tex;#endif}/****************************************************************************//** * Validate the consistency of a set of texture heaps. * Original version by Keith Whitwell in r200/r200_sanity.c. */GLbooleandriValidateTextureHeaps( driTexHeap * const * texture_heaps,			 unsigned nr_heaps, const driTextureObject * swapped ){   driTextureObject *t;   unsigned  i;   for ( i = 0 ; i < nr_heaps ; i++ ) {      int last_end = 0;      unsigned textures_in_heap = 0;      unsigned blocks_in_mempool = 0;      const driTexHeap * heap = texture_heaps[i];      const struct mem_block *p = heap->memory_heap;      /* Check each texture object has a MemBlock, and is linked into       * the correct heap.         *       * Check the texobj base address corresponds to the MemBlock       * range.  Check the texobj size (recalculate?) fits within       * the MemBlock.       *       * Count the number of texobj's using this heap.       */      foreach ( t, &heap->texture_objects ) {	 if ( !check_in_heap( t, heap ) ) {	    fprintf( stderr, "%s memory block for texture object @ %p not "		     "found in heap #%d\n",		     __FUNCTION__, (void *)t, i );	    return GL_FALSE;	 }	 if ( t->totalSize > t->memBlock->size ) {	    fprintf( stderr, "%s: Memory block for texture object @ %p is "		     "only %u bytes, but %u are required\n",		     __FUNCTION__, (void *)t, t->totalSize, t->memBlock->size );	    return GL_FALSE;	 }	 textures_in_heap++;      }      /* Validate the contents of the heap:       *   - Ordering       *   - Overlaps       *   - Bounds       */      while ( p != NULL ) {	 if (p->reserved) {	    fprintf( stderr, "%s: Block (%08x,%x), is reserved?!\n",		     __FUNCTION__, p->ofs, p->size );	    return GL_FALSE;	 }	 if (p->ofs != last_end) {	    fprintf( stderr, "%s: blocks_in_mempool = %d, last_end = %d, p->ofs = %d\n",		     __FUNCTION__, blocks_in_mempool, last_end, p->ofs );	    return GL_FALSE;	 }	 if (!p->reserved && !p->free) {	    blocks_in_mempool++;	 }	 last_end = p->ofs + p->size;	 p = p->next;      }      if (textures_in_heap != blocks_in_mempool) {	 fprintf( stderr, "%s: Different number of textures objects (%u) and "		  "inuse memory blocks (%u)\n", 		  __FUNCTION__, textures_in_heap, blocks_in_mempool );	 return GL_FALSE;      }#if 0      fprintf( stderr, "%s: textures_in_heap = %u\n", 	       __FUNCTION__, textures_in_heap );#endif   }   /* Check swapped texobj's have zero memblocks    */   i = 0;   foreach ( t, swapped ) {      if ( t->memBlock != NULL ) {	 fprintf( stderr, "%s: Swapped texobj %p has non-NULL memblock %p\n",		  __FUNCTION__, (void *)t, (void *)t->memBlock );	 return GL_FALSE;      }      i++;   }#if 0   fprintf( stderr, "%s: swapped texture count = %u\n", __FUNCTION__, i );#endif   return GL_TRUE;}/****************************************************************************//** * Compute which mipmap levels that really need to be sent to the hardware. * This depends on the base image size, GL_TEXTURE_MIN_LOD, * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. */voiddriCalculateTextureFirstLastLevel( driTextureObject * t ){   struct gl_texture_object * const tObj = t->tObj;   const struct gl_texture_image * const baseImage =       tObj->Image[0][tObj->BaseLevel];   /* These must be signed values.  MinLod and MaxLod can be negative numbers,    * and having firstLevel and lastLevel as signed prevents the need for    * extra sign checks.    */   int   firstLevel;   int   lastLevel;   /* Yes, this looks overly complicated, but it's all needed.    */   switch (tObj->Target) {   case GL_TEXTURE_1D:   case GL_TEXTURE_2D:   case GL_TEXTURE_3D:   case GL_TEXTURE_CUBE_MAP:      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.          */         firstLevel = lastLevel = tObj->BaseLevel;      }      else {	 firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);	 firstLevel = MAX2(firstLevel, tObj->BaseLevel);	 firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);	 lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);	 lastLevel = MAX2(lastLevel, t->tObj->BaseLevel);	 lastLevel = MIN2(lastLevel, t->tObj->BaseLevel + baseImage->MaxLog2);	 lastLevel = MIN2(lastLevel, t->tObj->MaxLevel);	 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */      }      break;   case GL_TEXTURE_RECTANGLE_NV:   case GL_TEXTURE_4D_SGIS:      firstLevel = lastLevel = 0;      break;   default:      return;   }   /* save these values */   t->firstLevel = firstLevel;   t->lastLevel = lastLevel;}/** * \name DRI texture formats.  Pointers initialized to either the big- or * little-endian Mesa formats. *//*@{*/const struct gl_texture_format *_dri_texformat_rgba8888 = NULL;const struct gl_texture_format *_dri_texformat_argb8888 = NULL;const struct gl_texture_format *_dri_texformat_rgb565 = NULL;const struct gl_texture_format *_dri_texformat_argb4444 = NULL;const struct gl_texture_format *_dri_texformat_argb1555 = NULL;const struct gl_texture_format *_dri_texformat_al88 = NULL;const struct gl_texture_format *_dri_texformat_a8 = &_mesa_texformat_a8;const struct gl_texture_format *_dri_texformat_ci8 = &_mesa_texformat_ci8;const struct gl_texture_format *_dri_texformat_i8 = &_mesa_texformat_i8;const struct gl_texture_format *_dri_texformat_l8 = &_mesa_texformat_l8;/*@}*//** * Initialize little endian target, host byte order independent texture formats */voiddriInitTextureFormats(void){   const GLuint ui = 1;   const GLubyte littleEndian = *((const GLubyte *) &ui);   if (littleEndian) {      _dri_texformat_rgba8888	= &_mesa_texformat_rgba8888;      _dri_texformat_argb8888	= &_mesa_texformat_argb8888;      _dri_texformat_rgb565	= &_mesa_texformat_rgb565;      _dri_texformat_argb4444	= &_mesa_texformat_argb4444;      _dri_texformat_argb1555	= &_mesa_texformat_argb1555;      _dri_texformat_al88	= &_mesa_texformat_al88;   }   else {      _dri_texformat_rgba8888	= &_mesa_texformat_rgba8888_rev;      _dri_texformat_argb8888	= &_mesa_texformat_argb8888_rev;      _dri_texformat_rgb565	= &_mesa_texformat_rgb565_rev;      _dri_texformat_argb4444	= &_mesa_texformat_argb4444_rev;      _dri_texformat_argb1555	= &_mesa_texformat_argb1555_rev;      _dri_texformat_al88	= &_mesa_texformat_al88_rev;   }}

⌨️ 快捷键说明

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