Mercurial > hg > Members > kono > Cerium
diff TaskManager/Test/test_render/spe/DrawSpan.cpp @ 128:776eca0daa02
texture load use hash table
author | gongo@charles.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Tue, 25 Nov 2008 15:52:28 +0900 |
parents | 7635f223fc7d |
children | 805d27efafd8 |
line wrap: on
line diff
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp Tue Nov 25 12:22:03 2008 +0900 +++ b/TaskManager/Test/test_render/spe/DrawSpan.cpp Tue Nov 25 15:52:28 2008 +0900 @@ -11,7 +11,64 @@ SchedDefineTask(DrawSpan); -unsigned char *tex; +static const int hashsize = 263; + +static TilePtr hash_table[hashsize] = {NULL}; + +unsigned short PRIME[8] = { + 0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd, +}; + +static TileListPtr tileList; + +static int +hash(uint32 data) +{ + int value = 0; + int n = 0; + int key; + + for (int i = 0; i < 8; i ++) { + key = data & 0xf; + value += key * PRIME[n++]; + data >>= 4; + } + + return value % hashsize; +} + +static int +put(void *key, TilePtr data) +{ + int hashval = hash((uint32)key); + + for (int i = 0; i < hashsize/2; i++) { + int index = (hashval + i*i)%hashsize; + + if (hash_table[index] == 0) { + hash_table[index] = data; + return index; + } + } + + return -1; +} + +static TilePtr +get(void *key) +{ + int hashval = hash((uint32)key); + + for (int i = 0; i < hashsize/2; i++) { + int index = (hashval + i*i)%hashsize; + + if (hash_table[index]->texture_addr == key) { + return hash_table[index]; + } + } + + return NULL; +} void DrawSpan::linebuf_init(int *buf, int x, int rgb) @@ -54,25 +111,44 @@ Uint8 red, green, blue, alpha; if (tx<0) tx = 0; - if (128-1< tx) tx = 128-1 ; + if (tex_width-1< tx) tx = tex_width-1 ; if (ty<0) ty = 0; - if (128-1< ty) ty = 128-1 ; + if (tex_height-1< ty) ty = tex_height-1 ; -#if 0 - char *p = get_pixel(tx,ty,texture); -#else void *texture_addr; int blockX = tx / 8; int blockY = ty / 8; void** addrList = (void**)global_get(TEXTURE2_ID); - - texture_addr = addrList[blockX + 16*blockY]; - smanager->dma_load(tex, (uint32)texture_addr, sizeof(uint32)*64, TEX_LOAD); - smanager->dma_wait(TEX_LOAD); + TilePtr tile; + + texture_addr = addrList[blockX + (tex_width/8)*blockY]; + + tile = get(texture_addr); + if (tile == NULL) { + if (tileList->size >= MAX_TILE) { + tileList->init(); + bzero(hash_table, sizeof(TilePtr)*hashsize); + } + + tile = &tileList->tile[tileList->size]; + tile->texture_addr = texture_addr; - char *p = get_pixel(tx%8, ty%8, tex); -#endif + smanager->dma_load(tile->pixel, (uint32)texture_addr, + sizeof(uint32)*64, TEX_LOAD); + + int index = put(tile->texture_addr, tile); + if (index < 0) { + printf("[%p] Can't entry\n", tile); + return 0xff0000; + } + + tileList->size++; + + smanager->dma_wait(TEX_LOAD); + } + + char *p = get_pixel(tx%8, ty%8, tile); alpha = 255; red = (Uint8) p[0]; @@ -93,6 +169,9 @@ SpanPack *tmp_sp = NULL; Span *span; + tileList = (TileListPtr)smanager->allocate(sizeof(TileList)); + tileList->init(); + int render_y = sp->info.y_top; void *texture_image = global_get(TEXTURE_ID); @@ -105,14 +184,13 @@ int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey); - tex = (unsigned char*)smanager->allocate(sizeof(unsigned char)*64*4); - for (int i = 0; i < rangey; i++) { linebuf[i] = (int*)smanager->get_output(i); - //linebuf_init(linebuf[i], rangex, 0x00ff00ff); linebuf_init(linebuf[i], rangex, 0); } + bzero(hash_table, sizeof(TilePtr)*hashsize); + do { /** * SpanPack->next が存在する場合、 @@ -196,7 +274,7 @@ free(free_sp); free(linebuf); free(zRow); - free(tex); + free(tileList); return 0; }