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

📄 r300_texmem.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static void r300UploadSubImage(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;	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 (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 {			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 = RADEON_TXFORMAT_I8;	/* any 1-byte texel format */		tex.pitch = (R300_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);		_mesa_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 (t->image_override)		return 0;	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->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;		}	}	/* 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) {				r300UploadSubImage(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 + -