Mercurial > hg > Game > Cerium
diff TaskManager/Test/test_render/spe/DrawSpan.cpp @ 184:a19d3ed4ce5b draft
fix
author | gongo@gendarme.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Tue, 06 Jan 2009 15:39:48 +0900 |
parents | 8e9ada0c1ed0 |
children | 06cdf8baa989 |
line wrap: on
line diff
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp Tue Dec 23 16:27:07 2008 +0900 +++ b/TaskManager/Test/test_render/spe/DrawSpan.cpp Tue Jan 06 15:39:48 2009 +0900 @@ -2,19 +2,15 @@ #include <string.h> #include "DrawSpan.h" #include "polygon_pack.h" -#include "SpanPack.h" #include "texture.h" #include "viewer_types.h" -#include "TileHash.h" +#include "Func.h" #define SPAN_PACK_LOAD 0 #define TEX_LOAD 1 SchedDefineTask(DrawSpan); -static TileHashPtr hash; -static TileListPtr tileList; - /** * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する * @@ -45,8 +41,8 @@ * @param[in] twidth Width of texture * @return block ID */ -static inline int -get_tex_block(int tx, int ty, int twidth) +int +DrawSpan::getTexBlock(int tx, int ty, int twidth) { int blockX, blockY; @@ -66,10 +62,10 @@ * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address * @return block ID */ -static inline uint32* -getTile(int tx, int ty, int tw, uint32 *tex_addr_top) +uint32* +DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top) { - int block = get_tex_block(tx, ty, tw); + int block = getTexBlock(tx, ty, tw); return tex_addr_top + block*TEXTURE_BLOCK_SIZE; } @@ -81,54 +77,115 @@ } } +/** + * Span が使う Texture Tile があるか + * + * @retval != NULL 存在する + * @retval NULL 存在しない + */ +TilePtr +DrawSpan::isAvailableTile(uint32 *addr) +{ + return hash->get(addr); +} + +void +DrawSpan::set_rgb(uint32 *addr) +{ + TilePtr tile; + + if (!isAvailableTile(addr)) { + tile = tileList->nextTile(); + /** + * FIFO なので、もし前のが残っていれば削除 + */ + hash->remove(tile->texture_addr); + + tile->texture_addr = addr; + + hash->put(tile->texture_addr, tile); + + smanager->dma_load(tile->pixel, (uint32)addr, + sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD); + + smanager->dma_wait(TEX_LOAD); + } +} + +void +DrawSpan::set_rgbs(uint32 *addr, uint32 *max_addr) +{ + uint32 start = (uint32)addr; + uint32 end = (uint32)max_addr; + uint32 length = end-start; + uint32 diff = sizeof(uint32)*TEXTURE_BLOCK_SIZE; + uint32 max_tile = 8; + + for (uint32 i = 0, j = 0; i <= length && j < max_tile; i += diff, j++) { + set_rgb((uint32*)(start + i)); + } +} + Uint32 DrawSpan::get_rgb(int tx, int ty, uint32 *addr) { TilePtr tile; tile = hash->get(addr); - if (tile == NULL) { - tile = tileList->nextTile(); - - /** - * FIFO なので、もし前のが残っていれば削除 - */ - hash->remove(tile->texture_addr); - - tile->texture_addr = addr; - - smanager->dma_load(tile->pixel, (uint32)addr, - sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD); - - int index = hash->put(tile->texture_addr, tile); - - /** - * TODO: - * 入らなかったやつは - * 今までのやつを描画してから続きをするとか - */ - if (index < 0) { - printf("[%p] Can't entry\n", tile); - return 0xff0000; - } - - smanager->dma_wait(TEX_LOAD); - } - return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx]; } +/** + * DrawSpan の再起動 (DrawSpanRenew 生成) + * + * @param[in] spack 現在処理している SpanPack + * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で + * どこまで進んでいるか + */ +void +DrawSpan::reboot(SpanPackPtr spack, int cur_span_x) +{ + TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); + int rangey = smanager->get_param(2); + /** + * 共通の outData, param はそのまま渡す + */ + for (int i = 0; i < rangey; i++) { + renew_task->add_outData(smanager->get_outputAddr(i), + smanager->get_outputSize(i)); + } + + // rangex_start, rangex_end, rangey + renew_task->add_param(smanager->get_param(0)); + renew_task->add_param(smanager->get_param(1)); + renew_task->add_param(smanager->get_param(2)); + + /** + * SpanPack は続きから開始するので、 + * 現在の状態をコピーしておく。 + * spack は rbuf から取得してる可能性があり + * rbuf はシステムが自動的に free() するため + * アドレスだけ渡すのはNG + */ + SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + memcpy(curr, spack, sizeof(SpanPack)); + renew_task->add_param((int)curr); + + renew_task->add_param(cur_span_x); + + /** + * 再起動したタスクを待つ + */ + smanager->wait_task(renew_task); + + // next_spack は free() するので wait する + smanager->dma_wait(SPAN_PACK_LOAD); +} int DrawSpan::run(void *rbuf, void *wbuf) { - SpanPack *spack = (SpanPack*)smanager->get_input(0); - SpanPack *next_spack = - (SpanPack*)smanager->allocate(sizeof(SpanPack)); - SpanPack *free_spack = next_spack; // next_spack の free() 用 - Span *span; - hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH); tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); @@ -141,7 +198,12 @@ // y の範囲 (render_y + rangey - 1) int rangey = smanager->get_param(2); - float *zRow = (float*)smanager->get_input(1); + float *zRow = (float*)smanager->allocate(sizeof(float)*rangex*rangey); + + for (int i = 0; i < rangex*rangey; i++) { + zRow[i] = 65535.0f; + } + int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey); for (int i = 0; i < rangey; i++) { @@ -149,6 +211,11 @@ linebuf_init(linebuf[i], rangex, 0xffffffff); } + SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0); + SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + SpanPackPtr free_spack = next_spack; // next_spack の free() 用 + Span *span; + do { /** * SpanPack->next が存在する場合、 @@ -210,6 +277,20 @@ tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; + /** + * Tile が無い場合、一旦タスクはここで中断し、 + * Tile をロードするタスクを走らせた後に再起動する + */ + if (!isAvailableTile(tex_addr)) { + spack->info.start = t; + //set_rgb(tex_addr); + set_rgbs(tex_addr, + getTile(span->tex_width-1, tex_ypos, + span->tex_width, span->tex_addr)); + reboot(spack, 0); + goto FINISH; + } + rgb = get_rgb(tex_localx, tex_localy, tex_addr); zRow[localx + (rangex * localy)] = zpos; @@ -239,6 +320,16 @@ span->tex_width, span->tex_addr); tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; + + if (!isAvailableTile(tex_addr)) { + spack->info.start = t; + //set_rgb(tex_addr); + set_rgbs(tex_addr, + getTile(span->tex_width-1, tex_ypos, + span->tex_width, span->tex_addr)); + reboot(spack, j); + goto FINISH; + } rgb = get_rgb(tex_localx, tex_localy, tex_addr); @@ -251,11 +342,13 @@ smanager->dma_wait(SPAN_PACK_LOAD); - SpanPack *tmp_spack = spack; + SpanPackPtr tmp_spack = spack; spack = next_spack; next_spack = tmp_spack; } while (spack); + +FINISH: free(free_spack); free(linebuf);