📄 savagetex.c
字号:
const struct gl_texture_object *tObj ){ savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; GLuint offset, i, textureFormat, tileIndex, size; GLint firstLevel, lastLevel; assert(t); assert(image); switch (image->TexFormat->MesaFormat) { case MESA_FORMAT_ARGB8888: textureFormat = TFT_ARGB8888; t->texelBytes = tileIndex = 4; break; case MESA_FORMAT_ARGB1555: textureFormat = TFT_ARGB1555; t->texelBytes = tileIndex = 2; break; case MESA_FORMAT_ARGB4444: textureFormat = TFT_ARGB4444; t->texelBytes = tileIndex = 2; break; case MESA_FORMAT_RGB565: textureFormat = TFT_RGB565; t->texelBytes = tileIndex = 2; break; case MESA_FORMAT_L8: textureFormat = TFT_L8; t->texelBytes = tileIndex = 1; break; case MESA_FORMAT_I8: textureFormat = TFT_I8; t->texelBytes = tileIndex = 1; break; case MESA_FORMAT_A8: textureFormat = TFT_A8; t->texelBytes = tileIndex = 1; break; case MESA_FORMAT_RGB_DXT1: textureFormat = TFT_S3TC4Bit; tileIndex = TILE_INDEX_DXT1; t->texelBytes = 8; break; case MESA_FORMAT_RGBA_DXT1: textureFormat = TFT_S3TC4Bit; tileIndex = TILE_INDEX_DXT1; t->texelBytes = 8; break; case MESA_FORMAT_RGBA_DXT3: textureFormat = TFT_S3TC4A4Bit; tileIndex = TILE_INDEX_DXTn; t->texelBytes = 16; break; case MESA_FORMAT_RGBA_DXT5: textureFormat = TFT_S3TC4CA4Bit; tileIndex = TILE_INDEX_DXTn; t->texelBytes = 16; break; default: _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__); return; } t->hwFormat = textureFormat; /* Select tiling format depending on the chipset and texture format */ if (imesa->savageScreen->chipset <= S3_SAVAGE4) t->tileInfo = &tileInfo_s3d_s4[tileIndex]; else t->tileInfo = &tileInfo_pro[tileIndex]; /* Compute which mipmap levels we really want to send to the hardware. */ driCalculateTextureFirstLastLevel( &t->base ); firstLevel = t->base.firstLevel; lastLevel = t->base.lastLevel; /* Figure out the size now (and count the levels). Upload won't be * done until later. If the number of tiles changes, it means that * this function is called for the first time on this tex object or * the image or the destination color format changed. So all tiles * are marked as dirty. */ offset = 0; size = 1; for ( i = firstLevel ; i <= lastLevel && tObj->Image[0][i] ; i++ ) { GLuint nTiles; nTiles = savageTexImageTiles (image->Width2, image->Height2, t->tileInfo); if (t->image[i].nTiles != nTiles) { GLuint words = (nTiles + 31) / 32; if (t->image[i].nTiles != 0) { free(t->image[i].dirtyTiles); } t->image[i].dirtyTiles = malloc(words*sizeof(GLuint)); memset(t->image[i].dirtyTiles, ~0, words*sizeof(GLuint)); } t->image[i].nTiles = nTiles; t->image[i].offset = offset; image = tObj->Image[0][i]; if (t->texelBytes >= 8) size = savageCompressedTexImageSize (image->Width2, image->Height2, t->texelBytes); else size = savageTexImageSize (image->Width2, image->Height2, t->texelBytes); offset += size; } t->base.lastLevel = i-1; t->base.totalSize = offset; /* the last three mipmap levels don't add to the offset. They are packed * into 64 pixels. */ if (size == 0) t->base.totalSize += (t->texelBytes >= 8 ? 4 : 64) * t->texelBytes; /* 2k-aligned (really needed?) */ t->base.totalSize = (t->base.totalSize + 2047UL) & ~2047UL;}void savageDestroyTexObj(savageContextPtr imesa, savageTexObjPtr t){ GLuint i; /* Free dirty tiles bit vectors */ for (i = 0; i < SAVAGE_TEX_MAXLEVELS; ++i) { if (t->image[i].nTiles) free (t->image[i].dirtyTiles); } /* See if it was the driver's current object. */ if ( imesa != NULL ) { for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { if ( &t->base == imesa->CurrentTexObj[ i ] ) { assert( t->base.bound & (1 << i) ); imesa->CurrentTexObj[ i ] = NULL; } } }}/* Upload a texture's images to one of the texture heaps. May have to * eject our own and/or other client's texture objects to make room * for the upload. */static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t ){ const GLint numLevels = t->base.lastLevel - t->base.firstLevel + 1; GLuint i; assert(t); LOCK_HARDWARE(imesa); /* Do we need to eject LRU texture objects? */ if (!t->base.memBlock) { GLint heap; GLuint ofs; heap = driAllocateTexture(imesa->textureHeaps, imesa->lastTexHeap, (driTextureObject *)t); if (heap == -1) { UNLOCK_HARDWARE(imesa); return; } ofs = t->base.memBlock->ofs; t->setup.physAddr = imesa->savageScreen->textureOffset[heap] + ofs; t->bufAddr = (GLubyte *)imesa->savageScreen->texVirtual[heap] + ofs; imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */ } /* Let the world know we've used this memory recently. */ driUpdateTextureLRU( &t->base ); UNLOCK_HARDWARE(imesa); if (t->base.dirty_images[0] || t->dirtySubImages) { if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) fprintf(stderr, "Texture upload: |"); /* Heap timestamps are only reliable with Savage DRM 2.3.x or * later. Earlier versions had only 16 bit time stamps which * would wrap too frequently. */ if (imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) { unsigned int heap = t->base.heap->heapId; LOCK_HARDWARE(imesa); savageWaitEvent (imesa, imesa->textureHeaps[heap]->timestamp); } else { savageFlushVertices (imesa); LOCK_HARDWARE(imesa); savageFlushCmdBufLocked (imesa, GL_FALSE); WAIT_IDLE_EMPTY_LOCKED(imesa); } for (i = 0 ; i < numLevels ; i++) { const GLint j = t->base.firstLevel + i; /* the texObj's level */ if (t->base.dirty_images[0] & (1 << j)) { savageMarkAllTiles(t, j); if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) fprintf (stderr, "*"); } else if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) { if (t->dirtySubImages & (1 << j)) fprintf (stderr, "."); else fprintf (stderr, " "); } if ((t->base.dirty_images[0] | t->dirtySubImages) & (1 << j)) savageUploadTexLevel( t, j ); } UNLOCK_HARDWARE(imesa); t->base.dirty_images[0] = 0; t->dirtySubImages = 0; if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) fprintf(stderr, "|\n"); }}static voidsavage4_set_wrap_mode( savageContextPtr imesa, unsigned unit, GLenum s_mode, GLenum t_mode ){ switch( s_mode ) { case GL_REPEAT: imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Wrap; break; case GL_CLAMP: case GL_CLAMP_TO_EDGE: imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Clamp; break; case GL_MIRRORED_REPEAT: imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Mirror; break; } switch( t_mode ) { case GL_REPEAT: imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Wrap; break; case GL_CLAMP: case GL_CLAMP_TO_EDGE: imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Clamp; break; case GL_MIRRORED_REPEAT: imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Mirror; break; }}/** * Sets the hardware bits for the specified GL texture filter modes. * * \todo * Does the Savage4 have the ability to select the magnification filter? */static voidsavage4_set_filter_mode( savageContextPtr imesa, unsigned unit, GLenum minFilter, GLenum magFilter ){ (void) magFilter; switch (minFilter) { case GL_NEAREST: imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Point; imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE; break; case GL_LINEAR: imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Bilin; imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE; break; case GL_NEAREST_MIPMAP_NEAREST: imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Point; imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; break; case GL_LINEAR_MIPMAP_NEAREST: imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Bilin; imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; break; case GL_NEAREST_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR: imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Trilin; imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; break; }}static void savageUpdateTex0State_s4( GLcontext *ctx ){ savageContextPtr imesa = SAVAGE_CONTEXT(ctx); struct gl_texture_object *tObj; struct gl_texture_image *image; savageTexObjPtr t; GLuint format; /* disable */ imesa->regs.s4.texDescr.ni.tex0En = GL_FALSE; imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap; imesa->regs.s4.texCtrl[0].ui = 0x20f040; if (ctx->Texture.Unit[0]._ReallyEnabled == 0) return; tObj = ctx->Texture.Unit[0]._Current; if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) || tObj->Image[0][tObj->BaseLevel]->Border > 0) { /* 3D texturing enabled, or texture border - fallback */ FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); return; } /* Do 2D texture setup */ t = tObj->DriverData; if (!t) { t = savageAllocTexObj( tObj ); if (!t) return; } imesa->CurrentTexObj[0] = &t->base; t->base.bound |= 1; if (t->base.dirty_images[0] || t->dirtySubImages) { savageSetTexImages(imesa, tObj); savageUploadTexImages(imesa, t); } driUpdateTextureLRU( &t->base ); format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; switch (ctx->Texture.Unit[0].EnvMode) { case GL_REPLACE: imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; switch(format) { case GL_LUMINANCE: case GL_RGB: imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal; break; case GL_LUMINANCE_ALPHA: case GL_RGBA: case GL_INTENSITY: imesa->regs.s4.texBlendCtrl[0].ui = TBC_Copy; break; case GL_ALPHA: imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha; break; } __HWEnvCombineSingleUnitScale(imesa, 0, 0, &imesa->regs.s4.texBlendCtrl[0]); break; case GL_DECAL: imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; switch (format) { case GL_RGB: case GL_LUMINANCE: imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal; break; case GL_RGBA: case GL_INTENSITY: case GL_LUMINANCE_ALPHA: imesa->regs.s4.texBlendCtrl[0].ui = TBC_DecalAlpha; break; /* GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY are undefined with GL_DECAL */ case GL_ALPHA: imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha; break; } __HWEnvCombineSingleUnitScale(imesa, 0, 0, &imesa->regs.s4.texBlendCtrl[0]); break; case GL_MODULATE: imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha; __HWEnvCombineSingleUnitScale(imesa, 0, 0, &imesa->regs.s4.texBlendCtrl[0]); break; case GL_BLEND: imesa->regs.s4.texBlendColor.ui = imesa->texEnvColor; switch (format) { case GL_ALPHA: imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha; imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; break; case GL_LUMINANCE: case GL_RGB: imesa->regs.s4.texBlendCtrl[0].ui = TBC_Blend0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -