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

📄 r200_texmem.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
      }   }}/** * Upload the texture image associated with texture \a t at the specified * level at the address relative to \a start. */static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, 			    GLint hwlevel,			    GLint x, GLint y, GLint width, GLint height,			    GLuint face ){   struct gl_texture_image *texImage = NULL;   GLuint offset;   GLint imageWidth, imageHeight;   GLint ret;   drm_radeon_texture_t tex;   drm_radeon_tex_image_t tmp;   const int level = hwlevel + t->base.firstLevel;   if ( R200_DEBUG & DEBUG_TEXTURE ) {      fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", 	       __FUNCTION__, (void *)t, (void *)t->base.tObj,	       level, width, height, face );   }   ASSERT(face < 6);   /* Ensure we have a valid texture to upload */   if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {      _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);      return;   }   texImage = t->base.tObj->Image[face][level];   if ( !texImage ) {      if ( R200_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );      return;   }   if ( !texImage->Data ) {      if ( R200_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );      return;   }   if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {      assert(level == 0);      assert(hwlevel == 0);      if ( R200_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);      r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height );      return;   }   else if (texImage->IsClientData) {      if ( R200_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: image data is in GART client storage\n",		  __FUNCTION__);      r200UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,				   x, y, width, height );      return;   }   else if ( R200_DEBUG & DEBUG_TEXTURE )      fprintf( stderr, "%s: image data is in normal memory\n",	       __FUNCTION__);         imageWidth = texImage->Width;   imageHeight = texImage->Height;   offset = t->bufAddr + t->base.totalSize / 6 * face;   if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {      GLint imageX = 0;      GLint imageY = 0;      GLint blitX = t->image[face][hwlevel].x;      GLint blitY = t->image[face][hwlevel].y;      GLint blitWidth = t->image[face][hwlevel].width;      GLint blitHeight = t->image[face][hwlevel].height;      fprintf( stderr, "   upload image: %d,%d at %d,%d\n",	       imageWidth, imageHeight, imageX, imageY );      fprintf( stderr, "   upload  blit: %d,%d at %d,%d\n",	       blitWidth, blitHeight, blitX, blitY );      fprintf( stderr, "       blit ofs: 0x%07x level: %d/%d\n",	       (GLuint)offset, hwlevel, level );   }   t->image[face][hwlevel].data = texImage->Data;   /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.    * NOTE: we're always use a 1KB-wide blit and I8 texture format.    * We used to use 1, 2 and 4-byte texels and used to use the texture    * width to dictate the blit width - but that won't work for compressed    * textures. (Brian)    * NOTE: can't do that with texture tiling. (sroland)    */   tex.offset = offset;   tex.image = &tmp;   /* copy (x,y,width,height,data) */   memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );      if (texImage->TexFormat->TexelBytes) {      /* use multi-byte upload scheme */      tex.height = imageHeight;      tex.width = imageWidth;      tex.format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK;      if (tex.format == R200_TXFORMAT_ABGR8888) {	 /* drm will refuse abgr8888 textures. */	 tex.format = R200_TXFORMAT_ARGB8888;      }      tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);      tex.offset += tmp.x & ~1023;      tmp.x = tmp.x % 1024;      if (t->tile_bits & R200_TXO_MICRO_TILE) {	 /* need something like "tiled coordinates" ? */	 tmp.y = tmp.x / (tex.pitch * 128) * 2;	 tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;	 tex.pitch |= RADEON_DST_TILE_MICRO >> 22;      }      else {	 tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);      }      if ((t->tile_bits & R200_TXO_MACRO_TILE) &&	 (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&	 ((!(t->tile_bits & R200_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||	    (texImage->Height >= 16))) {	 /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,	    OR if height is smaller than 8 automatically, but if micro tiling is active	    the limit is height 16 instead ? */	 tex.pitch |= RADEON_DST_TILE_MACRO >> 22;      }   }   else {      /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is         needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */      /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed         so the kernel module reads the right amount of data. */      tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */      tex.pitch = (BLIT_WIDTH_BYTES / 64);      tex.height = (imageHeight + 3) / 4;      tex.width = (imageWidth + 3) / 4;      switch (t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) {      case R200_TXFORMAT_DXT1:           tex.width *= 8;           break;      case R200_TXFORMAT_DXT23:      case R200_TXFORMAT_DXT45:           tex.width *= 16;           break;      default:          fprintf(stderr, "unknown compressed tex format in uploadSubImage\n");      }   }   LOCK_HARDWARE( rmesa );   do {      ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE,                                 &tex, sizeof(drm_radeon_texture_t) );      if (ret) {	 if (R200_DEBUG & DEBUG_IOCTL)	    fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n");	 usleep(1);      }   } while ( ret == -EAGAIN );   UNLOCK_HARDWARE( rmesa );   if ( ret ) {      fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );      fprintf( stderr, "   offset=0x%08x\n",	       offset );      fprintf( stderr, "   image width=%d height=%d\n",	       imageWidth, imageHeight );      fprintf( stderr, "    blit width=%d height=%d data=%p\n",	       t->image[face][hwlevel].width, t->image[face][hwlevel].height,	       t->image[face][hwlevel].data );      exit( 1 );   }}/** * Upload the texture images associated with texture \a t.  This might * require the allocation of texture memory. *  * \param rmesa Context pointer * \param t Texture to be uploaded * \param face Cube map face to be uploaded.  Zero for non-cube maps. */int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ){   const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;   if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {      fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,	       (void *)rmesa->glCtx, (void *)t->base.tObj, t->base.totalSize,	       t->base.firstLevel, t->base.lastLevel );   }   if ( !t || t->base.totalSize == 0 || t->image_override )      return 0;   if (R200_DEBUG & DEBUG_SYNC) {      fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );      r200Finish( rmesa->glCtx );   }   LOCK_HARDWARE( rmesa );   if ( t->base.memBlock == NULL ) {      int heap;      heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps,				 (driTextureObject *) t );      if ( heap == -1 ) {	 UNLOCK_HARDWARE( rmesa );	 return -1;      }      /* Set the base offset of the texture image */      t->bufAddr = rmesa->r200Screen->texOffset[heap] 	   + t->base.memBlock->ofs;      t->pp_txoffset = t->bufAddr;             if (!(t->base.tObj->Image[0][0]->IsClientData)) {	 /* hope it's safe to add that here... */	 t->pp_txoffset |= t->tile_bits;      }      /* Mark this texobj as dirty on all units:       */      t->dirty_state = TEX_ALL;   }   /* Let the world know we've used this memory recently.    */   driUpdateTextureLRU( (driTextureObject *) t );   UNLOCK_HARDWARE( rmesa );   /* Upload any images that are new */   if (t->base.dirty_images[face]) {      int i;      for ( i = 0 ; i < numLevels ; i++ ) {         if ( (t->base.dirty_images[face] & (1 << (i+t->base.firstLevel))) != 0 ) {            uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width,			    t->image[face][i].height, face );         }      }      t->base.dirty_images[face] = 0;   }   if (R200_DEBUG & DEBUG_SYNC) {      fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );      r200Finish( rmesa->glCtx );   }   return 0;}

⌨️ 快捷键说明

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