📄 r300_texstate.c
字号:
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 + -