Annotation of quake1/d_surf.c, revision 1.1.1.3

1.1       root        1: // d_surf.c: rasterization driver surface heap manager
                      2: 
                      3: #include "quakedef.h"
                      4: #include "d_local.h"
                      5: #include "r_local.h"
                      6: 
1.1.1.3 ! root        7: float           surfscale;
        !             8: qboolean        r_cache_thrash;         // set if surface cache is thrashing
1.1       root        9: 
1.1.1.3 ! root       10: int                                     sc_size;
        !            11: surfcache_t                     *sc_rover, *sc_base;
1.1       root       12: 
1.1.1.3 ! root       13: #define GUARDSIZE       4
1.1       root       14: 
                     15: 
1.1.1.3 ! root       16: int     D_SurfaceCacheForRes (int width, int height)
1.1       root       17: {
1.1.1.3 ! root       18:        int             size, pix;
1.1       root       19: 
                     20:        if (COM_CheckParm ("-surfcachesize"))
                     21:        {
                     22:                size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024;
                     23:                return size;
                     24:        }
                     25:        
                     26:        size = SURFCACHE_SIZE_AT_320X200;
                     27: 
                     28:        pix = width*height;
                     29:        if (pix > 64000)
1.1.1.3 ! root       30:                size += (pix-64000)*3;
1.1       root       31:                
                     32: 
                     33:        return size;
                     34: }
                     35: 
                     36: void D_CheckCacheGuard (void)
                     37: {
1.1.1.3 ! root       38:        byte    *s;
        !            39:        int             i;
1.1       root       40: 
                     41:        s = (byte *)sc_base + sc_size;
                     42:        for (i=0 ; i<GUARDSIZE ; i++)
                     43:                if (s[i] != (byte)i)
                     44:                        Sys_Error ("D_CheckCacheGuard: failed");
                     45: }
                     46: 
                     47: void D_ClearCacheGuard (void)
                     48: {
1.1.1.3 ! root       49:        byte    *s;
        !            50:        int             i;
1.1       root       51:        
                     52:        s = (byte *)sc_base + sc_size;
                     53:        for (i=0 ; i<GUARDSIZE ; i++)
                     54:                s[i] = (byte)i;
                     55: }
                     56: 
                     57: 
                     58: /*
                     59: ================
                     60: D_InitCaches
                     61: 
                     62: ================
                     63: */
                     64: void D_InitCaches (void *buffer, int size)
                     65: {
1.1.1.3 ! root       66: 
        !            67:        if (!msg_suppress_1)
        !            68:                Con_Printf ("%ik surface cache\n", size/1024);
1.1       root       69: 
                     70:        sc_size = size - GUARDSIZE;
                     71:        sc_base = (surfcache_t *)buffer;
                     72:        sc_rover = sc_base;
                     73:        
                     74:        sc_base->next = NULL;
                     75:        sc_base->owner = NULL;
                     76:        sc_base->size = sc_size;
                     77:        
                     78:        D_ClearCacheGuard ();
                     79: }
                     80: 
                     81: 
                     82: /*
                     83: ==================
                     84: D_FlushCaches
                     85: ==================
                     86: */
                     87: void D_FlushCaches (void)
                     88: {
1.1.1.3 ! root       89:        surfcache_t     *c;
1.1       root       90:        
                     91:        if (!sc_base)
                     92:                return;
                     93: 
                     94:        for (c = sc_base ; c ; c = c->next)
                     95:        {
                     96:                if (c->owner)
                     97:                        *c->owner = NULL;
                     98:        }
                     99:        
                    100:        sc_rover = sc_base;
                    101:        sc_base->next = NULL;
                    102:        sc_base->owner = NULL;
                    103:        sc_base->size = sc_size;
                    104: }
                    105: 
                    106: /*
                    107: =================
                    108: D_SCAlloc
                    109: =================
                    110: */
