📄 tdfx_tex.c
字号:
RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; fxMesa->new_state |= TDFX_NEW_TEXTURE;}static voidtdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; GLint texelBytes, dstRowStride; if (!texObj->DriverData) { _mesa_problem(ctx, "problem in fxDDTexSubImage2D"); return; } ti = TDFX_TEXTURE_DATA(texObj); assert(ti); mml = TDFX_TEXIMAGE_DATA(texImage); assert(mml); assert(texImage->Data); /* must have an existing texture image! */ assert(texImage->_BaseFormat); texelBytes = texImage->TexFormat->TexelBytes; if (texImage->IsCompressed) { dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width); } else { dstRowStride = mml->width * texelBytes; } if (mml->wScale != 1 || mml->hScale != 1) { /* need to rescale subimage to match mipmap level's rescale factors */ if (!adjust2DRatio(ctx, xoffset, yoffset, width, height, format, type, pixels, packing, mml, texImage, texelBytes, dstRowStride) ) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); return; } } else { /* no rescaling needed */ texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, texImage->TexFormat, texImage->Data, xoffset, yoffset, 0, dstRowStride, texImage->ImageOffsets, width, height, 1, format, type, pixels, packing); } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); width = texImage->Width; height = texImage->Height; while (level < texObj->MaxLevel && level < maxLevels - 1) { mipWidth = width / 2; if (!mipWidth) { mipWidth = 1; } mipHeight = height / 2; if (!mipHeight) { mipHeight = 1; } if ((mipWidth == width) && (mipHeight == height)) { break; } ++level; mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, texelBytes, mml->width, mml->height, texImage->Data, mipImage->Data); texImage = mipImage; mml = mip; width = mipWidth; height = mipHeight; } } ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */}static voidtdfxTexImage1D(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage){ tdfxTexImage2D(ctx, target, level, internalFormat, width, 1, border, format, type, pixels, packing, texObj, texImage);}static voidtdfxTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ){ tdfxTexSubImage2D(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage);}/**********************************************************************//**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****//**********************************************************************/static voidtdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; GLuint mesaFormat; if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n", texObj->Name, internalFormat, width, height); } if ((target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || texImage->Border > 0) { _mesa_problem(NULL, "tdfx: unsupported texture in tdfxCompressedTexImg()\n"); return; } assert(texImage->IsCompressed); ti = TDFX_TEXTURE_DATA(texObj); if (!ti) { texObj->DriverData = fxAllocTexObjData(fxMesa); if (!texObj->DriverData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } ti = TDFX_TEXTURE_DATA(texObj); } assert(ti); mml = TDFX_TEXIMAGE_DATA(texImage); if (!mml) { texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel)); if (!texImage->DriverData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } mml = TDFX_TEXIMAGE_DATA(texImage); } tdfxTexGetInfo(ctx, width, height, NULL, NULL, NULL, NULL, &mml->wScale, &mml->hScale); mml->width = width * mml->wScale; mml->height = height * mml->hScale; /* choose the texture format */ assert(ctx->Driver.ChooseTextureFormat); texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, internalFormat, -1/*format*/, -1/*type*/); assert(texImage->TexFormat); /* Determine the appropriate Glide texel format, * given the user's internal texture format hint. */ mesaFormat = texImage->TexFormat->MesaFormat; mml->glideFormat = fxGlideFormat(mesaFormat); ti->info.format = mml->glideFormat; texImage->FetchTexelc = fxFetchFunction(mesaFormat); /* allocate new storage for texture image, if needed */ if (!texImage->Data) { texImage->CompressedSize = _mesa_compressed_texture_size(ctx, mml->width, mml->height, 1, mesaFormat); texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } } /* save the texture data */ if (mml->wScale != 1 || mml->hScale != 1) { /* [dBorca] Hack alert: * now we're screwed. We can't decompress, * unless we do it in HW (via textureBuffer). * We still have some chances: * 1) we got FXT1 textures - we CAN decompress, rescale for * aspectratio, then compress back. * 2) there is a chance that MIN("s", "t") won't be overflowed. * Thus, we don't care about textureclamp and we could lower * MIN("uscale", "vscale") below 32. We still have to have * our data aligned inside a 8:1 rectangle. * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT, * we replicate the data over the padded area. * For now, we take 2) + 3) but texelfetchers will be wrong! */ const GLuint mesaFormat = texImage->TexFormat->MesaFormat; GLuint srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); GLuint destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4, destRowStride, (mml->height+3) / 4, 1, data, srcRowStride, texImage->Data); ti->padded = GL_TRUE; } else { MEMCPY(texImage->Data, data, texImage->CompressedSize); } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { assert(!texImage->IsCompressed); } RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; fxMesa->new_state |= TDFX_NEW_TEXTURE;}static voidtdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLint height, GLenum format, GLsizei imageSize, const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; GLint destRowStride, srcRowStride; GLint i, rows; GLubyte *dest; const GLuint mesaFormat = texImage->TexFormat->MesaFormat; if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name); } ti = TDFX_TEXTURE_DATA(texObj); assert(ti); mml = TDFX_TEXIMAGE_DATA(texImage); assert(mml); srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); dest = _mesa_compressed_image_address(xoffset, yoffset, 0, mesaFormat, mml->width, (GLubyte*) texImage->Data); rows = height / 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */ for (i = 0; i < rows; i++) { MEMCPY(dest, data, srcRowStride); dest += destRowStride; data = (GLvoid *)((intptr_t)data + (intptr_t)srcRowStride); } /* [dBorca] Hack alert: * see fxDDCompressedTexImage2D for caveats */ if (mml->wScale != 1 || mml->hScale != 1) { srcRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width); destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4, destRowStride, mml->height / 4, 1, texImage->Data, destRowStride, texImage->Data); } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { assert(!texImage->IsCompressed); } RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; fxMesa->new_state |= TDFX_NEW_TEXTURE;}#if 0static voidPrintTexture(int w, int h, int c, const GLubyte * data){ int i, j; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (c == 2) printf("%02x %02x ", data[0], data[1]); else if (c == 3) printf("%02x %02x %02x ", data[0], data[1], data[2]); data += c; } printf("\n"); }}#endifGLbooleantdfxTestProxyTexImage(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, GLint depth, GLint border){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; switch (target) { case GL_PROXY_TEXTURE_1D: /*JJJ wrong*/ case GL_PROXY_TEXTURE_2D: { struct gl_texture_object *tObj; tdfxTexInfo *ti; int memNeeded; tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = TDFX_TEXTURE_DATA(tObj); assert(ti); /* assign the parameters to test against */ tObj->Image[0][level]->Width = width; tObj->Image[0][level]->Height = height; tObj->Image[0][level]->Border = border;#if 0 tObj->Image[0][level]->InternalFormat = internalFormat;#endif if (level == 0) { /* don't use mipmap levels > 0 */ tObj->MinFilter = tObj->MagFilter = GL_NEAREST; } else { /* test with all mipmap levels */ tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR; tObj->MagFilter = GL_NEAREST; } RevalidateTexture(ctx, tObj); /* printf("small lodlog2 0x%x\n", ti->info.smallLodLog2); printf("large lodlog2 0x%x\n", ti->info.largeLodLog2); printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2); printf("glide format 0x%x\n", ti->info.format); printf("data %p\n", ti->info.data); printf("lodblend %d\n", (int) ti->LODblend); */ /* determine where texture will reside */ if (ti->LODblend && !shared->umaTexMemory) { /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ memNeeded = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); } else { /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ memNeeded = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); } /* printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]); */ if (memNeeded > shared->totalTexMem[0]) return GL_FALSE; else return GL_TRUE; } case GL_PROXY_TEXTURE_3D: return GL_TRUE; /* software rendering */ default: return GL_TRUE; /* never happens, silence compiler */ }}/** * Allocate a new texture object. * Called via ctx->Driver.NewTextureObject. * Note: this function will be called during context creation to * allocate the default texture objects. * Note: we could use containment here to 'derive' the driver-specific * texture object from the core mesa gl_texture_object. Not done at this time. */static struct gl_texture_object *tdfxNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ){ struct gl_texture_object *obj; obj = _mesa_new_texture_object(ctx, name, target); return obj;}void tdfxInitTextureFuncs( struct dd_function_table *functions ){ functions->BindTexture = tdfxBindTexture; functions->NewTextureObject = tdfxNewTextureObject; functions->DeleteTexture = tdfxDeleteTexture; functions->TexEnv = tdfxTexEnv; functions->TexParameter = tdfxTexParameter; functions->ChooseTextureFormat = tdfxChooseTextureFormat; functions->TexImage1D = tdfxTexImage1D; functions->TexSubImage1D = tdfxTexSubImage1D; functions->TexImage2D = tdfxTexImage2D; functions->TexSubImage2D = tdfxTexSubImage2D; functions->IsTextureResident = tdfxIsTextureResident; functions->CompressedTexImage2D = tdfxCompressedTexImage2D; functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D; functions->UpdateTexturePalette = tdfxUpdateTexturePalette;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -