diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/mga/mgatex.c')
-rw-r--r-- | xc/lib/GL/mesa/src/drv/mga/mgatex.c | 1675 |
1 files changed, 549 insertions, 1126 deletions
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 5c31934d8..16bad1439 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -1,4 +1,3 @@ -/* -*- mode: C; c-basic-offset:8 -*- */ /* * GLX Hardware Device Driver for Matrox Millenium G200 * Copyright (C) 1999 Wittawat Yamwong @@ -33,369 +32,115 @@ #include <GL/gl.h> #include "mm.h" -#include "mgalib.h" -#include "mgadma.h" +#include "mgacontext.h" #include "mgatex.h" -#include "mgalog.h" #include "mgaregs.h" +#include "mgaioctl.h" +#include "enums.h" #include "simple_list.h" +#include "mem.h" +#define TEX_0 1 +#define TEX_1 2 /* * mgaDestroyTexObj * Free all memory associated with a texture and NULL any pointers * to it. */ -static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { - - if ( !t ) return; +void +mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + if ( !t ) return; - /* free the texture memory */ - if (t->MemBlock) { - mmFreeMem( t->MemBlock ); - t->MemBlock = 0; - - if (t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } + /* free the texture memory */ + if (t->MemBlock) { + mmFreeMem( t->MemBlock ); + t->MemBlock = 0; + + if (t->age > mmesa->dirtyAge) + mmesa->dirtyAge = t->age; + } - /* free mesa's link */ - if (t->tObj) - t->tObj->DriverData = NULL; + /* free mesa's link */ + if (t->tObj) + t->tObj->DriverData = NULL; - /* see if it was the driver's current object */ - if (t->bound) - mmesa->CurrentTexObj[t->bound - 1] = 0; + /* see if it was the driver's current object */ + if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; + if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; - remove_from_list(t); - free( t ); -} - -static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) -{ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } - - t->dirty_images = ~0; - move_to_tail(&(mmesa->SwappedOut), t); + remove_from_list(t); + FREE( t ); } -static void mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) -{ - mgaTextureObjectPtr t; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - - fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); - - foreach( t, &(mmesa->TexObjList[heap]) ) { - if (!t->tObj) - fprintf(stderr, "Placeholder %d at %x sz %x\n", - t->MemBlock->ofs / sz, - t->MemBlock->ofs, - t->MemBlock->size); - else - fprintf(stderr, "Texture (bound %d) at %x sz %x\n", - t->bound, - t->MemBlock->ofs, - t->MemBlock->size); - - } - - fprintf(stderr, "\n\n"); -} - -static void mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +/* + * mgaSetTexWrappings + */ +static void mgaSetTexWrapping( mgaTextureObjectPtr t, + GLenum sWrap, + GLenum tWrap ) { - int i, j; - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + GLuint val = 0; - fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); - - for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_NR_TEX_REGIONS ; i++) { - fprintf(stderr, "list[%d] age %d next %d prev %d\n", - j, list[j].age, list[j].next, list[j].prev); - j = list[j].next; - if (j == MGA_NR_TEX_REGIONS) break; - } - - if (j != MGA_NR_TEX_REGIONS) { - fprintf(stderr, "Loop detected in global LRU\n\n\n"); - for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) { - fprintf(stderr, "list[%d] age %d next %d prev %d\n", - i, list[i].age, list[i].next, list[i].prev); - } - } + if (sWrap != GL_REPEAT) + val |= TMC_clampu_enable; - fprintf(stderr, "\n\n"); -} - - -static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) -{ - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; - int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; - int i; - - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - - if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); - - /* (Re)initialize the global circular LRU list. The last element - * in the array (MGA_NR_TEX_REGIONS) is the sentinal. Keeping it - * at the end of the array allows it to be addressed rationally - * when looking up objects at a particular location in texture - * memory. - */ - for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = mmesa->sarea->texAge[heap]; - } - - i--; - list[0].prev = MGA_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = MGA_NR_TEX_REGIONS; - list[MGA_NR_TEX_REGIONS].prev = i; - list[MGA_NR_TEX_REGIONS].next = 0; + if (tWrap != GL_REPEAT) + val |= TMC_clampv_enable; + t->Setup[MGA_TEXREG_CTL] &= ~(TMC_clampu_enable|TMC_clampv_enable); + t->Setup[MGA_TEXREG_CTL] |= val; } -static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int i; - int heap = t->heap; - int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; - int start = t->MemBlock->ofs >> logsz; - int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; - - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - - if (!t->MemBlock) { - fprintf(stderr, "no memblock\n\n"); - return; - } - - /* Update our local LRU - */ - move_to_head( &(mmesa->TexObjList[heap]), t ); - - - if (0) - fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); - - - /* Update the global LRU - */ - for (i = start ; i <= end ; i++) { - - list[i].in_use = 1; - list[i].age = mmesa->texAge[heap]; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = MGA_NR_TEX_REGIONS; - list[i].next = list[MGA_NR_TEX_REGIONS].next; - list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; - list[MGA_NR_TEX_REGIONS].next = i; - } - - if (0) { - mgaPrintGlobalLRU(mmesa, t->heap); - mgaPrintLocalLRU(mmesa, t->heap); - } -} - -/* Called for every shared texture region which has increased in age - * since we last held the lock. - * - * Figures out which of our textures have been ejected by other clients, - * and pushes a placeholder texture onto the LRU list to represent - * the other client's textures. +/* + * mgaSetTexFilter */ -static void mgaTexturesGone( mgaContextPtr mmesa, - GLuint heap, - GLuint offset, - GLuint size, - GLuint in_use ) +static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) { - mgaTextureObjectPtr t, tmp; - - - - foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) { - - if (t->MemBlock->ofs >= offset + size || - t->MemBlock->ofs + t->MemBlock->size <= offset) - continue; - - - - - /* It overlaps - kick it off. Need to hold onto the currently bound - * objects, however. - */ - if (t->bound) - mgaSwapOutTexObj( mmesa, t ); - else - mgaDestroyTexObj( mmesa, t ); + GLuint val = 0; + + switch (minf) { + case GL_NEAREST: val = TF_minfilter_nrst; break; + case GL_LINEAR: val = TF_minfilter_bilin; break; + case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break; + case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break; + case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break; + case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break; + default: val = TF_minfilter_nrst; break; } - - if (in_use) { - t = (mgaTextureObjectPtr) calloc(1,sizeof(*t)); - if (!t) return; - - t->heap = heap; - t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset); - if (!t->MemBlock) { - fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset); - mmDumpMemInfo( mmesa->texHeap[heap]); - return; - } - insert_at_head( &(mmesa->TexObjList[heap]), t ); + switch (magf) { + case GL_NEAREST: val |= TF_magfilter_nrst; break; + case GL_LINEAR: val |= TF_magfilter_bilin; break; + default: val |= TF_magfilter_nrst; break; } -} - - -void mgaAgeTextures( mgaContextPtr mmesa, int heap ) -{ - drm_mga_sarea_t *sarea = mmesa->sarea; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... Fix with a cursor pointer. - */ - for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ; - idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; - idx = sarea->texList[heap][idx].prev, nr++) - { - if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { - mgaTexturesGone(mmesa, heap, idx * sz, sz, 1); - } - } - - if (nr == MGA_NR_TEX_REGIONS) { - mgaTexturesGone(mmesa, heap, 0, - mmesa->mgaScreen->textureSize[heap], 0); - mgaResetGlobalLRU( mmesa, heap ); - } - - - if (0) { - mgaPrintGlobalLRU( mmesa, heap ); - mgaPrintLocalLRU( mmesa, heap ); - } - - mmesa->texAge[heap] = sarea->texAge[heap]; - mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; -} - - -/* - * mgaSetTexWrappings - */ -static void mgaSetTexWrapping( mgaTextureObjectPtr t, - GLenum sWrap, GLenum tWrap ) { - if (sWrap == GL_REPEAT) { - t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampu_enable; - } else { - t->Setup[MGA_TEXREG_CTL] |= TMC_clampu_enable; - } - if (tWrap == GL_REPEAT) { - t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampv_enable; - } else { - t->Setup[MGA_TEXREG_CTL] |= TMC_clampv_enable; - } -} - -/* - * mgaSetTexFilter - */ -static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) { - switch (minf) { - case GL_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_nrst); - break; - case GL_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_bilin); - break; - case GL_NEAREST_MIPMAP_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm1s); - break; - case GL_LINEAR_MIPMAP_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm4s); - break; - case GL_NEAREST_MIPMAP_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm2s); - break; - case GL_LINEAR_MIPMAP_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_minfilter_MASK, TF_minfilter_mm8s); - break; - default: - mgaError("mgaSetTexFilter(): not supported min. filter %d\n", - (int)minf); - break; - } - - switch (magf) { - case GL_NEAREST: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_magfilter_MASK,TF_magfilter_nrst); - break; - case GL_LINEAR: - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER], - TF_magfilter_MASK,TF_magfilter_bilin); - break; - default: - mgaError("mgaSetTexFilter(): not supported mag. filter %d\n", - (int)magf); - break; - } - /* See OpenGL 1.2 specification */ - if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || - minf == GL_NEAREST_MIPMAP_LINEAR)) { - /* c = 0.5 */ - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK, - 0x20 << TF_fthres_SHIFT); - } else { - /* c = 0 */ - MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK, - 0x10 << TF_fthres_SHIFT); - } + /* See OpenGL 1.2 specification */ + if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || + minf == GL_NEAREST_MIPMAP_LINEAR)) { + val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */ + } else { + val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */ + } + + t->Setup[MGA_TEXREG_FILTER] &= (TF_minfilter_MASK | + TF_magfilter_MASK | + TF_fthres_MASK); + t->Setup[MGA_TEXREG_FILTER] |= val; } /* * mgaSetTexBorderColor */ -static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { - t->Setup[MGA_TEXREG_BORDERCOL] = - MGAPACKCOLOR8888(color[0],color[1],color[2],color[3]); - +static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) +{ + t->Setup[MGA_TEXREG_BORDERCOL] = MGAPACKCOLOR8888(color[0],color[1], + color[2],color[3]); } @@ -404,152 +149,6 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { -/* - * mgaUploadSubImageLocked - * - * Perform an iload based update of a resident buffer. This is used for - * both initial loading of the entire image, and texSubImage updates. - * - * Performed with the hardware lock held. - */ -static void mgaUploadSubImageLocked( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ) { - int x2; - int dwords; - int offset; - struct gl_texture_image *image; - int texelBytes, texelsPerDword, texelMaccess, length; - - if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) { - mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level ); - return; - } - - image = t->tObj->Image[level]; - if ( !image ) { - mgaError( "mgaUploadSubImage: NULL image\n" ); - return; - } - - /* find the proper destination offset for this level */ - offset = (t->MemBlock->ofs + - t->offsets[level]); - - texelBytes = t->texelBytes; - switch( texelBytes ) { - case 1: - texelsPerDword = 4; - texelMaccess = 0; - break; - case 2: - texelsPerDword = 2; - texelMaccess = 1; - break; - case 4: - texelsPerDword = 1; - texelMaccess = 2; - break; - default: - return; - } - - - /* We can't do a subimage update if pitch is < 32 texels due - * to hardware XY addressing limits, so we will need to - * linearly upload all modified rows. - */ - if ( image->Width < 32 ) { - x = 0; - width = image->Width * height; - height = 1; - - /* Assume that 1x1 textures aren't going to cause a - * bus error if we read up to four texels from that - * location: - */ - if ( width < texelsPerDword ) { - width = texelsPerDword; - } - } else { - /* pad the size out to dwords. The image is a pointer - to the entire image, so we can safely reference - outside the x,y,width,height bounds if we need to */ - x2 = x + width; - x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1); - x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); - width = x2 - x; - } - - /* we may not be able to upload the entire texture in one - batch due to register limits or dma buffer limits. - Recursively split it up. */ - while ( 1 ) { - dwords = height * width / texelsPerDword; - if ( dwords * 4 <= MGA_DMA_BUF_SZ ) { - break; - } - mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" ); - - mgaUploadSubImageLocked( mmesa, t, level, x, y, - width, height >> 1 ); - y += ( height >> 1 ); - height -= ( height >> 1 ); - } - - mgaMsg(10, "mgaUploadSubImage: %i,%i of %i,%i at %i,%i\n", - width, height, image->Width, image->Height, x, y ); - - /* bump the performance counter */ - mgaglx.c_textureSwaps += ( dwords << 2 ); - - length = dwords * 4; - - /* Fill in the secondary buffer with properly converted texels - * from the mesa buffer. */ - if(t->heap == MGA_CARD_HEAP) { - mgaGetILoadBufferLocked( mmesa ); - mgaConvertTexture( (mgaUI32 *)mmesa->iload_buffer->address, - texelBytes, image, x, y, width, height ); - if(length < 64) length = 64; - mgaMsg(10, "TexelBytes : %d, offset: %d, length : %d\n", - texelBytes, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); - - mgaFireILoadLocked( mmesa, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); - } else { - /* This works, is slower for uploads to card space and needs - * additional synchronization with the dma stream. - */ - mgaConvertTexture( (mgaUI32 *) - (mmesa->mgaScreen->texVirtual[t->heap] + - offset + - y * width * 4/texelsPerDword), - texelBytes, image, x, y, width, height ); - } -} - - -static void mgaUploadTexLevel( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int l ) -{ - mgaUploadSubImageLocked( mmesa, - t, - l, - 0, 0, - t->tObj->Image[l]->Width, - t->tObj->Image[l]->Height); -} - /* @@ -558,490 +157,334 @@ static void mgaUploadTexLevel( mgaContextPtr mmesa, * This will happen before drawing with a new texture, or drawing with a * texture after it was swapped out or teximaged again. */ -static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) +static void mgaCreateTexObj(mgaContextPtr mmesa, + struct gl_texture_object *tObj) { - mgaTextureObjectPtr t; - int i, ofs, size; - struct gl_texture_image *image; - int LastLevel; - int s, s2; - int textureFormat; - - mgaMsg( 10,"mgaCreateTexObj( %p )\n", tObj ); - - t = malloc( sizeof( *t ) ); - if ( !t ) { - mgaError( "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); - return; - } - memset( t, 0, sizeof( *t ) ); - - image = tObj->Image[ 0 ]; - if ( !image ) { - return; - } - - if ( 0 ) { - /* G400 texture format options */ - - } else { - /* G200 texture format options */ - - switch( image->Format ) { - case GL_RGB: - case GL_LUMINANCE: - if ( image->IntFormat != GL_RGB5 && - ( image->IntFormat == GL_RGB8 || - mgaglx.default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw16; - } - break; - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_RGBA: - if ( image->IntFormat != GL_RGBA4 && - ( image->IntFormat == GL_RGBA8 || - mgaglx.default32BitTextures ) ) { - t->texelBytes = 4; - textureFormat = TMC_tformat_tw32; - } else { - t->texelBytes = 2; - textureFormat = TMC_tformat_tw12; - } - break; - case GL_COLOR_INDEX: - textureFormat = TMC_tformat_tw8; - t->texelBytes = 1; - break; - default: - mgaError( "mgaCreateTexObj: bad image->Format\n" ); - free( t ); - return; - } - } - - /* we are going to upload all levels that are present, even if - later levels wouldn't be used by the current filtering mode. This - allows the filtering mode to change without forcing another upload - of the images */ - LastLevel = MGA_TEX_MAXLEVELS-1; - - ofs = 0; - for ( i = 0 ; i <= LastLevel ; i++ ) { - int levelWidth, levelHeight; - - t->offsets[i] = ofs; - image = tObj->Image[ i ]; - if ( !image ) { - LastLevel = i - 1; - mgaMsg( 10, " missing images after LastLevel: %i\n", - LastLevel ); - break; - } - /* the G400 doesn't work with textures less than 8 - units in size */ - levelWidth = image->Width; - levelHeight = image->Height; - if ( levelWidth < 8 ) { - levelWidth = 8; - } - if ( levelHeight < 8 ) { - levelHeight = 8; - } - size = levelWidth * levelHeight * t->texelBytes; - size = ( size + 31 ) & ~31; /* 32 byte aligned */ - ofs += size; - t->dirty_images |= (1<<i); - } - t->totalSize = ofs; - t->lastLevel = LastLevel; + const struct gl_texture_image *image = tObj->Image[ 0 ]; + mgaTextureObjectPtr t; + int i, ofs; + int LastLevel; + int s, s2; + int textureFormat; - /* fill in our mga texture object */ - t->tObj = tObj; - t->ctx = mmesa; - t->age = 0; - t->bound = 0; + if (!image) return; - - insert_at_tail(&(mmesa->SwappedOut), t); - - t->MemBlock = 0; - /* base image */ - image = tObj->Image[ 0 ]; + tObj->DriverData = t = CALLOC( sizeof( *t ) ); + if (!t) { + fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); + return; + } - /* setup hardware register values */ - t->Setup[MGA_TEXREG_CTL] = (TMC_takey_1 | - TMC_tamask_0 | - textureFormat ); + switch( image->Format ) { + case GL_RGB: + case GL_LUMINANCE: + if ( image->IntFormat != GL_RGB5 && ( image->IntFormat == GL_RGB8 || + mmesa->default32BitTextures ) ) { + t->texelBytes = 4; + textureFormat = TMC_tformat_tw32; + } else { + t->texelBytes = 2; + textureFormat = TMC_tformat_tw16; + } + break; + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_RGBA: + if ( image->IntFormat != GL_RGBA4 && ( image->IntFormat == GL_RGBA8 || + mmesa->default32BitTextures ) ) { + t->texelBytes = 4; + textureFormat = TMC_tformat_tw32; + } else { + t->texelBytes = 2; + textureFormat = TMC_tformat_tw12; + } + break; + case GL_COLOR_INDEX: + textureFormat = TMC_tformat_tw8; + t->texelBytes = 1; + break; + default: + fprintf(stderr, "mgaCreateTexObj: bad image->Format %x/%s\n", + image->Format, + gl_lookup_enum_by_nr(image->Format)); + FREE( t ); + tObj->DriverData = 0; + return; + } + + /* We are going to upload all levels that are present, even if + * later levels wouldn't be used by the current filtering mode. This + * allows the filtering mode to change without forcing another upload + * of the images. + */ + LastLevel = MGA_TEX_MAXLEVELS-1; - if (image->WidthLog2 >= 3) { - t->Setup[MGA_TEXREG_CTL] |= ((image->WidthLog2 - 3) << - TMC_tpitch_SHIFT); - } else { - t->Setup[MGA_TEXREG_CTL] |= (TMC_tpitchlin_enable | - (image->Width << - TMC_tpitchext_SHIFT)); - } + ofs = 0; + for ( i = 0 ; i <= LastLevel ; i++ ) { + if ( !tObj->Image[i] ) { + LastLevel = i - 1; + break; + } + t->offsets[i] = ofs; + t->dirty_images |= (1<<i); - t->Setup[MGA_TEXREG_CTL2] = TMC_ckstransdis_enable; + ofs += ((MAX2( tObj->Image[i]->Width, 8 ) * + MAX2( tObj->Image[i]->Height, 8 ) * + t->texelBytes) + 31) & ~31; + } - if ( mmesa->glCtx->Light.Model.ColorControl == - GL_SEPARATE_SPECULAR_COLOR ) - { - t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - } - - t->Setup[MGA_TEXREG_FILTER] = (TF_minfilter_nrst | - TF_magfilter_nrst | - TF_filteralpha_enable | - (0x10 << TF_fthres_SHIFT) | - (LastLevel << TF_mapnb_SHIFT)); - - /* warp texture registers */ - if (MGA_IS_G200(mmesa)) { - ofs = 28; - } else { - ofs = 11; - } - - s = image->Width; - s2 = image->WidthLog2; - t->Setup[MGA_TEXREG_WIDTH] = - MGA_FIELD(TW_twmask, s - 1) | - MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ); + t->totalSize = ofs; + t->lastLevel = LastLevel; + t->tObj = tObj; + t->ctx = mmesa; + t->age = 0; + t->bound = 0; + t->MemBlock = 0; + insert_at_tail(&(mmesa->SwappedOut), t); - s = image->Height; - s2 = image->HeightLog2; - t->Setup[MGA_TEXREG_HEIGHT] = - MGA_FIELD(TH_thmask, s - 1) | - MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ); - - - /* set all the register values for filtering, border, etc */ - mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); - mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); - mgaSetTexBorderColor( t, tObj->BorderColor ); - - tObj->DriverData = t; -} - -static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - /* NOT DONE */ -} - -static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - return 0; -} + /* setup hardware register values */ + t->Setup[MGA_TEXREG_CTL] = (TMC_takey_1 | + TMC_tamask_0 | + textureFormat ); + if (image->WidthLog2 >= 3) + t->Setup[MGA_TEXREG_CTL] |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT); + else + t->Setup[MGA_TEXREG_CTL] |= (TMC_tpitchlin_enable | + (image->Width << TMC_tpitchext_SHIFT)); -int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int heap; - int i; - int ofs; - mgaglx.c_textureSwaps++; - - heap = t->heap = mgaChooseTexHeap( mmesa, t ); - - /* Do we need to eject LRU texture objects? - */ - if (!t->MemBlock) { - while (1) - { - mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; - - t->MemBlock = mmAllocMem( mmesa->texHeap[heap], - t->totalSize, - 6, 0 ); - if (t->MemBlock) - break; - - if (mmesa->TexObjList[heap].prev->bound) { - fprintf(stderr, - "Hit bound texture in upload\n"); - return -1; - } - - if (mmesa->TexObjList[heap].prev == - &(mmesa->TexObjList[heap])) - { - fprintf(stderr, "Failed to upload texture, " - "sz %d\n", t->totalSize); - mmDumpMemInfo( mmesa->texHeap[heap] ); - return -1; - } - - mgaDestroyTexObj( mmesa, tmp ); - } - - ofs = t->MemBlock->ofs - + mmesa->mgaScreen->textureOffset[heap] - ; - t->Setup[MGA_TEXREG_ORG] = ofs; - t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1]; - t->Setup[MGA_TEXREG_ORG2] = ofs + t->offsets[2]; - t->Setup[MGA_TEXREG_ORG3] = ofs + t->offsets[3]; - t->Setup[MGA_TEXREG_ORG4] = ofs + t->offsets[4]; + t->Setup[MGA_TEXREG_CTL2] = TMC_ckstransdis_enable; - mmesa->dirty |= MGA_UPLOAD_CTX; - } - - /* Let the world know we've used this memory recently. - */ - mgaUpdateTexLRU( mmesa, t ); + if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "dispatch age: %d age freed memory: %d\n", - GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); - - if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) - mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); - - if (t->dirty_images) { - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "*"); + t->Setup[MGA_TEXREG_FILTER] = (TF_minfilter_nrst | + TF_magfilter_nrst | + TF_filteralpha_enable | + (0x10 << TF_fthres_SHIFT) | + (LastLevel << TF_mapnb_SHIFT)); + + /* warp texture registers */ + ofs = MGA_IS_G200(mmesa) ? 28 : 11; + s = image->Width; + s2 = image->WidthLog2; + t->Setup[MGA_TEXREG_WIDTH] = (MGA_FIELD(TW_twmask, s - 1) | + MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | + MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 )); - for (i = 0 ; i <= t->lastLevel ; i++) - if (t->dirty_images & (1<<i)) - mgaUploadTexLevel( mmesa, t, i ); - } + + s = image->Height; + s2 = image->HeightLog2; + t->Setup[MGA_TEXREG_HEIGHT] = (MGA_FIELD(TH_thmask, s - 1) | + MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | + MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 )); - t->dirty_images = 0; - return 0; + /* set all the register values for filtering, border, etc */ + mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + mgaSetTexBorderColor( t, tObj->BorderColor ); } -/* -============================================================================ - -PUBLIC MGA FUNCTIONS - -============================================================================ -*/ static void mgaUpdateTextureEnvG200( GLcontext *ctx ) { - struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; - mgaTextureObjectPtr t; - - if (!tObj || !tObj->DriverData) - return; - - t = (mgaTextureObjectPtr)tObj->DriverData; - - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_REPLACE: - t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_MODULATE: - t->Setup[MGA_TEXREG_CTL] |= TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_DECAL: - t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable; - break; - case GL_BLEND: - t->ctx->Fallback |= MGA_FALLBACK_TEXTURE; - break; - default: - break; - } + struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; + mgaTextureObjectPtr t; + + if (!tObj || !tObj->DriverData) + return; + + t = (mgaTextureObjectPtr)tObj->DriverData; + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_REPLACE: + t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; + break; + case GL_MODULATE: + t->Setup[MGA_TEXREG_CTL] |= TMC_tmodulate_enable; + break; + case GL_DECAL: + t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable; + break; + case GL_BLEND: + t->ctx->Fallback |= MGA_FALLBACK_TEXTURE; + break; + default: + break; + } } -static void mgaUpdateTextureStage( GLcontext *ctx, int unit ) +static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; - GLuint source = mmesa->tmu_source[unit]; - struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; - - *reg = 0; - if (unit == 1) - *reg = mmesa->Setup[MGA_CTXREG_TDUAL0]; - - if ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) - return; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; + GLuint source = mmesa->tmu_source[unit]; + struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; + + if ( tObj != ctx->Texture.Unit[source].CurrentD[2] || + !tObj || + !tObj->Complete || + ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) + return; - if ( ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D ) - return; - - if (!tObj || !tObj->Complete) - return; - - switch (ctx->Texture.Unit[source].EnvMode) { - case GL_REPLACE: - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); - break; - - case GL_MODULATE: - if (unit == 0) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - else - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_sel_mul | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_mul); - break; - case GL_DECAL: - *reg = (TD0_color_arg2_fcol | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_fcol | - TD0_alpha_sel_arg2 ); - break; - - case GL_ADD: - if (unit == 0) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_add); - else - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_add); - break; - - case GL_BLEND: - if (0) - fprintf(stderr, "GL_BLEND unit %d flags %x\n", unit, - mmesa->blend_flags); - - if (mmesa->blend_flags) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; - - /* Do singletexture GL_BLEND with 'all ones' env-color - * by using both texture units. Multitexture gl_blend - * is a fallback. - */ - if (unit == 0) { - /* Part 1: R1 = Rf ( 1 - Rt ) - * A1 = Af At - */ - *reg = ( TD0_color_arg2_diffuse | - TD0_color_arg1_inv_enable | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); - } else { - /* Part 2: R2 = R1 + Rt - * A2 = A1 - */ - *reg = ( TD0_color_arg2_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2); - } - - break; - default: - break; - } -} + switch (ctx->Texture.Unit[source].EnvMode) { + case GL_REPLACE: + *reg = (TD0_color_sel_arg1 | + TD0_alpha_sel_arg1 ); + break; + + case GL_MODULATE: + if (unit == 0) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul); + else + *reg = ( TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul); + break; + case GL_DECAL: + if (unit == 0) + *reg = (TD0_color_arg2_diffuse | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + else + *reg = (TD0_color_arg2_prevstage | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + + break; + + case GL_ADD: + if (unit == 0) + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_add); + else + *reg = ( TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_add); + break; + + case GL_BLEND: + if (mmesa->blend_flags) + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + + /* Do singletexture GL_BLEND with 'all ones' env-color + * by using both texture units. Multitexture gl_blend + * is a fallback. + */ + if (unit == 0) { + /* Part 1: R1 = Rf ( 1 - Rt ) + * A1 = Af At + */ + *reg = ( TD0_color_arg2_diffuse | + TD0_color_arg1_inv_enable | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg1); + } else { + /* Part 2: R2 = R1 + Rt + * A2 = A1 + */ + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } + break; + default: + break; + } +} -static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { - mgaTextureObjectPtr t; - struct gl_texture_object *tObj; - GLuint enabled; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint source = mmesa->tmu_source[unit]; - - mgaMsg(15,"mgaUpdateTextureState %d\n", unit); - - /* disable texturing until it is known to be good */ - mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; - mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_trap; - - enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY; - if (enabled != TEXTURE0_2D) { - if (enabled) - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; - } - tObj = ctx->Texture.Unit[source].Current; +static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) +{ + mgaTextureObjectPtr t; + struct gl_texture_object *tObj; + GLuint enabled; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + GLuint source = mmesa->tmu_source[unit]; - if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] ) - return; -/* fprintf(stderr, "unit %d: %d\n", unit, tObj->Name); */ - - /* if the texture object doesn't exist at all (never used or - swapped out), create it now, uploading all texture images */ + enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY; + tObj = ctx->Texture.Unit[source].Current; - if ( !tObj->DriverData ) { - /* clear the current pointer so that texture object can be - swapped out if necessary to make room */ - mgaCreateTexObj( mmesa, tObj ); + if (enabled != TEXTURE0_2D) { + if (enabled) + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } - if ( !tObj->DriverData ) { - mgaMsg( 5, "mgaUpdateTextureState: create failed\n" ); - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; - return; /* can't create a texture object */ - } - } + if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] ) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } - /* we definately have a valid texture now */ - mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; - mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_texture_trap; +/* if (!tObj) tObj = ctx->Texture.Unit[0].Current; */ +/* if (!tObj) return; */ - t = (mgaTextureObjectPtr)tObj->DriverData; + if ( !tObj->DriverData ) { + mgaCreateTexObj( mmesa, tObj ); + if ( !tObj->DriverData ) { + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + } + } - if (t->dirty_images) - mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit); + t = (mgaTextureObjectPtr)tObj->DriverData; - mmesa->CurrentTexObj[unit] = t; - t->bound = unit+1; + if (t->dirty_images) + mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit); - if (t->MemBlock) - mgaUpdateTexLRU( mmesa, t ); + mmesa->CurrentTexObj[unit] = t; + t->bound |= unit+1; +/* if (t->MemBlock) */ +/* mgaUpdateTexLRU( mmesa, t ); */ - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable; - if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D)) - t->Setup[MGA_TEXREG_CTL2] |= TMC_dualtex_enable; + t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable; + if (mmesa->multitex) + t->Setup[MGA_TEXREG_CTL2] |= TMC_dualtex_enable; - t->Setup[MGA_TEXREG_CTL2] &= ~TMC_specen_enable; - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; - + t->Setup[MGA_TEXREG_CTL2] &= ~TMC_specen_enable; + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable; } @@ -1053,279 +496,259 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { */ void mgaUpdateTextureState( GLcontext *ctx ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE; - - if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->bound = 0; - if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->bound = 0; - mmesa->CurrentTexObj[0] = 0; - mmesa->CurrentTexObj[1] = 0; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE; - if (MGA_IS_G400(mmesa)) { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureStage( ctx, 0 ); + if (mmesa->CurrentTexObj[0]) { + mmesa->CurrentTexObj[0]->bound = 0; + mmesa->CurrentTexObj[0] = 0; + } - mmesa->Setup[MGA_CTXREG_TDUAL1] = - mmesa->Setup[MGA_CTXREG_TDUAL0]; + if (mmesa->CurrentTexObj[1]) { + mmesa->CurrentTexObj[1]->bound = 0; + mmesa->CurrentTexObj[1] = 0; + } - if (mmesa->multitex) { - mgaUpdateTextureObject( ctx, 1 ); - mgaUpdateTextureStage( ctx, 1 ); - } - - mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1; - } else { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureEnvG200( ctx ); - } - - /* schedule the register writes */ - mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0; -} + if (MGA_IS_G400(mmesa)) { + mgaUpdateTextureObject( ctx, 0 ); + mgaUpdateTextureEnvG400( ctx, 0 ); + + mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0]; + + if (mmesa->multitex || 1) { + mgaUpdateTextureObject( ctx, 1 ); + mgaUpdateTextureEnvG400( ctx, 1 ); + } +/* else */ +/* mmesa->Setup[MGA_CTXREG_TDUAL1] = ( TD0_color_arg2_prevstage | */ +/* TD0_color_sel_arg2 | */ +/* TD0_alpha_arg2_prevstage | */ +/* TD0_alpha_sel_arg2); */ + + + mmesa->dirty |= MGA_UPLOAD_TEX1; + } else { + mgaUpdateTextureObject( ctx, 0 ); + mgaUpdateTextureEnvG200( ctx ); + } + mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0; + mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; + mmesa->Setup[MGA_CTXREG_DWGCTL] |= (ctx->Texture.Enabled + ? DC_opcod_texture_trap + : DC_opcod_trap); +} -/* -============================================================================ -Driver functions called directly from mesa -============================================================================ -*/ -/* - * mgaTexEnv - */ -void mgaTexEnv( GLcontext *ctx, GLenum target, GLenum pname, - const GLfloat *param ) +static void mgaDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) { - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mgaMsg( 10, "mgaTexEnv( %i )\n", pname ); - - - if (pname == GL_TEXTURE_ENV_MODE) { - /* force the texture state to be updated */ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; - } - else if (pname == GL_TEXTURE_ENV_COLOR) - { - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; - GLubyte c[4]; - GLuint col; - - - c[0] = fc[0]; - c[1] = fc[1]; - c[2] = fc[2]; - c[3] = fc[3]; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); - /* No alpha at 16bpp? - */ - col = mgaPackColor( mmesa->mgaScreen->Attrib, - c[0], c[1], c[2], c[3] ); - mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + if (pname == GL_TEXTURE_ENV_MODE) { + /* force the texture state to be updated */ + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE | + MGA_NEW_ALPHA); + } + else if (pname == GL_TEXTURE_ENV_COLOR) + { + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + GLfloat *fc = texUnit->EnvColor; + GLubyte c[4]; + GLuint col; + + COPY_4V(c, fc); + col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] ); + mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); - if (mmesa->Setup[MGA_CTXREG_FCOL] != col) { - FLUSH_BATCH(mmesa); - mmesa->Setup[MGA_CTXREG_FCOL] = col; - mmesa->dirty |= MGA_UPLOAD_CTX; - - mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; - - /* Actually just require all four components to be - * equal. This permits a single-pass GL_BLEND. - * - * More complex multitexture/multipass fallbacks - * for blend can be done later. - */ - if (mmesa->envcolor != 0x0 && - mmesa->envcolor != 0xffffffff) - mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; - } - } - + if (mmesa->Setup[MGA_CTXREG_FCOL] != col) { + FLUSH_BATCH(mmesa); + mmesa->Setup[MGA_CTXREG_FCOL] = col; + mmesa->dirty |= MGA_UPLOAD_CTX; + + mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; + + /* Actually just require all four components to be + * equal. This permits a single-pass GL_BLEND. + * + * More complex multitexture/multipass fallbacks + * for blend can be done later. + */ + if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff) + mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; + } + } } -/* - * mgaTexImage - */ -void mgaTexImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint internalFormat, - const struct gl_texture_image *image ) + +static void mgaDDTexImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; - mgaMsg( 10,"mgaTexImage( %p, level %i )\n", tObj, level ); - - /* just free the mga texture if it exists, it will be recreated at - mgaUpdateTextureState time. */ - t = (mgaTextureObjectPtr) tObj->DriverData; - if ( t ) { - if (t->bound) FLUSH_BATCH(mmesa); - /* if this is the current object, it will force an update */ - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + /* just free the mga texture if it exists, it will be recreated at + mgaUpdateTextureState time. */ + t = (mgaTextureObjectPtr) tObj->DriverData; + if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); + /* if this is the current object, it will force an update */ + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } + + if (0) + fprintf(stderr, "mgaDDTexImage tObj %p, level %d, image %p\n", + tObj, level, image); + } -/* - * mgaTexSubImage - */ -void mgaTexSubImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLint internalFormat, - const struct gl_texture_image *image ) +static void mgaDDTexSubImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLint internalFormat, + const struct gl_texture_image *image ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; - - mgaMsg(10,"mgaTexSubImage() Size: %d,%d of %d,%d; Level %d\n", - width, height, image->Width,image->Height, level); + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; - t = (mgaTextureObjectPtr) tObj->DriverData; + t = (mgaTextureObjectPtr) tObj->DriverData; - /* just free the mga texture if it exists, it will be recreated at - mgaUpdateTextureState time. */ - t = (mgaTextureObjectPtr) tObj->DriverData; - if ( t ) { - if (t->bound) FLUSH_BATCH(mmesa); - /* if this is the current object, it will force an update */ - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + /* just free the mga texture if it exists, it will be recreated at + mgaUpdateTextureState time. */ + t = (mgaTextureObjectPtr) tObj->DriverData; + if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); + /* if this is the current object, it will force an update */ + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } #if 0 - /* the texture currently exists, so directly update it */ - mgaUploadSubImage( t, level, xoffset, yoffset, width, height ); + /* the texture currently exists, so directly update it */ + mgaUploadSubImage( t, level, xoffset, yoffset, width, height ); #endif } + + /* * mgaTexParameter * This just changes variables and flags for a state update, which * will happen at the next mgaUpdateTextureState */ -void mgaTexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) +static void +mgaDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; - - mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname ); - - t = (mgaTextureObjectPtr) tObj->DriverData; - - /* if we don't have a hardware texture, it will be automatically - created with current state before it is used, so we don't have - to do anything now */ - if ( !t || target != GL_TEXTURE_2D ) { - return; - } - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); - break; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t; + + t = (mgaTextureObjectPtr) tObj->DriverData; + + /* if we don't have a hardware texture, it will be automatically + created with current state before it is used, so we don't have + to do anything now */ + if ( !t || !t->bound || target != GL_TEXTURE_2D ) { + return; + } + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + FLUSH_BATCH(mmesa); + mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + FLUSH_BATCH(mmesa); + mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); + break; - case GL_TEXTURE_BORDER_COLOR: - if (t->bound) FLUSH_BATCH(mmesa); - mgaSetTexBorderColor(t,tObj->BorderColor); - break; + case GL_TEXTURE_BORDER_COLOR: + FLUSH_BATCH(mmesa); + mgaSetTexBorderColor(t,tObj->BorderColor); + break; - default: - return; - } + default: + return; + } - mmesa->new_state |= MGA_NEW_TEXTURE; + mmesa->new_state |= MGA_NEW_TEXTURE; } -/* - * mgaBindTexture - */ -void mgaBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) -{ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaMsg( 10, "mgaBindTexture( %p )\n", tObj ); +static void +mgaDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + int unit = ctx->Texture.CurrentUnit; - FLUSH_BATCH(mmesa); + FLUSH_BATCH(mmesa); - if (mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { - mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; - mmesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; - } + if (mmesa->CurrentTexObj[unit]) { + mmesa->CurrentTexObj[unit]->bound &= ~(unit+1); + mmesa->CurrentTexObj[unit] = 0; + } - /* force the texture state to be updated - */ - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + /* force the texture state to be updated + */ + MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } -/* - * mgaDeleteTexture - */ -void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) + +static void +mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + + if ( t ) { + if (t->bound) { + FLUSH_BATCH(mmesa); + if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; + if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; + mmesa->new_state |= MGA_NEW_TEXTURE; + } - mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj ); - - if ( t ) { - if (t->bound) { - FLUSH_BATCH(mmesa); - mmesa->CurrentTexObj[t->bound-1] = 0; - mmesa->new_state |= MGA_NEW_TEXTURE; - } - - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; - } + mgaDestroyTexObj( mmesa, t ); + mmesa->new_state |= MGA_NEW_TEXTURE; + } } -/* Have to grab the lock to find out if anyone has kicked out our - * textures. - */ -GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) +static GLboolean +mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) { - mgaTextureObjectPtr mt; - -/* LOCK_HARDWARE; */ - mt = (mgaTextureObjectPtr)t->DriverData; -/* UNLOCK_HARDWARE; */ - - return mt && mt->MemBlock; + mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData; + return mt && mt->MemBlock; } -void mgaDDInitTextureFuncs( GLcontext *ctx ) + +void +mgaDDInitTextureFuncs( GLcontext *ctx ) { - ctx->Driver.TexEnv = mgaTexEnv; - ctx->Driver.TexImage = mgaTexImage; - ctx->Driver.TexSubImage = mgaTexSubImage; - ctx->Driver.BindTexture = mgaBindTexture; - ctx->Driver.DeleteTexture = mgaDeleteTexture; - ctx->Driver.TexParameter = mgaTexParameter; + ctx->Driver.TexEnv = mgaDDTexEnv; + ctx->Driver.TexImage = mgaDDTexImage; + ctx->Driver.TexSubImage = mgaDDTexSubImage; + ctx->Driver.BindTexture = mgaDDBindTexture; + ctx->Driver.DeleteTexture = mgaDDDeleteTexture; + ctx->Driver.TexParameter = mgaDDTexParameter; ctx->Driver.UpdateTexturePalette = 0; - ctx->Driver.IsTextureResident = mgaIsTextureResident; + ctx->Driver.IsTextureResident = mgaDDIsTextureResident; } |