1.1.1.3 ! root      111: surfcache_t     *D_SCAlloc (int width, int size)
1.1       root      112: {
1.1.1.3 ! root      113:        surfcache_t             *new;
        !           114:        qboolean                wrapped_this_time;
1.1       root      115: 
                    116:        if ((width < 0) || (width > 256))
                    117:                Sys_Error ("D_SCAlloc: bad cache width %d\n", width);
                    118: 
                    119:        if ((size <= 0) || (size > 0x10000))
                    120:                Sys_Error ("D_SCAlloc: bad cache size %d\n", size);
                    121:        
1.1.1.3 ! root      122:        size = (int)&((surfcache_t *)0)->data[size];
        !           123:        size = (size + 3) & ~3;
1.1       root      124:        if (size > sc_size)
                    125:                Sys_Error ("D_SCAlloc: %i > cache size",size);
                    126: 
                    127: // if there is not size bytes after the rover, reset to the start
                    128:        wrapped_this_time = false;
                    129: 
                    130:        if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
                    131:        {
                    132:                if (sc_rover)
                    133:                {
                    134:                        wrapped_this_time = true;
                    135:                }
                    136:                sc_rover = sc_base;
                    137:        }
                    138:                
                    139: // colect and free surfcache_t blocks until the rover block is large enough
                    140:        new = sc_rover;
                    141:        if (sc_rover->owner)
                    142:                *sc_rover->owner = NULL;
                    143:        
                    144:        while (new->size < size)
                    145:        {
                    146:        // free another
                    147:                sc_rover = sc_rover->next;
                    148:                if (!sc_rover)
                    149:                        Sys_Error ("D_SCAlloc: hit the end of memory");
                    150:                if (sc_rover->owner)
                    151:                        *sc_rover->owner = NULL;
                    152:                        
                    153:                new->size += sc_rover->size;
                    154:                new->next = sc_rover->next;
                    155:        }
                    156: 
                    157: // create a fragment out of any leftovers
                    158:        if (new->size - size > 256)
                    159:        {
                    160:                sc_rover = (surfcache_t *)( (byte *)new + size);
                    161:                sc_rover->size = new->size - size;
                    162:                sc_rover->next = new->next;
                    163:                sc_rover->width = 0;
                    164:                sc_rover->owner = NULL;
                    165:                new->next = sc_rover;
                    166:                new->size = size;
                    167:        }
                    168:        else
                    169:                sc_rover = new->next;
                    170:        
                    171:        new->width = width;
                    172: // DEBUG
                    173:        if (width > 0)
                    174:                new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
                    175: 
1.1.1.3 ! root      176:        new->owner = NULL;              // should be set properly after return
1.1       root      177: 
                    178:        if (d_roverwrapped)
                    179:        {
                    180:                if (wrapped_this_time || (sc_rover >= d_initial_rover))
                    181:                        r_cache_thrash = true;
                    182:        }
                    183:        else if (wrapped_this_time)
1.1.1.3 ! root      184:        {       
1.1       root      185:                d_roverwrapped = true;
                    186:        }
                    187: 
1.1.1.3 ! root      188: D_CheckCacheGuard ();   // DEBUG
1.1       root      189:        return new;
                    190: }
                    191: 
                    192: 
                    193: /*
                    194: =================
                    195: D_SCDump
                    196: =================
                    197: */
                    198: void D_SCDump (void)
                    199: {
1.1.1.3 ! root      200:        surfcache_t             *test;
1.1       root      201: 
                    202:        for (test = sc_base ; test ; test = test->next)
                    203:        {
                    204:                if (test == sc_rover)
                    205:                        Sys_Printf ("ROVER:\n");
                    206:                printf ("%p : %i bytes     %i width\n",test, test->size, test->width);
                    207:        }
                    208: }
                    209: 
                    210: //=============================================================================
                    211: 
                    212: // if the num is not a power of 2, assume it will not repeat
                    213: 
1.1.1.3 ! root      214: int     MaskForNum (int num)
1.1       root      215: {
                    216:        if (num==128)
                    217:                return 127;
                    218:        if (num==64)
                    219:                return 63;
                    220:        if (num==32)
                    221:                return 31;
                    222:        if (num==16)
                    223:                return 15;
                    224:        return 255;
                    225: }
                    226: 
                    227: int D_log2 (int num)
                    228: {
1.1.1.3 ! root      229:        int     c;
1.1       root      230:        
                    231:        c = 0;
                    232:        
                    233:        while (num>>=1)
                    234:                c++;
                    235:        return c;
                    236: }
                    237: 
                    238: //=============================================================================
                    239: 
                    240: /*
                    241: ================
                    242: D_CacheSurface
                    243: ================
                    244: */
                    245: surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
                    246: {
1.1.1.3 ! root      247:        surfcache_t     *cache;
1.1       root      248: 
                    249: //
                    250: // if the surface is animating or flashing, flush the cache
                    251: //
                    252:        r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture);
                    253:        r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
                    254:        r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
                    255:        r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
                    256:        r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
                    257:        
                    258: //
                    259: // see if the cache holds apropriate data
                    260: //
                    261:        cache = surface->cachespots[miplevel];
                    262: 
                    263:        if (cache && !cache->dlight && surface->dlightframe != r_framecount
                    264:                        && cache->texture == r_drawsurf.texture
                    265:                        && cache->lightadj[0] == r_drawsurf.lightadj[0]
                    266:                        && cache->lightadj[1] == r_drawsurf.lightadj[1]
                    267:                        && cache->lightadj[2] == r_drawsurf.lightadj[2]
1.1.1.3 ! root      268:                        && cache->lightadj[3] == r_drawsurf.lightadj[3] )
1.1       root      269:                return cache;
                    270: 
                    271: //
                    272: // determine shape of surface
                    273: //
                    274:        surfscale = 1.0 / (1<<miplevel);
                    275:        r_drawsurf.surfmip = miplevel;
                    276:        r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
                    277:        r_drawsurf.rowbytes = r_drawsurf.surfwidth;
                    278:        r_drawsurf.surfheight = surface->extents[1] >> miplevel;
                    279:        
                    280: //
                    281: // allocate memory if needed
                    282: //
1.1.1.3 ! root      283:        if (!cache)     // if a texture just animated, don't reallocate it
1.1       root      284:        {
                    285:                cache = D_SCAlloc (r_drawsurf.surfwidth,
                    286:                                                   r_drawsurf.surfwidth * r_drawsurf.surfheight);
                    287:                surface->cachespots[miplevel] = cache;
                    288:                cache->owner = &surface->cachespots[miplevel];
                    289:                cache->mipscale = surfscale;
                    290:        }
                    291:        
                    292:        if (surface->dlightframe == r_framecount)
                    293:                cache->dlight = 1;
                    294:        else
                    295:                cache->dlight = 0;
                    296: 
                    297:        r_drawsurf.surfdat = (pixel_t *)cache->data;
                    298:        
                    299:        cache->texture = r_drawsurf.texture;
                    300:        cache->lightadj[0] = r_drawsurf.lightadj[0];
                    301:        cache->lightadj[1] = r_drawsurf.lightadj[1];
                    302:        cache->lightadj[2] = r_drawsurf.lightadj[2];
                    303:        cache->lightadj[3] = r_drawsurf.lightadj[3];
                    304: 
                    305: //
                    306: // draw and light the surface texture
                    307: //
                    308:        r_drawsurf.surf = surface;
                    309: 
                    310:        c_surf++;
                    311:        R_DrawSurface ();
                    312: 
                    313:        return surface->cachespots[miplevel];
                    314: }
                    315: 
1.1.1.3 ! root      316: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.