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

📄 r300_texmem.c

📁 mesa-6.5-minigui源码
💻 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( r300ContextPtr rmesa, r300TexObjPtr 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 ( RADEON_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 ( RADEON_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );      return;   }   if ( !texImage->Data ) {      if ( RADEON_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 ( RADEON_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);      r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );      return;   }   else if (texImage->IsClientData) {      if ( RADEON_DEBUG & DEBUG_TEXTURE )	 fprintf( stderr, "%s: image data is in GART client storage\n",		  __FUNCTION__);      r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,				   x, y, width, height );      return;   }   else if ( RADEON_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 ( RADEON_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 > 4) {      const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));      tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */      tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);      tex.height = imageHeight;      tex.width = imageWidth << log2TexelBytes;      tex.offset += (tmp.x << log2TexelBytes) & ~1023;      tmp.x = tmp.x % (1024 >> log2TexelBytes);      tmp.width = tmp.width << log2TexelBytes;   }   else if (texImage->TexFormat->TexelBytes) {      /* use multi-byte upload scheme */      tex.height = imageHeight;      tex.width = imageWidth;      switch(texImage->TexFormat->TexelBytes) {      case 1:	tex.format = RADEON_TXFORMAT_I8;	break;      case 2:	tex.format = RADEON_TXFORMAT_AI88;	break;      case 4:	tex.format = RADEON_TXFORMAT_ARGB8888;	break;      }      tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);      tex.offset += tmp.x & ~1023;      tmp.x = tmp.x % 1024;#if 1      if (t->tile_bits & R300_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 #endif      {	 tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);      }#if 1      if ((t->tile_bits & R300_TXO_MACRO_TILE) &&	 (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&	 ((!(t->tile_bits & R300_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;      }#endif   }   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;      if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)      {           tex.width *= 8;      } else {           tex.width *= 16;      }   }   LOCK_HARDWARE( &rmesa->radeon );   do {      ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,                                 &tex, sizeof(drm_radeon_texture_t) );      if (ret) {	 if (RADEON_DEBUG & DEBUG_IOCTL)	    fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n");	 usleep(1);      }   } while ( ret == -EAGAIN );   UNLOCK_HARDWARE( &rmesa->radeon );   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 r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face){	const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;	if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {		fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,			(void *)rmesa->radeon.glCtx, (void *)t->base.tObj,			t->base.totalSize, t->base.firstLevel,			t->base.lastLevel);	}	if (!t || t->base.totalSize == 0)		return 0;	if (RADEON_DEBUG & DEBUG_SYNC) {		fprintf(stderr, "%s: Syncing\n", __FUNCTION__);		radeonFinish(rmesa->radeon.glCtx);	}	LOCK_HARDWARE(&rmesa->radeon);	if (t->base.memBlock == NULL) {		int heap;		heap = driAllocateTexture(rmesa->texture_heaps, rmesa->nr_heaps,					  (driTextureObject *) t);		if (heap == -1) {			UNLOCK_HARDWARE(&rmesa->radeon);			return -1;		}		/* Set the base offset of the texture image */		t->bufAddr = rmesa->radeon.radeonScreen->texOffset[heap]		    + t->base.memBlock->ofs;		t->offset = t->bufAddr;		if (!(t->base.tObj->Image[0][0]->IsClientData)) {			/* hope it's safe to add that here... */			t->offset |= 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->radeon);	/* 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 (RADEON_DEBUG & DEBUG_SYNC) {		fprintf(stderr, "%s: Syncing\n", __FUNCTION__);		radeonFinish(rmesa->radeon.glCtx);	}	return 0;}

⌨️ 快捷键说明

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