Ejemplo n.º 1
0
/*
 * After a context switch this function will be called to restore
 * texture memory for the new context.
 */
void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa )
{
   GLcontext *ctx = fxMesa->glCtx;
   struct gl_texture_object *tObj;
   int i;

   for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) {
      tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj );
      if ( ti && ti->isInTM ) {
	 for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
	    if ( ctx->Texture.Unit[i]._Current == tObj ) {
	       tdfxTMDownloadTexture( fxMesa, tObj );
	       break;
	    }
	 }
	 if ( i == MAX_TEXTURE_UNITS ) {
	    tdfxTMMoveOutTM_NoLock( fxMesa, tObj );
	 }
      }
   }
   /*
   VerifyFreeList(fxMesa, 0);
   VerifyFreeList(fxMesa, 1);
   */
}
Ejemplo n.º 2
0
/*
 * When we've run out of texture memory we have to throw out an
 * existing texture to make room for the new one.  This function
 * determins the texture to throw out.
 */
static struct gl_texture_object *
FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu)
{
    const GLuint bindnumber = fxMesa->texBindNumber;
    struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj;
    GLfloat lowestPriority;
    GLuint oldestAge;

    oldestObj = NULL;
    oldestAge = 0;

    lowestPriority = 1.0F;
    lowestPriorityObj = NULL;

    for (obj = fxMesa->glCtx->Shared->TexObjectList; obj; obj = obj->Next) {
        tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj);

        if (info && info->isInTM &&
            ((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) ||
             (info->whichTMU == TDFX_TMU_SPLIT))) {
            GLuint age, lasttime;

            assert(info->tm[0]);
            lasttime = info->lastTimeUsed;

            if (lasttime > bindnumber)
                age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */
            else
                age = bindnumber - lasttime;

            if (age >= oldestAge) {
                oldestAge = age;
                oldestObj = obj;
            }

            /* examine priority */
            if (obj->Priority < lowestPriority) {
                lowestPriority = obj->Priority;
                lowestPriorityObj = obj;
            }
        }
    }

    if (lowestPriority < 1.0) {
        ASSERT(lowestPriorityObj);
        /*
        printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority);
        */
        return lowestPriorityObj;
    }
    else {
        /*
        printf("discard %d age=%d\n", oldestObj->Name, oldestAge);
        */
        return oldestObj;
    }
}
Ejemplo n.º 3
0
static void
dump_texmem(tdfxContextPtr fxMesa)
{
    struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
    struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
    struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj;
    tdfxMemRange *r;
    FxU32 prev;

    printf("DUMP Objects:\n");
    for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) {
        tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj);

        if (info && info->isInTM) {
        printf("Obj %8p: %4d  info = %p\n", obj, obj->Name, info);

           printf("  isInTM=%d  whichTMU=%d  lastTimeUsed=%d\n",
                  info->isInTM, info->whichTMU, info->lastTimeUsed);
           printf("    tm[0] = %p", info->tm[0]);
           assert(info->tm[0]);
           if (info->tm[0]) {
              printf("  tm startAddr = %d  endAddr = %d",
                     info->tm[0]->startAddr,
                     info->tm[0]->endAddr);
           }
           printf("\n");
           printf("    tm[1] = %p", info->tm[1]);
           if (info->tm[1]) {
              printf("  tm startAddr = %d  endAddr = %d",
                     info->tm[1]->startAddr,
                     info->tm[1]->endAddr);
           }
           printf("\n");
        }
    }

    VerifyFreeList(fxMesa, 0);
    VerifyFreeList(fxMesa, 1);

    printf("Free memory unit 0:  %d bytes\n", shared->freeTexMem[0]);
    prev = 0;
    for (r = shared->tmFree[0]; r; r = r->next) {
       printf("%8p:  start %8d  end %8d  size %8d  gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev);
       prev = r->endAddr;
    }

    printf("Free memory unit 1:  %d bytes\n", shared->freeTexMem[1]);
    prev = 0;
    for (r = shared->tmFree[1]; r; r = r->next) {
       printf("%8p:  start %8d  end %8d  size %8d  gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev);
       prev = r->endAddr;
    }

}
Ejemplo n.º 4
0
/*
 * Called via glDeleteTexture to delete a texture object.
 */
void
tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
{
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
    if (ti) {
        tdfxTMMoveOutTM(fxMesa, tObj);
        FREE(ti);
        tObj->DriverData = NULL;
    }
    /*
    VerifyFreeList(fxMesa, 0);
    VerifyFreeList(fxMesa, 1);
    */
}
Ejemplo n.º 5
0
/*
 * Verify the consistancy of the texture memory manager.
 * This involves:
 *    Traversing all texture objects and computing total memory used.
 *    Traverse the free block list and computing total memory free.
 *    Compare the total free and total used amounts to the total memory size.
 *    Make various assertions about the results.
 */
static void
VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu)
{
    struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
    struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
    tdfxMemRange *block;
    int prevStart = -1, prevEnd = -1;
    int totalFree = 0;
    int numObj = 0, numRes = 0;
    int totalUsed = 0;

    for (block = shared->tmFree[tmu]; block; block = block->next) {
       assert( block->endAddr > 0 );
       assert( block->startAddr <= shared->totalTexMem[tmu] );
       assert( block->endAddr <= shared->totalTexMem[tmu] );
       assert( (int) block->startAddr > prevStart );
       assert( (int) block->startAddr >= prevEnd );
       prevStart = (int) block->startAddr;
       prevEnd = (int) block->endAddr;
       totalFree += (block->endAddr - block->startAddr);
    }
    assert(totalFree == shared->freeTexMem[tmu]);

    {
       struct gl_texture_object *obj;
       for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) {
          tdfxTexInfo *ti = TDFX_TEXTURE_DATA(obj);
          numObj++;
          if (ti) {
             if (ti->isInTM) {
                numRes++;
                assert(ti->tm[0]);
                if (ti->tm[tmu])
                   totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr);
             }
             else {
                assert(!ti->tm[0]);
             }
          }
       }
    }

    printf("totalFree: %d  totalUsed: %d  totalMem: %d #objs=%d  #res=%d\n",
           shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu],
           numObj, numRes);

    assert(totalUsed + totalFree == shared->totalTexMem[tmu]);
}
Ejemplo n.º 6
0
/*
 * Move the given texture out of hardware texture memory.
 * This deallocates the texture's memory space.
 */
