|
|
|
@@ -780,521 +780,375 @@ void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt) |
|
|
|
static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat, |
|
|
|
const struct gl_texture_image *image) |
|
|
|
{ |
|
|
|
if(target!=GL_TEXTURE_2D) |
|
|
|
if(target != GL_TEXTURE_2D) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
#if 0 |
|
|
|
/* mesa will have already checked this */ |
|
|
|
switch(internalFormat) { |
|
|
|
case GL_INTENSITY: |
|
|
|
case GL_INTENSITY4: |
|
|
|
case GL_INTENSITY8: |
|
|
|
case GL_INTENSITY12: |
|
|
|
case GL_INTENSITY16: |
|
|
|
case 1: |
|
|
|
case GL_LUMINANCE: |
|
|
|
case GL_LUMINANCE4: |
|
|
|
case GL_LUMINANCE8: |
|
|
|
case GL_LUMINANCE12: |
|
|
|
case GL_LUMINANCE16: |
|
|
|
case 2: |
|
|
|
case GL_LUMINANCE_ALPHA: |
|
|
|
case GL_LUMINANCE4_ALPHA4: |
|
|
|
case GL_LUMINANCE6_ALPHA2: |
|
|
|
case GL_LUMINANCE8_ALPHA8: |
|
|
|
case GL_LUMINANCE12_ALPHA4: |
|
|
|
case GL_LUMINANCE12_ALPHA12: |
|
|
|
case GL_LUMINANCE16_ALPHA16: |
|
|
|
case GL_ALPHA: |
|
|
|
case GL_ALPHA4: |
|
|
|
case GL_ALPHA8: |
|
|
|
case GL_ALPHA12: |
|
|
|
case GL_ALPHA16: |
|
|
|
case 3: |
|
|
|
case GL_RGB: |
|
|
|
case GL_R3_G3_B2: |
|
|
|
case GL_RGB4: |
|
|
|
case GL_RGB5: |
|
|
|
case GL_RGB8: |
|
|
|
case GL_RGB10: |
|
|
|
case GL_RGB12: |
|
|
|
case GL_RGB16: |
|
|
|
case 4: |
|
|
|
case GL_RGBA: |
|
|
|
case GL_RGBA2: |
|
|
|
case GL_RGBA4: |
|
|
|
case GL_RGB5_A1: |
|
|
|
case GL_RGBA8: |
|
|
|
case GL_RGB10_A2: |
|
|
|
case GL_RGBA12: |
|
|
|
case GL_RGBA16: |
|
|
|
case GL_COLOR_INDEX: |
|
|
|
case GL_COLOR_INDEX1_EXT: |
|
|
|
case GL_COLOR_INDEX2_EXT: |
|
|
|
case GL_COLOR_INDEX4_EXT: |
|
|
|
case GL_COLOR_INDEX8_EXT: |
|
|
|
case GL_COLOR_INDEX12_EXT: |
|
|
|
case GL_COLOR_INDEX16_EXT: |
|
|
|
break; |
|
|
|
default: |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
if(image->Width>256) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
if(image->Height>256) |
|
|
|
return GL_FALSE; |
|
|
|
#endif |
|
|
|
|
|
|
|
if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, |
|
|
|
NULL,NULL)) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
static void fxTexBuildImageMap(const struct gl_texture_image *image, |
|
|
|
GLint internalFormat, unsigned short **dest) |
|
|
|
{ |
|
|
|
int w, h, wscale, hscale; |
|
|
|
int texelSize; /* in bytes */ |
|
|
|
MesaIntTexFormat intFormat; |
|
|
|
|
|
|
|
fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, |
|
|
|
&wscale,&hscale); |
|
|
|
w = image->Width * wscale; |
|
|
|
h = image->Height * hscale; |
|
|
|
|
|
|
|
switch (internalFormat) { |
|
|
|
case GL_INTENSITY: |
|
|
|
case GL_INTENSITY4: |
|
|
|
case GL_INTENSITY8: |
|
|
|
case GL_INTENSITY12: |
|
|
|
case GL_INTENSITY16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_I8; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
case GL_LUMINANCE: |
|
|
|
case GL_LUMINANCE4: |
|
|
|
case GL_LUMINANCE8: |
|
|
|
case GL_LUMINANCE12: |
|
|
|
case GL_LUMINANCE16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_L8; |
|
|
|
break; |
|
|
|
case GL_ALPHA: |
|
|
|
case GL_ALPHA4: |
|
|
|
case GL_ALPHA8: |
|
|
|
case GL_ALPHA12: |
|
|
|
case GL_ALPHA16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_A8; |
|
|
|
break; |
|
|
|
case GL_COLOR_INDEX: |
|
|
|
case GL_COLOR_INDEX1_EXT: |
|
|
|
case GL_COLOR_INDEX2_EXT: |
|
|
|
case GL_COLOR_INDEX4_EXT: |
|
|
|
case GL_COLOR_INDEX8_EXT: |
|
|
|
case GL_COLOR_INDEX12_EXT: |
|
|
|
case GL_COLOR_INDEX16_EXT: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_C8; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
case GL_LUMINANCE_ALPHA: |
|
|
|
case GL_LUMINANCE4_ALPHA4: |
|
|
|
case GL_LUMINANCE6_ALPHA2: |
|
|
|
case GL_LUMINANCE8_ALPHA8: |
|
|
|
case GL_LUMINANCE12_ALPHA4: |
|
|
|
case GL_LUMINANCE12_ALPHA12: |
|
|
|
case GL_LUMINANCE16_ALPHA16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_L8_A8; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
case GL_RGB: |
|
|
|
case GL_R3_G3_B2: |
|
|
|
case GL_RGB4: |
|
|
|
case GL_RGB5: |
|
|
|
case GL_RGB8: |
|
|
|
case GL_RGB10: |
|
|
|
case GL_RGB12: |
|
|
|
case GL_RGB16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_R5_G6_B5; |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
case GL_RGBA: |
|
|
|
case GL_RGBA2: |
|
|
|
case GL_RGBA4: |
|
|
|
case GL_RGBA8: |
|
|
|
case GL_RGB10_A2: |
|
|
|
case GL_RGBA12: |
|
|
|
case GL_RGBA16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_A4_R4_G4_B4; |
|
|
|
break; |
|
|
|
case GL_RGB5_A1: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_A1_R5_G5_B5; |
|
|
|
break; |
|
|
|
default: |
|
|
|
fprintf(stderr,"tdfx driver: texbuildimagemap() bad format\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* alloc teximage memory */ |
|
|
|
if (!(*dest)) { |
|
|
|
*dest = (GLushort *) MALLOC(w * h * texelSize); |
|
|
|
if (!(*dest)) { |
|
|
|
return; /* out of memory */ |
|
|
|
} |
|
|
|
} |
|
|
|
if (image->Border > 0) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
/* convert image to internal format */ |
|
|
|
_mesa_convert_teximage(intFormat, w, h, *dest, |
|
|
|
image->Width, image->Height, |
|
|
|
image->Format, GL_UNSIGNED_BYTE, |
|
|
|
image->Data, &_mesa_native_packing); |
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/ |
|
|
|
/**** NEW TEXTURE IMAGE FUNCTIONS ****/ |
|
|
|
/**********************************************************************/ |
|
|
|
|
|
|
|
void fxDDTexImg(GLcontext *ctx, GLenum target, |
|
|
|
struct gl_texture_object *tObj, GLint level, |
|
|
|
GLint internalFormat, |
|
|
|
const struct gl_texture_image *image) |
|
|
|
GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, |
|
|
|
GLenum format, GLenum type, const GLvoid *pixels, |
|
|
|
const struct gl_pixelstore_attrib *packing, |
|
|
|
struct gl_texture_object *texObj, |
|
|
|
struct gl_texture_image *texImage, |
|
|
|
GLboolean *retainInternalCopy) |
|
|
|
{ |
|
|
|
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; |
|
|
|
tfxTexInfo *ti; |
|
|
|
fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; |
|
|
|
|
|
|
|
if (MESA_VERBOSE&VERBOSE_DRIVER) { |
|
|
|
fprintf(stderr, |
|
|
|
"fxmesa: (%d) fxDDTexImg(...,level=%d,target=%d,format=%x,width=%d,height=%d...)\n", |
|
|
|
tObj->Name, level, target, internalFormat, image->Width, |
|
|
|
image->Height); |
|
|
|
} |
|
|
|
|
|
|
|
if (target!=GL_TEXTURE_2D) |
|
|
|
return; |
|
|
|
|
|
|
|
if (!tObj->DriverData) |
|
|
|
tObj->DriverData=fxAllocTexObjData(fxMesa); |
|
|
|
if (target != GL_TEXTURE_2D) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
ti = fxTMGetTexInfo(tObj); |
|
|
|
if (!texObj->DriverData) |
|
|
|
texObj->DriverData = fxAllocTexObjData(fxMesa); |
|
|
|
|
|
|
|
if (fxIsTexSupported(target,internalFormat,image)) { |
|
|
|
if (fxIsTexSupported(target, texImage->IntFormat, texImage)) { |
|
|
|
GrTextureFormat_t gldformat; |
|
|
|
tfxTexInfo *ti = fxTMGetTexInfo(texObj); |
|
|
|
tfxMipMapLevel *mml = &ti->mipmapLevel[level]; |
|
|
|
GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride; |
|
|
|
MesaIntTexFormat intFormat; |
|
|
|
|
|
|
|
fxTexGetFormat(internalFormat, &gldformat, NULL); |
|
|
|
fxTexGetFormat(texImage->IntFormat, &gldformat, NULL); |
|
|
|
|
|
|
|
fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL, |
|
|
|
NULL,NULL, &wScale, &hScale); |
|
|
|
|
|
|
|
if ((mml->glideFormat == gldformat) && |
|
|
|
(mml->width == image->Width) && |
|
|
|
(mml->height == image->Height)) { |
|
|
|
/* overwrite existing texture image of same size and format */ |
|
|
|
fxTexBuildImageMap(image, internalFormat, &(mml->data)); |
|
|
|
|
|
|
|
if(ti->validated && ti->isInTM) |
|
|
|
fxTMReloadMipMapLevel(fxMesa, tObj, level); |
|
|
|
else |
|
|
|
fxTexInvalidate(ctx,tObj); |
|
|
|
dstWidth = texImage->Width * wScale; |
|
|
|
dstHeight = texImage->Height * hScale; |
|
|
|
|
|
|
|
switch (texImage->IntFormat) { |
|
|
|
case GL_INTENSITY: |
|
|
|
case GL_INTENSITY4: |
|
|
|
case GL_INTENSITY8: |
|
|
|
case GL_INTENSITY12: |
|
|
|
case GL_INTENSITY16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_I8; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
case GL_LUMINANCE: |
|
|
|
case GL_LUMINANCE4: |
|
|
|
case GL_LUMINANCE8: |
|
|
|
case GL_LUMINANCE12: |
|
|
|
case GL_LUMINANCE16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_L8; |
|
|
|
break; |
|
|
|
case GL_ALPHA: |
|
|
|
case GL_ALPHA4: |
|
|
|
case GL_ALPHA8: |
|
|
|
case GL_ALPHA12: |
|
|
|
case GL_ALPHA16: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_A8; |
|
|
|
break; |
|
|
|
case GL_COLOR_INDEX: |
|
|
|
case GL_COLOR_INDEX1_EXT: |
|
|
|
case GL_COLOR_INDEX2_EXT: |
|
|
|
case GL_COLOR_INDEX4_EXT: |
|
|
|
case GL_COLOR_INDEX8_EXT: |
|
|
|
case GL_COLOR_INDEX12_EXT: |
|
|
|
case GL_COLOR_INDEX16_EXT: |
|
|
|
texelSize = 1; |
|
|
|
intFormat = MESA_C8; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
case GL_LUMINANCE_ALPHA: |
|
|
|
case GL_LUMINANCE4_ALPHA4: |
|
|
|
case GL_LUMINANCE6_ALPHA2: |
|
|
|
case GL_LUMINANCE8_ALPHA8: |
|
|
|
case GL_LUMINANCE12_ALPHA4: |
|
|
|
case GL_LUMINANCE12_ALPHA12: |
|
|
|
case GL_LUMINANCE16_ALPHA16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_A8_L8; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
case GL_RGB: |
|
|
|
case GL_R3_G3_B2: |
|
|
|
case GL_RGB4: |
|
|
|
case GL_RGB5: |
|
|
|
case GL_RGB8: |
|
|
|
case GL_RGB10: |
|
|
|
case GL_RGB12: |
|
|
|
case GL_RGB16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_R5_G6_B5; |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
case GL_RGBA: |
|
|
|
case GL_RGBA2: |
|
|
|
case GL_RGBA4: |
|
|
|
case GL_RGBA8: |
|
|
|
case GL_RGB10_A2: |
|
|
|
case GL_RGBA12: |
|
|
|
case GL_RGBA16: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_A4_R4_G4_B4; |
|
|
|
break; |
|
|
|
case GL_RGB5_A1: |
|
|
|
texelSize = 2; |
|
|
|
intFormat = MESA_A1_R5_G5_B5; |
|
|
|
break; |
|
|
|
default: |
|
|
|
gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format"); |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
else { |
|
|
|
/* deallocate existing texture image, if any */ |
|
|
|
if (mml->data) { |
|
|
|
|
|
|
|
_mesa_set_teximage_component_sizes(intFormat, texImage); |
|
|
|
|
|
|
|
/*printf("teximage:\n");*/ |
|
|
|
/* allocate new storage for texture image, if needed */ |
|
|
|
if (!mml->data || mml->glideFormat != gldformat || |
|
|
|
mml->width != dstWidth || mml->height != dstHeight) { |
|
|
|
if (mml->data) |
|
|
|
FREE(mml->data); |
|
|
|
mml->data = NULL; |
|
|
|
} |
|
|
|
mml->data = MALLOC(dstWidth * dstHeight * texelSize); |
|
|
|
if (!mml->data) |
|
|
|
return GL_FALSE; |
|
|
|
mml->glideFormat = gldformat; |
|
|
|
mml->width = image->Width; |
|
|
|
mml->height = image->Height; |
|
|
|
|
|
|
|
/* make new texture image */ |
|
|
|
fxTexBuildImageMap(image, internalFormat, &(mml->data)); |
|
|
|
fxTexInvalidate(ctx, tObj); |
|
|
|
mml->width = dstWidth; |
|
|
|
mml->height = dstHeight; |
|
|
|
fxTexInvalidate(ctx, texObj); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void fxTexBuildSubImageMap(const struct gl_texture_image *image, |
|
|
|
GLint internalFormat, |
|
|
|
GLint xoffset, GLint yoffset, |
|
|
|
GLint width, GLint height, |
|
|
|
unsigned short *destimg) |
|
|
|
{ |
|
|
|
fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, |
|
|
|
NULL,NULL); |
|
|
|
|
|
|
|
switch(internalFormat) { |
|
|
|
case GL_INTENSITY: |
|
|
|
case GL_INTENSITY4: |
|
|
|
case GL_INTENSITY8: |
|
|
|
case GL_INTENSITY12: |
|
|
|
case GL_INTENSITY16: |
|
|
|
case 1: |
|
|
|
case GL_LUMINANCE: |
|
|
|
case GL_LUMINANCE4: |
|
|
|
case GL_LUMINANCE8: |
|
|
|
case GL_LUMINANCE12: |
|
|
|
case GL_LUMINANCE16: |
|
|
|
case GL_ALPHA: |
|
|
|
case GL_ALPHA4: |
|
|
|
case GL_ALPHA8: |
|
|
|
case GL_ALPHA12: |
|
|
|
case GL_ALPHA16: |
|
|
|
case GL_COLOR_INDEX: |
|
|
|
case GL_COLOR_INDEX1_EXT: |
|
|
|
case GL_COLOR_INDEX2_EXT: |
|
|
|
case GL_COLOR_INDEX4_EXT: |
|
|
|
case GL_COLOR_INDEX8_EXT: |
|
|
|
case GL_COLOR_INDEX12_EXT: |
|
|
|
case GL_COLOR_INDEX16_EXT: |
|
|
|
{ |
|
|
|
int y; |
|
|
|
unsigned char *bdst; |
|
|
|
const unsigned char *bsrc; |
|
|
|
|
|
|
|
bsrc=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)); |
|
|
|
bdst=((unsigned char *)destimg)+(yoffset*image->Width+xoffset); |
|
|
|
|
|
|
|
for(y=0;y<height;y++) { |
|
|
|
MEMCPY(bdst,bsrc,width); |
|
|
|
bsrc += image->Width; |
|
|
|
bdst += image->Width; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
case GL_LUMINANCE_ALPHA: |
|
|
|
case GL_LUMINANCE4_ALPHA4: |
|
|
|
case GL_LUMINANCE6_ALPHA2: |
|
|
|
case GL_LUMINANCE8_ALPHA8: |
|
|
|
case GL_LUMINANCE12_ALPHA4: |
|
|
|
case GL_LUMINANCE12_ALPHA12: |
|
|
|
case GL_LUMINANCE16_ALPHA16: |
|
|
|
{ |
|
|
|
int x,y; |
|
|
|
unsigned char *src; |
|
|
|
unsigned short *dst,a,l; |
|
|
|
int simgw,dimgw; |
|
|
|
|
|
|
|
src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*2); |
|
|
|
dst=destimg+(yoffset*image->Width+xoffset); |
|
|
|
|
|
|
|
simgw=(image->Width-width)*2; |
|
|
|
dimgw=image->Width-width; |
|
|
|
for(y=0;y<height;y++) { |
|
|
|
for(x=0;x<width;x++) { |
|
|
|
l=*src++; |
|
|
|
a=*src++; |
|
|
|
*dst++=(a << 8) | l; |
|
|
|
} |
|
|
|
|
|
|
|
src += simgw; |
|
|
|
dst += dimgw; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
case GL_RGB: |
|
|
|
case GL_R3_G3_B2: |
|
|
|
case GL_RGB4: |
|
|
|
case GL_RGB5: |
|
|
|
case GL_RGB8: |
|
|
|
case GL_RGB10: |
|
|
|
case GL_RGB12: |
|
|
|
case GL_RGB16: |
|
|
|
{ |
|
|
|
int x,y; |
|
|
|
unsigned char *src; |
|
|
|
unsigned short *dst,r,g,b; |
|
|
|
int simgw,dimgw; |
|
|
|
|
|
|
|
src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*3); |
|
|
|
dst=destimg+(yoffset*image->Width+xoffset); |
|
|
|
|
|
|
|
simgw=(image->Width-width)*3; |
|
|
|
dimgw=image->Width-width; |
|
|
|
for(y=0;y<height;y++) { |
|
|
|
for(x=0;x<width;x++) { |
|
|
|
r=*src++; |
|
|
|
g=*src++; |
|
|
|
b=*src++; |
|
|
|
*dst++=((0xf8 & r) << (11-3)) | |
|
|
|
((0xfc & g) << (5-3+1)) | |
|
|
|
((0xf8 & b) >> 3); |
|
|
|
} |
|
|
|
|
|
|
|
src += simgw; |
|
|
|
dst += dimgw; |
|
|
|
} |
|
|
|
dstStride = dstWidth * texelSize; |
|
|
|
|
|
|
|
/* store the texture image */ |
|
|
|
if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data, |
|
|
|
dstStride, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing)) { |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
case GL_RGBA: |
|
|
|
case GL_RGBA2: |
|
|
|
case GL_RGBA4: |
|
|
|
case GL_RGBA8: |
|
|
|
case GL_RGB10_A2: |
|
|
|
case GL_RGBA12: |
|
|
|
case GL_RGBA16: |
|
|
|
{ |
|
|
|
int x,y; |
|
|
|
unsigned char *src; |
|
|
|
unsigned short *dst,r,g,b,a; |
|
|
|
int simgw,dimgw; |
|
|
|
|
|
|
|
src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4); |
|
|
|
dst=destimg+(yoffset*image->Width+xoffset); |
|
|
|
|
|
|
|
simgw=(image->Width-width)*4; |
|
|
|
dimgw=image->Width-width; |
|
|
|
for(y=0;y<height;y++) { |
|
|
|
for(x=0;x<width;x++) { |
|
|
|
r=*src++; |
|
|
|
g=*src++; |
|
|
|
b=*src++; |
|
|
|
a=*src++; |
|
|
|
*dst++=((0xf0 & a) << 8) | |
|
|
|
((0xf0 & r) << 4) | |
|
|
|
(0xf0 & g) | |
|
|
|
((0xf0 & b) >> 4); |
|
|
|
} |
|
|
|
|
|
|
|
src += simgw; |
|
|
|
dst += dimgw; |
|
|
|
} |
|
|
|
if (ti->validated && ti->isInTM) { |
|
|
|
/*printf("reloadmipmaplevels\n");*/ |
|
|
|
fxTMReloadMipMapLevel(fxMesa, texObj, level); |
|
|
|
} |
|
|
|
break; |
|
|
|
case GL_RGB5_A1: |
|
|
|
{ |
|
|
|
int x,y; |
|
|
|
unsigned char *src; |
|
|
|
unsigned short *dst,r,g,b,a; |
|
|
|
int simgw,dimgw; |
|
|
|
|
|
|
|
src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4); |
|
|
|
dst=destimg+(yoffset*image->Width+xoffset); |
|
|
|
|
|
|
|
simgw=(image->Width-width)*4; |
|
|
|
dimgw=image->Width-width; |
|
|
|
for(y=0;y<height;y++) { |
|
|
|
for(x=0;x<width;x++) { |
|
|
|
r=*src++; |
|
|
|
g=*src++; |
|
|
|
b=*src++; |
|
|
|
a=*src++; |
|
|
|
*dst++= |
|
|
|
((0x80 & a) << 8) | |
|
|
|
((0xf8 & r) << 7) | |
|
|
|
((0xf8 & g) << 2) | |
|
|
|
((0xf8 & b) >> 3); |
|
|
|
} |
|
|
|
|
|
|
|
src += simgw; |
|
|
|
dst += dimgw; |
|
|
|
} |
|
|
|
else { |
|
|
|
/*printf("invalidate2\n");*/ |
|
|
|
fxTexInvalidate(ctx,texObj); |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
fprintf(stderr,"tdfx driver: fxTexBuildSubImageMap() bad format\n"); |
|
|
|
break; |
|
|
|
|
|
|
|
*retainInternalCopy = GL_FALSE; |
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
else { |
|
|
|
gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void fxDDTexSubImg(GLcontext *ctx, GLenum target, |
|
|
|
struct gl_texture_object *tObj, GLint level, |
|
|
|
GLint xoffset, GLint yoffset, GLint width, GLint height, |
|
|
|
GLint internalFormat, const struct gl_texture_image *image) |
|
|
|
|
|
|
|
GLboolean fxDDTexSubImage2D(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) |
|
|
|
{ |
|
|
|
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; |
|
|
|
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; |
|
|
|
tfxTexInfo *ti; |
|
|
|
GrTextureFormat_t gldformat; |
|
|
|
int wscale,hscale; |
|
|
|
GLint wscale, hscale, dstStride; |
|
|
|
tfxMipMapLevel *mml; |
|
|
|
GLboolean result; |
|
|
|
|
|
|
|
if (MESA_VERBOSE&VERBOSE_DRIVER) { |
|
|
|
fprintf(stderr, |
|
|
|
"fxmesa: (%d) fxDDTexSubImg(level=%d,target=%d,format=%x,width=%d,height=%d)\n", |
|
|
|
tObj->Name, level, target, internalFormat, image->Width, |
|
|
|
image->Height); |
|
|
|
} |
|
|
|
if (target != GL_TEXTURE_2D) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
if(target!=GL_TEXTURE_2D) |
|
|
|
return; |
|
|
|
if (!texObj->DriverData) |
|
|
|
return GL_FALSE; |
|
|
|
|
|
|
|
if (!tObj->DriverData) |
|
|
|
return; |
|
|
|
ti = fxTMGetTexInfo(texObj); |
|
|
|
mml = &ti->mipmapLevel[level]; |
|
|
|
|
|
|
|
ti=fxTMGetTexInfo(tObj); |
|
|
|
mml=&ti->mipmapLevel[level]; |
|
|
|
fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL, |
|
|
|
NULL,NULL, &wscale, &hscale); |
|
|
|
|
|
|
|
fxTexGetFormat(internalFormat,&gldformat,NULL); |
|
|
|
assert(mml->data); /* must have an existing texture image! */ |
|
|
|
|
|
|
|
if (mml->glideFormat != gldformat) { |
|
|
|
if (MESA_VERBOSE&VERBOSE_DRIVER) { |
|
|
|
gl_problem(NULL, "glide texture format mismatch in fxDDTexSubImg"); |
|
|
|
} |
|
|
|
fxDDTexImg(ctx,target,tObj,level,internalFormat,image); |
|
|
|
return; |
|
|
|
switch (mml->glideFormat) { |
|
|
|
case GR_TEXFMT_INTENSITY_8: |
|
|
|
dstStride = mml->width; |
|
|
|
result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ALPHA_8: |
|
|
|
dstStride = mml->width; |
|
|
|
result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_P_8: |
|
|
|
dstStride = mml->width; |
|
|
|
result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ALPHA_INTENSITY_88: |
|
|
|
dstStride = mml->width * 2; |
|
|
|
result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_RGB_565: |
|
|
|
dstStride = mml->width * 2; |
|
|
|
result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ARGB_4444: |
|
|
|
dstStride = mml->width * 2; |
|
|
|
result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ARGB_1555: |
|
|
|
dstStride = mml->width * 2; |
|
|
|
result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset, |
|
|
|
mml->width, mml->height, mml->data, |
|
|
|
dstStride, width, height, |
|
|
|
texImage->Width, texImage->Height, |
|
|
|
format, type, pixels, packing); |
|
|
|
break; |
|
|
|
default: |
|
|
|
gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format"); |
|
|
|
result = GL_FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,&wscale,&hscale); |
|
|
|
|
|
|
|
if((wscale!=1) || (hscale!=1)) { |
|
|
|
if (MESA_VERBOSE&VERBOSE_DRIVER) { |
|
|
|
fprintf(stderr,"fxmesa: (wscale!=1) || (hscale!=1) in fxDDTexSubImg()\n"); |
|
|
|
} |
|
|
|
fxDDTexImg(ctx,target,tObj,level,internalFormat,image); |
|
|
|
|
|
|
|
return; |
|
|
|
if (!result) { |
|
|
|
return GL_FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
assert(mml->data); /* must have an existing texture image! */ |
|
|
|
fxTexBuildSubImageMap(image,internalFormat,xoffset,yoffset, |
|
|
|
width,height,mml->data); |
|
|
|
|
|
|
|
if(ti->validated && ti->isInTM) |
|
|
|
fxTMReloadSubMipMapLevel(fxMesa,tObj,level,yoffset,height); |
|
|
|
if (ti->validated && ti->isInTM) |
|
|
|
fxTMReloadSubMipMapLevel(fxMesa, texObj, level, yoffset, height); |
|
|
|
else |
|
|
|
fxTexInvalidate(ctx,tObj); |
|
|
|
} |
|
|
|
|
|
|
|
fxTexInvalidate(ctx, texObj); |
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
/**********************************************************************/ |
|
|
|
/**** NEW TEXTURE IMAGE FUNCTIONS ****/ |
|
|
|
/**********************************************************************/ |
|
|
|
|
|
|
|
GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, |
|
|
|
GLenum format, GLenum type, const GLvoid *pixels, |
|
|
|
const struct gl_pixelstore_attrib *packing, |
|
|
|
struct gl_texture_object *texObj, |
|
|
|
struct gl_texture_image *texImage, |
|
|
|
GLboolean *retainInternalCopy) |
|
|
|
static void PrintTexture(int w, int h, int c, const GLubyte *data) |
|
|
|
{ |
|
|
|
*retainInternalCopy = GL_TRUE; |
|
|
|
return GL_FALSE; |
|
|
|
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"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GLboolean fxDDTexSubImage2D(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) |
|
|
|
GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level, |
|
|
|
const struct gl_texture_object *texObj, |
|
|
|
GLenum *formatOut, GLenum *typeOut, |
|
|
|
GLboolean *freeImageOut ) |
|
|
|
{ |
|
|
|
tfxTexInfo *ti; |
|
|
|
tfxMipMapLevel *mml; |
|
|
|
|
|
|
|
return GL_FALSE; |
|
|
|
if (target != GL_TEXTURE_2D) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
if (!texObj->DriverData) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
ti = fxTMGetTexInfo(texObj); |
|
|
|
mml = &ti->mipmapLevel[level]; |
|
|
|
if (mml->data) { |
|
|
|
MesaIntTexFormat mesaFormat; |
|
|
|
GLenum glFormat; |
|
|
|
struct gl_texture_image *texImage = texObj->Image[level]; |
|
|
|
GLint srcStride; |
|
|
|
|
|
|
|
GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4); |
|
|
|
if (!data) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
switch (mml->glideFormat) { |
|
|
|
case GR_TEXFMT_INTENSITY_8: |
|
|
|
mesaFormat = MESA_I8; |
|
|
|
glFormat = GL_INTENSITY; |
|
|
|
srcStride = mml->width; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ALPHA_INTENSITY_88: |
|
|
|
mesaFormat = MESA_A8_L8; |
|
|
|
glFormat = GL_LUMINANCE_ALPHA; |
|
|
|
srcStride = mml->width; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ALPHA_8: |
|
|
|
mesaFormat = MESA_A8; |
|
|
|
glFormat = GL_ALPHA; |
|
|
|
srcStride = mml->width; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_RGB_565: |
|
|
|
mesaFormat = MESA_R5_G6_B5; |
|
|
|
glFormat = GL_RGB; |
|
|
|
srcStride = mml->width * 2; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ARGB_4444: |
|
|
|
mesaFormat = MESA_A4_R4_G4_B4; |
|
|
|
glFormat = GL_RGBA; |
|
|
|
srcStride = mml->width * 2; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_ARGB_1555: |
|
|
|
mesaFormat = MESA_A1_R5_G5_B5; |
|
|
|
glFormat = GL_RGBA; |
|
|
|
srcStride = mml->width * 2; |
|
|
|
break; |
|
|
|
case GR_TEXFMT_P_8: |
|
|
|
mesaFormat = MESA_C8; |
|
|
|
glFormat = GL_COLOR_INDEX; |
|
|
|
srcStride = mml->width; |
|
|
|
break; |
|
|
|
default: |
|
|
|
gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage"); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
_mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data, |
|
|
|
srcStride, texImage->Width, texImage->Height, |
|
|
|
glFormat, data); |
|
|
|
*formatOut = glFormat; |
|
|
|
*typeOut = GL_UNSIGNED_BYTE; |
|
|
|
*freeImageOut = GL_TRUE; |
|
|
|
return data; |
|
|
|
} |
|
|
|
else { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|