Mercurial > hg > Game > Cerium
diff TaskManager/Test/test_render/spe/DrawSpan.cpp @ 210:e75f9eb97180 draft
fix DrawSpan
author | gongo@localhost.localdomain |
---|---|
date | Fri, 30 Jan 2009 14:55:04 +0900 |
parents | de235e3ef9d3 |
children | 53cd9cf3ab99 |
line wrap: on
line diff
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp Fri Jan 30 09:57:32 2009 +0900 +++ b/TaskManager/Test/test_render/spe/DrawSpan.cpp Fri Jan 30 14:55:04 2009 +0900 @@ -7,11 +7,12 @@ #include "viewer_types.h" #include "Func.h" -#define SPAN_PACK_LOAD 0 -#define TEX_LOAD 1 -#define FB_STORE 2 +SchedDefineTask(DrawSpan); -SchedDefineTask(DrawSpan); +#define TEX_LOAD1 0 +#define TEX_LOAD2 1 +#define SPAN_PACK_LOAD 2 +#define FB_STORE 3 DrawSpan::~DrawSpan(void) { @@ -140,8 +141,8 @@ buf[i] = def; } #else - vector float init = {0.0f, 0.0f, 0.0f, 0.0f}; - vector float defi = {def, def, def, def}; + vector float init = spu_splats(0.0f); + vector float defi = spu_splats(def); for (int i = 0; i < width*height; i += 4) { vector float *out = (vector float *)&buf[i]; @@ -167,10 +168,14 @@ } void -DrawSpan::set_rgb(uint32 *addr) +DrawSpan::set_rgb(uint32 *addr, int tag) { TilePtr tile; + if (isAvailableTile(addr)) { + return; + } + tile = tileList->nextTile(); /** * FIFO なので、もし前のが残っていれば削除 @@ -179,23 +184,37 @@ tile->texture_addr = addr; - hash->put(tile->texture_addr, tile); - + int index = hash->put(tile->texture_addr, tile); smanager->dma_load(tile->pixel, (uint32)addr, - sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD); + sizeof(uint32)*TEXTURE_BLOCK_SIZE, tag); } +/** + * + */ void -DrawSpan::set_rgbs(uint32 *addr, uint32 *max_addr) +DrawSpan::set_rgbs(uint32 *cur_addr, uint32 *max_addr, int wait_tag) { - uint32 start = (uint32)addr; - uint32 end = (uint32)max_addr; - int length = (int)end-start; - int diff = sizeof(int)*TEXTURE_BLOCK_SIZE; - int max_tile = 16; + uint32 curp = (uint32)cur_addr; + uint32 maxp = (uint32)max_addr; + uint32 startp = curp; + uint32 diff = sizeof(int)*TEXTURE_BLOCK_SIZE; + int length = (int)maxp-(int)curp; + + int cmp = (length < 0); - for (int i = 0, j = 0; i <= length && j < max_tile; i += diff, j++) { - set_rgb((uint32*)(start + i)); +#if 1 + length += cmp*(-1)*length*2; + startp = cmp*maxp + !cmp*curp; +#else + if (length < 0) { + length = -length; + startp = maxp; + } +#endif + + for (int i = 0; i <= length; i += diff) { + set_rgb((uint32*)(startp + i), wait_tag); } } @@ -269,14 +288,35 @@ } /** + * zRow と Linebuf を更新する + * + * @param zpos 更新する pixel のZ座標 + * @param rangex このタスクが処理する描画領域の x の長さ + * @param x pixel の、描画領域内での x 座標 + * @param y 〃 の、y 座標 + * @param tex_x pixel が使用するテクスチャの、Tile (8x8) 内での x 座標 + * @param tex_y 〃 の y 座標 + * @param tex_addr テクスチャのアドレス(MainMemory) + */ +void +DrawSpan::updateBuffer(float zpos, int rangex, int x, int y, + int tex_x, int tex_y, uint32 *tex_addr) +{ + int rgb = get_rgb(tex_x, tex_y, tex_addr); + + zRow[x + (rangex*y)] = zpos; + linebuf[x + (rangex*y)] = rgb; +} + +/** * 長さが 1 の Span の描画 (要するに 1 pixel) * * @param span Span * @param startx 描画開始範囲 * @param endx 描画終了範囲 */ -void -DrawSpan::drawDot(SpanPtr span, int startx, int endx) +int +DrawSpan::drawDot1(SpanPtr span, int startx, int endx, int wait_tag) { int rangex = endx - startx + 1; @@ -303,7 +343,7 @@ uint32 *tex_addr; if (span->x < startx || endx < span->x) { - return; + return -1; } tex_xpos = (int)((span->tex_width-1) * tex); @@ -316,19 +356,26 @@ tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; if (!isAvailableTile(tex_addr)) { - set_rgb(tex_addr); - smanager->dma_wait(TEX_LOAD); + set_rgb(tex_addr, wait_tag); + smanager->dma_wait(wait_tag); + //return startx; } - int rgb = get_rgb(tex_localx, tex_localy, tex_addr); - - zRow[localx + (rangex*localy)] = zpos; - linebuf[localx + (rangex*localy)] = rgb; + updateBuffer(zpos, rangex, localx, localy, + tex_localx, tex_localy, tex_addr); } + + return -1; } void -DrawSpan::drawLine(SpanPtr span, int startx, int endx) +DrawSpan::drawDot2(SpanPtr span, int startx, int end, int js, int wait_tag) +{ + //printf("%d\n", js); +} + +int +DrawSpan::drawLine1(SpanPtr span, int startx, int endx, int wait_tag) { int x = span->x; int rangex = endx - startx + 1; @@ -355,6 +402,97 @@ // Tile 内での座標 int localx, localy = getLocalY(span->y-1); + int ret = je+1; + + //for (int j = js; j <= je; j++) { + for (int j = je; j >= js; j--) { + float tex_x, tex_y, tex_z; + + localx = getLocalX(x-1+j); + + tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); + + tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1); + tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1); + if (tex_x > 1) tex_x = 1; + if (tex_x < 0) tex_x = 0; + if (tex_y > 1) tex_y = 1; + if (tex_y < 0) tex_y = 0; + tex_xpos = (int)((span->tex_width-1) * tex_x); + tex_ypos = (int)((span->tex_height-1) * tex_y); + + if (tex_z < zRow[localx + (rangex*localy)]) { + // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と + // そのブロックのアドレス(MainMemory) + uint32 *tex_addr; + int tex_localx; + int tex_localy; + + tex_addr = getTile(tex_xpos, tex_ypos, + span->tex_width, span->tex_addr); + tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; + tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; + + set_rgb(tex_addr, wait_tag); + ret = j; + continue; + + if (!isAvailableTile(tex_addr)) { +#if 1 + tex_x = tex1*(x_len-1-js)/(x_len-1) + tex2*js/(x_len-1); + if (tex_x > 1) tex_x = 1; + if (tex_x < 0) tex_x = 0; + tex_xpos = (int)((span->tex_width-1) * tex_x); + + uint32 *max_addr = getTile(tex_xpos, tex_ypos, + span->tex_width, span->tex_addr); + + set_rgbs(tex_addr, max_addr, wait_tag); + return js; +#else + set_rgb(tex_addr, wait_tag); + ret = j; + //j -= 3; + continue; +#endif + } + + updateBuffer(tex_z, rangex, localx, localy, + tex_localx, tex_localy, tex_addr); + } + } + + return ret; +} + +void +DrawSpan::drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag) +{ + int x = span->x; + int rangex = endx - startx + 1; + int x_len = span->length_x; + + //int js = startx; + int je = (x + x_len > endx) ? endx - x : x_len; + + /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ + int tex_xpos, tex_ypos; + + // span の始点に対応する座標 (tex1, tey1) + float tex1 = span->tex_x1; + float tey1 = span->tex_y1; + + // span の終点に対応する座標 (tex2, tey2) + float tex2 = span->tex_x2; + float tey2 = span->tex_y2; + + // span の始点、終点に対応する z 座標 + float zpos1 = span->start_z; + float zpos2 = span->end_z; + + // Tile 内での座標 + int localx, localy = getLocalY(span->y-1); + // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と // そのブロックのアドレス(MainMemory) int tex_localx; @@ -363,7 +501,8 @@ float tex_x, tex_y, tex_z; -#if 0 + smanager->dma_wait(wait_tag); + for (int j = js; j <= je; j++) { localx = getLocalX(x-1+j); @@ -377,134 +516,17 @@ if (tex_y < 0) tex_y = 0; tex_xpos = (int)((span->tex_width-1) * tex_x); tex_ypos = (int)((span->tex_height-1) * tex_y); - + if (tex_z < zRow[localx + (rangex*localy)]) { tex_addr = getTile(tex_xpos, tex_ypos, span->tex_width, span->tex_addr); tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; - /** - * Tile が無い場合、一旦タスクはここで中断し、 - * Tile をロードするタスクを走らせた後に再起動する - */ - if (!isAvailableTile(tex_addr)) { - set_rgb(tex_addr); - smanager->dma_wait(TEX_LOAD); - } - - int rgb = get_rgb(tex_localx, tex_localy, tex_addr); - - zRow[localx + (rangex*localy)] = tex_z; - linebuf[localx + (rangex*localy)] = rgb; + updateBuffer(tex_z, rangex, localx, localy, + tex_localx, tex_localy, tex_addr); } - } -#else - for (int j = js; j <= je; j += 4) { - vector signed int vec_offset_i = {j, j+1, j+2, j+3}; - vector float vec_offset_f = {j, j+1, j+2, j+3}; - vector float len1 = spu_splats((float)(x_len-1)); - vector float len2 = spu_sub(len1, vec_offset_f); - - vector float vec_zpos1 = spu_splats(zpos1); - vector float vec_zpos2 = spu_splats(zpos2); - vector float vec_tex1 = spu_splats(tex1); - vector float vec_tex2 = spu_splats(tex2);; - vector float vec_tey1 = spu_splats(tey1); - vector float vec_tey2 = spu_splats(tey2); - - vector float vec_tex_x; - vector float vec_tex_y; - vector float vec_tex_z; - - // localx = getLocalX(x-1+j); - vector signed int vec_localx - = getLocalXVec(spu_add(spu_splats(x-1), vec_offset_i)); - vector signed int vec_localy = spu_splats(localy); - - // tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); - vec_tex_z = spu_madd(spu_mul(vec_zpos1, len2), spu_re_nrm(len1), - spu_mul(spu_mul(vec_zpos2, vec_offset_f), - spu_re_nrm(len1))); - - // tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1); - vec_tex_x = spu_madd(spu_mul(vec_tex1, len2), spu_re_nrm(len1), - spu_mul(spu_mul(vec_tex2, vec_offset_f), - spu_re_nrm(len1))); - - //tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1); - vec_tex_y = spu_madd(spu_mul(vec_tey1, len2), spu_re_nrm(len1), - spu_mul(spu_mul(vec_tey2, vec_offset_f), - spu_re_nrm(len1))); - -#if 0 - { - vector float ov1 = spu_splats(1.0f); - vector float ov0 = spu_splats(0.0f); - - // spu_cmpgt() true = 0xffffffff, false = 0x00000000 - vector unsigned int ovflag_1 = spu_cmpgt(vec_tex_x, ov1); - vector unsigned int ovflag_0 = spu_cmpgt(vec_tex_x, ov0); - - // *_t = 0xffffffff を 1 に変換 - // *_f = spu_cmpgt() の 論理否定 vector - // {0, 1, 0, 1} => {1, 0, 1, 0} - // *_t 同様 0xffffffff => 1 に変換 - vector signed int ovflag_1_t = spu_and(ovflag_1, 0x1); - vector signed int ovflag_1_f - = spu_and(spu_nor(ovflag_1, ovflag_1), 0x1); - - for (int h = 0; h < 4; h++) { - signed int fl = spu_extract(ovflag_1_f, h); - //float x = spu_extract((spu_mul(vec_tex_x, (vector float)ovflag_1_t)), h); - printf("[%d] %f %d\n", h, 3.3, fl); - } - - vector unsigned int ovflag_0_t = spu_and(ovflag_0, 0x1); - - //vec_tex_x = spu_add(spu_mul(ov1, (vector float)ovflag_1_t), - //spu_mul(vec_tex_x, (vector float)ovflag_1_f)); - //vec_tex_x = spu_mul(vec_tex_x, (vector float)ovflag_0_t); - } -#endif - int cnt = (je - j > 4) ? 4 : je - j + 1; - - for (int i = 0; i < cnt; i++) { - tex_x = spu_extract(vec_tex_x, i); - tex_y = spu_extract(vec_tex_y, i); - tex_z = spu_extract(vec_tex_z, i); - localx = spu_extract(vec_localx, i); - - if (tex_x > 1) tex_x = 1; - if (tex_x < 0) tex_x = 0; - if (tex_y > 1) tex_y = 1; - if (tex_y < 0) tex_y = 0; - tex_xpos = (int)((span->tex_width-1) * tex_x); - tex_ypos = (int)((span->tex_height-1) * tex_y); - - if (tex_z < zRow[localx + (rangex*localy)]) { - tex_addr = getTile(tex_xpos, tex_ypos, - span->tex_width, span->tex_addr); - tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; - tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; - - /** - * Tile が無い場合、一旦タスクはここで中断し、 - * Tile をロードするタスクを走らせた後に再起動する - */ - if (!isAvailableTile(tex_addr)) { - set_rgb(tex_addr); - smanager->dma_wait(TEX_LOAD); - } - - int rgb = get_rgb(tex_localx, tex_localy, tex_addr); - - zRow[localx + (rangex*localy)] = tex_z; - linebuf[localx + (rangex*localy)] = rgb; - } - } - } -#endif + } } int @@ -515,15 +537,22 @@ SpanPackPtr free_spack = next_spack; // next_spack の free() 用 Span *span; - void (DrawSpan::*drawFunc[2])(SpanPtr, int, int) = { - &DrawSpan::drawDot, &DrawSpan::drawLine + Span nop_span; + nop_span.length_x = 1; + + int (DrawSpan::*drawFunc1[2])(SpanPtr, int, int, int) = { + &DrawSpan::drawDot1, &DrawSpan::drawLine1 + }; + + void (DrawSpan::*drawFunc2[2])(SpanPtr, int, int, int, int) = { + &DrawSpan::drawDot2, &DrawSpan::drawLine2 }; uint32 display = smanager->get_param(0); int screen_width = smanager->get_param(1); int rangex_start = smanager->get_param(2); int rangex_end = smanager->get_param(3); - + // このタスクが担当する x の範囲 int rangex = rangex_end - rangex_start + 1; @@ -537,6 +566,10 @@ linebuf = linebuf_init(rangex, rangey, 0x00ffffff); doneWrite = 0; + + int tl_tag[2] = {TEX_LOAD1, TEX_LOAD2}; + int tl_tag_flg1 = 0; + int tl_tag_flg2 = 1; do { /** @@ -551,13 +584,36 @@ next_spack = NULL; } + SpanPtr resume_span = &nop_span; + int resume_span_x = 0; + for (int t = 0; t < spack->info.size; t++) { + SpanPtr next_span; + int next_span_x; + span = &spack->span[t]; - int x_len = span->length_x; + next_span_x + = (this->*drawFunc1[(span->length_x != 1)])( + span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]); + next_span = span; + + (this->*drawFunc2[(resume_span->length_x != 1)])( + resume_span, rangex_start, rangex_end, resume_span_x, + tl_tag[tl_tag_flg2]); - (this->*drawFunc[(x_len != 1)])(span, rangex_start, rangex_end); + resume_span = next_span; + resume_span_x = next_span_x; + + //smanager->dma_wait(tl_tag[tl_tag_flg1]); + + tl_tag_flg1 ^= 1; + tl_tag_flg2 ^= 1; } + + (this->*drawFunc2[(resume_span->length_x != 1)])( + resume_span, rangex_start, rangex_end, resume_span_x, + tl_tag[tl_tag_flg1]); smanager->dma_wait(SPAN_PACK_LOAD); @@ -573,12 +629,12 @@ //free(linebuf); free(zRow); -FINISH: +//FINISH: /** * goto FINISH; の時は reboot なので * linebuf, zRow は free() しない */ + free(free_spack); - return 0; }