void
tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj )
{
    struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
    struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);

    if (MESA_VERBOSE & VERBOSE_DRIVER) {
        fprintf(stderr, "fxmesa: fxTMMoveOutTM(%p (%d))\n", tObj, tObj->Name);
    }

    /*
    VerifyFreeList(fxMesa, 0);
    VerifyFreeList(fxMesa, 1);
    */

    if (!ti || !ti->isInTM)
        return;

    switch (ti->whichTMU) {
    case TDFX_TMU0:
    case TDFX_TMU1:
        RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]);
        break;
    case TDFX_TMU_SPLIT:
    case TDFX_TMU_BOTH:
        assert(!shared->umaTexMemory);
        RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]);
        RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]);
        break;
    default:
        _mesa_problem(NULL, "tdfx driver: bad tmu in tdfxTMMOveOutTM()");
        return;
    }

    ti->isInTM = GL_FALSE;
    ti->tm[0] = NULL;
    ti->tm[1] = NULL;
    ti->whichTMU = TDFX_TMU_NONE;

    /*
    VerifyFreeList(fxMesa, 0);
    VerifyFreeList(fxMesa, 1);
    */
}
Ejemplo n.º 7
0
static void uploadTextureImages( tdfxContextPtr fxMesa )
{
   GLcontext *ctx = fxMesa->glCtx;
   int unit;
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
      if (ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
         struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
         tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
         if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) {
            /*
            printf("download texture image on unit %d\n", unit);
            */
            tdfxTMDownloadTexture(fxMesa, tObj);
            ti->reloadImages = GL_FALSE;
         }
      }
   }
}
Ejemplo n.º 8
0
/*
 * Allocate space for the given texture in texture memory then
 * download (copy) it into that space.
 */
void
tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj,
                       FxU32 targetTMU )
{
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
    FxU32 texmemsize;

    fxMesa->stats.reqTexUpload++;

    if (ti->isInTM) {
        if (ti->whichTMU == targetTMU)
            return;
        if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) {
            tdfxTMMoveOutTM_NoLock(fxMesa, tObj);
        }
        else {
            if (ti->whichTMU == TDFX_TMU_BOTH)
                return;
            targetTMU = TDFX_TMU_BOTH;
        }
    }

    ti->whichTMU = targetTMU;

    switch (targetTMU) {
    case TDFX_TMU0:
    case TDFX_TMU1:
        texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,
                                                       &(ti->info));
        ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize);
        break;
    case TDFX_TMU_SPLIT:
        texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD,
                                                       &(ti->info));
        ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize);
        if (ti->tm[TDFX_TMU0])
           fxMesa->stats.memTexUpload += texmemsize;

        texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN,
                                                       &(ti->info));
        ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize);
        break;
    case TDFX_TMU_BOTH:
        texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,
                                                       &(ti->info));
        ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize);
        if (ti->tm[TDFX_TMU0])
           fxMesa->stats.memTexUpload += texmemsize;

        texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,
                                                       &(ti->info));
        ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize);
        break;
    default:
        _mesa_problem(NULL, "error in tdfxTMMoveInTM() -> bad tmu (%d)");
        return;
    }

    ti->reloadImages = GL_TRUE;
    ti->isInTM = GL_TRUE;

    fxMesa->stats.texUpload++;
}
Ejemplo n.º 9
0
void
tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj,
                        GLint level)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
    GrLOD_t glideLod;
    FxU32 tmu;

    tmu = ti->whichTMU;
    glideLod =  ti->info.largeLodLog2 - level + tObj->BaseLevel;
    ASSERT(ti->isInTM);

    LOCK_HARDWARE(fxMesa);

    switch (tmu) {
    case TDFX_TMU0:
    case TDFX_TMU1:
        fxMesa->Glide.grTexDownloadMipMapLevel(tmu,
                                    ti->tm[tmu]->startAddr,
                                    glideLod,
                                    ti->info.largeLodLog2,
                                    ti->info.aspectRatioLog2,
                                    ti->info.format,
                                    GR_MIPMAPLEVELMASK_BOTH,
                                    tObj->Image[level]->Data);
        break;
    case TDFX_TMU_SPLIT:
        fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0,
                                    ti->tm[GR_TMU0]->startAddr,
                                    glideLod,
                                    ti->info.largeLodLog2,
                                    ti->info.aspectRatioLog2,
                                    ti->info.format,
                                    GR_MIPMAPLEVELMASK_ODD,
                                    tObj->Image[level]->Data);

        fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1,
                                    ti->tm[GR_TMU1]->startAddr,
                                    glideLod,
                                    ti->info.largeLodLog2,
                                    ti->info.aspectRatioLog2,
                                    ti->info.format,
                                    GR_MIPMAPLEVELMASK_EVEN,
                                    tObj->Image[level]->Data);
        break;
    case TDFX_TMU_BOTH:
        fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0,
                                    ti->tm[GR_TMU0]->startAddr,
                                    glideLod,
                                    ti->info.largeLodLog2,
                                    ti->info.aspectRatioLog2,
                                    ti->info.format,
                                    GR_MIPMAPLEVELMASK_BOTH,
                                    tObj->Image[level]->Data);

        fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1,
                                    ti->tm[GR_TMU1]->startAddr,
                                    glideLod,
                                    ti->info.largeLodLog2,
                                    ti->info.aspectRatioLog2,
                                    ti->info.format,
                                    GR_MIPMAPLEVELMASK_BOTH,
                                    tObj->Image[level]->Data);
        break;

    default:
        _mesa_problem(ctx, "error in tdfxTMReloadMipMapLevel(): wrong tmu");
        break;
    }
    UNLOCK_HARDWARE(fxMesa);
}
Ejemplo n.º 10
0
/*
 * Download (copy) the given texture data (all mipmap levels) into the
 * Voodoo's texture memory.
 * The texture memory must have already been allocated.
 */
void
tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj)
{
    tdfxTexInfo *ti;
    GLint l;
    FxU32 targetTMU;

    assert(tObj);
    ti = TDFX_TEXTURE_DATA(tObj);
    assert(ti);
    targetTMU = ti->whichTMU;

    switch (targetTMU) {
    case TDFX_TMU0:
    case TDFX_TMU1:
        if (ti->tm[targetTMU]) {
            for (l = ti->minLevel; l <= ti->maxLevel
                    && tObj->Image[l]->Data; l++) {
                GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
                fxMesa->Glide.grTexDownloadMipMapLevel(targetTMU,
                                                  ti->tm[targetTMU]->startAddr,
                                                  glideLod,
                                                  ti->info.largeLodLog2,
                                                  ti->info.aspectRatioLog2,
                                                  ti->info.format,
                                                  GR_MIPMAPLEVELMASK_BOTH,
                                                  tObj->Image[l]->Data);
            }
        }
        break;
    case TDFX_TMU_SPLIT:
        if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) {
            for (l = ti->minLevel; l <= ti->maxLevel
                    && tObj->Image[l]->Data; l++) {
                GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
                fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0,
                                                  ti->tm[TDFX_TMU0]->startAddr,
                                                  glideLod,
                                                  ti->info.largeLodLog2,
                                                  ti->info.aspectRatioLog2,
                                                  ti->info.format,
                                                  GR_MIPMAPLEVELMASK_ODD,
                                                  tObj->Image[l]->Data);

                fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1,
                                                  ti->tm[TDFX_TMU1]->startAddr,
                                                  glideLod,
                                                  ti->info.largeLodLog2,
                                                  ti->info.aspectRatioLog2,
                                                  ti->info.format,
                                                  GR_MIPMAPLEVELMASK_EVEN,
                                                  tObj->Image[l]->Data);
            }
        }
        break;
    case TDFX_TMU_BOTH:
        if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) {
            for (l = ti->minLevel; l <= ti->maxLevel
                    && tObj->Image[l]->Data; l++) {
                GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel;
                fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0,
                                                  ti->tm[TDFX_TMU0]->startAddr,
                                                  glideLod,
                                                  ti->info.largeLodLog2,
                                                  ti->info.aspectRatioLog2,
                                                  ti->info.format,
                                                  GR_MIPMAPLEVELMASK_BOTH,
                                                  tObj->Image[l]->Data);

                fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1,
                                                  ti->tm[TDFX_TMU1]->startAddr,
                                                  glideLod,
                                                  ti->info.largeLodLog2,
                                                  ti->info.aspectRatioLog2,
                                                  ti->info.format,
                                                  GR_MIPMAPLEVELMASK_BOTH,
                                                  tObj->Image[l]->Data);
            }
        }
        break;
    default:
        _mesa_problem(NULL, "error in tdfxTMDownloadTexture: bad tmu");
        return;
    }
}