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

📄 r300_texstate.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
	texelBytes = baseImage->TexFormat->TexelBytes;	/* Compute which mipmap levels we really want to send to the hardware.	 */	driCalculateTextureFirstLastLevel((driTextureObject *) t);	log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;	log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;	log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;	numLevels = t->base.lastLevel - t->base.firstLevel + 1;	assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);	/* Calculate mipmap offsets and dimensions for blitting (uploading)	 * The idea is that we lay out the mipmap levels within a block of	 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.	 */	t->tile_bits = 0;	/* figure out if this texture is suitable for tiling. */#if 0				/* Disabled for now */	if (texelBytes) {		if ((tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&		    /* texrect might be able to use micro tiling too in theory? */		    (baseImage->Height > 1)) {			/* allow 32 (bytes) x 1 mip (which will use two times the space			   the non-tiled version would use) max if base texture is large enough */			if ((numLevels == 1) ||			    (((baseImage->Width * texelBytes /			       baseImage->Height) <= 32)			     && (baseImage->Width * texelBytes > 64))			    ||			    ((baseImage->Width * texelBytes /			      baseImage->Height) <= 16)) {				t->tile_bits |= R300_TXO_MICRO_TILE;			}		}		if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {			/* we can set macro tiling even for small textures, they will be untiled anyway */			t->tile_bits |= R300_TXO_MACRO_TILE;		}	}#endif	curOffset = 0;	if (tObj->Target == GL_TEXTURE_CUBE_MAP) {		ASSERT(log2Width == log2Height);		t->format |= R300_TX_FORMAT_CUBIC_MAP;		for(i = 0; i < numLevels; i++) {			GLuint face;			for(face = 0; face < 6; face++)				compute_tex_image_offset(tObj, face, i, &curOffset);		}	} else {		if (tObj->Target == GL_TEXTURE_3D)                	t->format |= R300_TX_FORMAT_3D;		for (i = 0; i < numLevels; i++)			compute_tex_image_offset(tObj, 0, i, &curOffset);	}	/* Align the total size of texture memory block.	 */	t->base.totalSize =	    (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;	t->size =	    (((tObj->Image[0][t->base.firstLevel]->Width -	       1) << R300_TX_WIDTHMASK_SHIFT)	     | ((tObj->Image[0][t->base.firstLevel]->Height - 1) <<		R300_TX_HEIGHTMASK_SHIFT)	     | ((tObj->Image[0][t->base.firstLevel]->DepthLog2) <<		R300_TX_DEPTHMASK_SHIFT))	    | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);	t->pitch = 0;	/* Only need to round to nearest 32 for textures, but the blitter	 * requires 64-byte aligned pitches, and we may/may not need the	 * blitter.   NPOT only!	 */	if (baseImage->IsCompressed) {		t->pitch |=		    (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);	} else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {		unsigned int align = (64 / texelBytes) - 1;		t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width *			     texelBytes) + 63) & ~(63);		t->size |= R300_TX_SIZE_TXPITCH_EN;		if (!t->image_override)			t->pitch_reg =			    (((tObj->Image[0][t->base.firstLevel]->Width) +			      align) & ~align) - 1;	} else {		t->pitch |=		    ((tObj->Image[0][t->base.firstLevel]->Width *		      texelBytes) + 63) & ~(63);	}	if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {	    if (tObj->Image[0][t->base.firstLevel]->Width > 2048)		t->pitch_reg |= R500_TXWIDTH_BIT11;	    if (tObj->Image[0][t->base.firstLevel]->Height > 2048)		t->pitch_reg |= R500_TXHEIGHT_BIT11;	}}/* ================================================================ * Texture unit state management */static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	struct gl_texture_object *tObj = texUnit->_Current;	r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;	ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);	if (t->base.dirty_images[0]) {		R300_FIREVERTICES(rmesa);		r300SetTexImages(rmesa, tObj);		r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);		if (!t->base.memBlock && !t->image_override)			return GL_FALSE;	}	return GL_TRUE;}static GLboolean r300EnableTexture3D(GLcontext * ctx, int unit){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	struct gl_texture_object *tObj = texUnit->_Current;	r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;	ASSERT(tObj->Target == GL_TEXTURE_3D);	/* r300 does not support mipmaps for 3D textures. */	if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {		return GL_FALSE;	}	if (t->base.dirty_images[0]) {		R300_FIREVERTICES(rmesa);		r300SetTexImages(rmesa, tObj);		r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);		if (!t->base.memBlock)			return GL_FALSE;	}	return GL_TRUE;}static GLboolean r300EnableTextureCube(GLcontext * ctx, int unit){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	struct gl_texture_object *tObj = texUnit->_Current;	r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;	GLuint face;	ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);	if (t->base.dirty_images[0] || t->base.dirty_images[1] ||	    t->base.dirty_images[2] || t->base.dirty_images[3] ||	    t->base.dirty_images[4] || t->base.dirty_images[5]) {		/* flush */		R300_FIREVERTICES(rmesa);		/* layout memory space, once for all faces */		r300SetTexImages(rmesa, tObj);	}	/* upload (per face) */	for (face = 0; face < 6; face++) {		if (t->base.dirty_images[face]) {			r300UploadTexImages(rmesa,					    (r300TexObjPtr) tObj->DriverData,					    face);		}	}	if (!t->base.memBlock) {		/* texmem alloc failed, use s/w fallback */		return GL_FALSE;	}	return GL_TRUE;}static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	struct gl_texture_object *tObj = texUnit->_Current;	r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;	ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);	if (t->base.dirty_images[0]) {		R300_FIREVERTICES(rmesa);		r300SetTexImages(rmesa, tObj);		r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);		if (!t->base.memBlock && !t->image_override &&		    !rmesa->prefer_gart_client_texturing)			return GL_FALSE;	}	return GL_TRUE;}static GLboolean r300UpdateTexture(GLcontext * ctx, int unit){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	struct gl_texture_object *tObj = texUnit->_Current;	r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;	/* Fallback if there's a texture border */	if (tObj->Image[0][tObj->BaseLevel]->Border > 0)		return GL_FALSE;	/* Update state if this is a different texture object to last	 * time.	 */	if (rmesa->state.texture.unit[unit].texobj != t) {		if (rmesa->state.texture.unit[unit].texobj != NULL) {			/* The old texture is no longer bound to this texture unit.			 * Mark it as such.			 */			rmesa->state.texture.unit[unit].texobj->base.bound &=			    ~(1 << unit);		}		rmesa->state.texture.unit[unit].texobj = t;		t->base.bound |= (1 << unit);		driUpdateTextureLRU((driTextureObject *) t);	/* XXX: should be locked! */	}	return !t->border_fallback;}void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,		      unsigned long long offset, GLint depth, GLuint pitch){	r300ContextPtr rmesa = pDRICtx->driverPrivate;	struct gl_texture_object *tObj =	    _mesa_lookup_texture(rmesa->radeon.glCtx, texname);	r300TexObjPtr t;	uint32_t pitch_val;	if (!tObj)		return;	t = (r300TexObjPtr) tObj->DriverData;	t->image_override = GL_TRUE;	if (!offset)		return;	t->offset = offset;	t->pitch_reg &= (1 << 13) -1;	pitch_val = pitch;	switch (depth) {	case 32:		t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);		t->filter |= tx_table[2].filter;		pitch_val /= 4;		break;	case 24:	default:		t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);		t->filter |= tx_table[4].filter;		pitch_val /= 4;		break;	case 16:		t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);		t->filter |= tx_table[5].filter;		pitch_val /= 2;		break;	}	pitch_val--;	t->pitch_reg |= pitch_val;}static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit){	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];	if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {		return (r300EnableTextureRect(ctx, unit) &&			r300UpdateTexture(ctx, unit));	} else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {		return (r300EnableTexture2D(ctx, unit) &&			r300UpdateTexture(ctx, unit));	} else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {		return (r300EnableTexture3D(ctx, unit) &&			r300UpdateTexture(ctx, unit));	} else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {		return (r300EnableTextureCube(ctx, unit) &&			r300UpdateTexture(ctx, unit));	} else if (texUnit->_ReallyEnabled) {		return GL_FALSE;	} else {		return GL_TRUE;	}}void r300UpdateTextureState(GLcontext * ctx){	int i;	for (i = 0; i < 8; i++) {		if (!r300UpdateTextureUnit(ctx, i)) {			_mesa_warning(ctx,				      "failed to update texture state for unit %d.\n",				      i);		}	}}

⌨️ 快捷键说明

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