Mercurial > hg > Game > Cerium
changeset 1164:d7637cb85bd8 draft
minor change
author | yutaka@charles.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Mon, 09 May 2011 16:29:30 +0900 |
parents | b417abf82193 |
children | ab8ed4d1d211 |
files | Renderer/Engine/Makefile.def Renderer/Engine/spe/AllocateSegment.cc Renderer/Engine/spe/CreateSpan.cc Renderer/Engine/spe/DrawSpan.cc Renderer/Engine/task/AllocateSegment.cc Renderer/Engine/task/CreateSpan.cc |
diffstat | 6 files changed, 256 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/Makefile.def Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/Makefile.def Mon May 09 16:29:30 2011 +0900 @@ -6,9 +6,7 @@ ABI = -m$(ABIBIT) CC = g++ #OPT = -g -DUSE_TASKARRAY -DUSE_PIPELINE -DUSE_SEGMENT -OPT = -O9 -DUSE_TASKARRAY -DUSE_PIPELINE -DUSE_SEGMENT - - +OPT = -O9 -DUSE_TASKARRAY -DUSE_PIPELINE #-DUSE_SEGMENT CFLAGS = -Wall $(ABI) $(OPT) # -DDEBUG
--- a/Renderer/Engine/spe/AllocateSegment.cc Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/spe/AllocateSegment.cc Mon May 09 16:29:30 2011 +0900 @@ -5,12 +5,15 @@ #include "Func.h" #include "Tapestry.h" #include "polygon_pack.h" +#include "SpanPack.h" SchedDefineTask(AllocateSegment); /** * 各種 MemorySegment の用意はここでするのか? - * + * いづれは、MemorySegment は大きく最初にガバっと領域を確保 + * MemorySegment は可変な大きさになって、要求したサイズだけ、poolから領域を与える。。 + * みたいな感じか。Cell以外のアーキテクチャではどうなんだろう。Segmentを管理ってのは必須なのか */ static int @@ -19,8 +22,17 @@ MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE); smanager->global_set(GLOBAL_TILE_LIST, (void *)ml); -// ml = smanager->createMemList(sizeof(PolygonPack), MAX_POLYGON); -// smanager->global_set(GLOBAL_POLYGONPACK_LIST, (void *)ml); + /*LSに入らないみたい。Code Load やるか*/ + +#ifdef USE_SEGMENT + + ml = smanager->createMemList(sizeof(PolygonPack), POLYGONPACK_SEGMENT_NUM); + smanager->global_set(GLOBAL_POLYGONPACK_LIST, (void *)ml); + + ml = smanager->createMemList(sizeof(SpanPack), SPANPACK_SEGMENT_NUM); + smanager->global_set(GLOBAL_SPANPACK_LIST, (void *)ml); + +#endif return 0; }
--- a/Renderer/Engine/spe/CreateSpan.cc Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/spe/CreateSpan.cc Mon May 09 16:29:30 2011 +0900 @@ -3,6 +3,8 @@ #include "viewer_types.h" #include "matrix_calc.h" #include "Tapestry.h" +#include "Func.h" + // DMA channel static const int SPAN_PACK_LOAD = 5; @@ -16,6 +18,7 @@ static SpanPackPtr send_spack = NULL; static int prev_index = 0; + SchedDefineTask(CreateSpan); static float @@ -203,12 +206,18 @@ * @param[in] tex_y_len 分割する前の Triangle に貼られている Texture の * 長さの割合 (0 ... 1) */ + static void half_triangle(SchedTask *smanager, SpanPackPtr *spackList, int charge_y_top, int charge_y_end, TriangleTexInfoPtr tex_info, VertexPack *vMin,VertexPack *vMid,VertexPack *vMid10, NormalPack *normal1, NormalPack *normal2, NormalPack *normal3, +#ifdef USE_SEGMENT + /* いや、こういう区切り方は反則か*/ + MemorySegmentPtr &span_get_ms, MemorySegmentPtr &span_put_ms, + MemList *span_ml, +#endif int length_y, float tex_y_len) { float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2; @@ -217,6 +226,7 @@ float start_tex_x, end_tex_x, start_tex_y, end_tex_y; int x, y, length; + #if 1 // これじゃないと // テクスチャの貼りに微妙に隙間が。謎だ @@ -230,8 +240,15 @@ int k = 0; int l = 1; +#ifdef USE_SEGMENT + + +#else + SpanPackPtr tmp_spack; +#endif + /** * 三角形ポリゴンをx軸に水平に二つに分けようとして * ある一辺がすでに水平だった場合、つまり @@ -283,7 +300,24 @@ * 現在の SpanPack をメインメモリに送り、 * 新しい SpanPack を取ってくる */ + if (index != prev_index) { + +#ifdef USE_SEGMENT + + smanager->wait_segment(span_put_ms); + + span_put_ms = span_get_ms; + smanager->put_segment(span_put_ms); + + span_get_ms = smanager->get_segment((memaddr)spackList[index], span_ml); + smanager->wait_segment(span_get_ms); + + prev_index = index; + spack = (SpanPackPtr)span_get_ms->data; + +#else + tmp_spack = spack; spack = send_spack; send_spack = tmp_spack; @@ -291,27 +325,59 @@ smanager->dma_wait(SPAN_PACK_STORE); smanager->dma_store(send_spack, (memaddr)spackList[prev_index], sizeof(SpanPack), SPAN_PACK_STORE); - + smanager->dma_load(spack, (memaddr)spackList[index], sizeof(SpanPack), SPAN_PACK_LOAD); + prev_index = index; smanager->dma_wait(SPAN_PACK_LOAD); + +#endif + } /** * 書き込む SpanPack が満杯だったら * メインメモリで allocate した領域 (next) を持ってきて * 現在の spack->next につなぎ、next を次の spack とする。 + * + * ------------------------------------------------------- + * + * ここどうすっかね。予め、Spanの大きさは予測できるけど、それで毎回SpanPack + * allocate するのってはもうやめようって話だよな。Mail Memory 側に ある程度の大きさの + * Segment領域を確保して、それをsegmentのAPIでやり取りするのが嬉しいのかね。 + * + * mainMem 追い出すには、ちょっと苦労するかも? */ + if (spack->info.size >= MAX_SIZE_SPAN) { SpanPackPtr next; + smanager->mainMem_alloc(0, sizeof(SpanPack)); smanager->mainMem_wait(); next = (SpanPackPtr)smanager->mainMem_get(0); spack->next = next; + +#ifdef USE_SEGMENT + + smanager->wait_segment(span_put_ms); + + span_put_ms = span_get_ms; + smanager->put_segment(span_put_ms); + + spackList[index] = next; + span_get_ms = smanager->get_segment((memaddr)spackList[index],span_ml); + smanager->wait_segment(span_get_ms); + + spack = (SpanPackPtr)span_get_ms->data; + spack->init((index+1)*split_screen_h); + +#else + + tmp_spack = spack; spack = send_spack; send_spack = tmp_spack; @@ -320,12 +386,17 @@ smanager->dma_store(send_spack, (memaddr)spackList[index], sizeof(SpanPack), SPAN_PACK_STORE); + spackList[index] = next; + smanager->dma_load(spack, (memaddr)spackList[index], sizeof(SpanPack), SPAN_PACK_LOAD); smanager->dma_wait(SPAN_PACK_LOAD); spack->init((index+1)*split_screen_h); + +#endif + } } else { /** @@ -375,6 +446,8 @@ end_tex_y = tmp_tey2; } + // ここいる? load してその後必ず、wait してるように見える。 + // この wait に対応しているloadはないはずだ・・・きっと。 smanager->dma_wait(SPAN_PACK_LOAD); Span *span = &spack->span[spack->info.size++]; @@ -388,10 +461,12 @@ span->tex_x2 = end_tex_x; span->tex_y1 = start_tex_y; span->tex_y2 = end_tex_y; - /*ここで頂点分法線ベクトルがあったんだけど、 - * 一つだけ取り出して、spanに一つの法線ベクトルを持たしている - *by yutaka + + /* + * ここで頂点分法線ベクトルがあったんだけど、 + * 一つだけ取り出して、spanに一つの法線ベクトルを持たしている */ + span->normal_x = normal1->x; span->normal_y = normal1->y; span->normal_z = normal1->z; @@ -433,35 +508,104 @@ static int run(SchedTask *smanager, void *rbuf, void *wbuf) { + /* + + get_segmentを使うと、input buffer からの入力は要らなくなる + Task化するなら、get_segment は取り去る。 + 途中でloadが入ってるのは DMA転送のサイズの限界と、SPEのLSの容量の少なさにある + 必要なときに、必要な分だけ load するのは、自動的にやってほしいから、get_segment も + いづれは、Task の内部で処理されるものになるのかな。 + そうすると、Task の input , output のデータの大きさはスケーラブルになるのか。 + + */ + PolygonPack *pp = (PolygonPack*)smanager->get_input(rbuf, 0); + + +#ifdef USE_SEGMENT + + // global に取ってみた。いづれはひとつにまとめて、サイズを可変にするのかね。 + MemList *pp_ml = (MemList*)smanager->global_get(GLOBAL_POLYGONPACK_LIST); + MemList *span_ml = (MemList*)smanager->global_get(GLOBAL_SPANPACK_LIST); + + MemorySegmentPtr pp_ms = NULL; //Tileみたいに typedef したほうがいいのか。でもPolygonPackはすでに使われてるし。 + + MemorySegmentPtr span_put_ms = NULL; + MemorySegmentPtr span_get_ms = NULL; + +#else + PolygonPack *next_pp = (PolygonPack*)smanager->allocate(sizeof(PolygonPack)); + PolygonPack *free_pp = next_pp; PolygonPack *tmp_pp; +#endif + TrianglePackPtr triPack; VertexPackPtr vMin, vMid, vMax; VertexPackPtr vMid10 = (VertexPackPtr)smanager->allocate(sizeof(VertexPack)); NormalPackPtr normal1,normal2, normal3; SpanPackPtr *spackList = (SpanPackPtr*)smanager->get_input(rbuf, 1); - spack = (SpanPackPtr)smanager->get_input(rbuf, 2); + send_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); prev_index = (long)smanager->get_param(0); + +#ifdef USE_SEGMENT + + /*rbuf2 はspackList[prev_index]と一緒なんだけど、この書き方は微妙ね*/ + span_get_ms = smanager->get_segment((memaddr)spackList[prev_index], span_ml); + smanager->wait_segment(span_get_ms); + spack = (SpanPackPtr)span_get_ms->data; + +#else + + spack = (SpanPackPtr)smanager->get_input(rbuf, 2); + // spack と send_spack は swap しながら DMA を繰り返すので // 自分で allocate した send_spack を覚えてないといけない SpanPackPtr free_spack = send_spack; + +#endif + int charge_y_top = (long)smanager->get_param(1); int charge_y_end = (long)smanager->get_param(2); do { if (pp->next != NULL) { + + +#ifdef USE_SEGMENT + + /* + Segmentの数は2つにしてその領域のアドレスが交互に返される + */ + + pp_ms = smanager->get_segment((memaddr)pp->next, pp_ml); + +#else + smanager->dma_load(next_pp, (memaddr)pp->next, sizeof(PolygonPack), POLYGON_PACK_LOAD); +#endif + } else { + + +#ifdef USE_SEGMENT + + pp_ms = NULL; + +#else next_pp = NULL; + +#endif + + } for (int i = 0; i < pp->info.size; i++) { @@ -492,30 +636,95 @@ * (vMax, vMid, vMid10) (vMin, vMid, vMid10) という * 二つの Triangle に分けている */ + +#ifdef USE_SEGMENT + + half_triangle(smanager, spackList, charge_y_top, charge_y_end, + tri_tex_info, vMin, vMid, vMid10, + normal1,normal2,normal3, + span_get_ms, span_put_ms, + span_ml, + (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); + + half_triangle(smanager, spackList, charge_y_top, charge_y_end, + tri_tex_info, vMax, vMid, vMid10, + normal1,normal2,normal3, + span_get_ms, span_put_ms, + span_ml, + (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); + +#else + half_triangle(smanager, spackList, charge_y_top, charge_y_end, tri_tex_info, vMin, vMid, vMid10, normal1,normal2,normal3, (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); + half_triangle(smanager, spackList, charge_y_top, charge_y_end, tri_tex_info, vMax, vMid, vMid10, normal1,normal2,normal3, (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); + + +#endif + } +#ifdef USE_SEGMENT + + + // うーん + + if (pp_ms != NULL) { + smanager->wait_segment(pp_ms); + pp = (PolygonPackPtr)pp_ms->data; + } else { + pp = NULL; + } + +#else + smanager->dma_wait(POLYGON_PACK_LOAD); tmp_pp = pp; pp = next_pp; next_pp = tmp_pp; + + +#endif + + } while (pp); + +#ifdef USE_SEGMENT + + smanager->wait_segment(span_put_ms); + span_put_ms = span_get_ms; + smanager->put_segment(span_put_ms); + smanager->wait_segment(span_put_ms); + +#else + smanager->dma_wait(SPAN_PACK_STORE); smanager->dma_store(spack, (memaddr)spackList[prev_index], - sizeof(SpanPack), SPAN_PACK_STORE); + sizeof(SpanPack), SPAN_PACK_STORE); smanager->dma_wait(SPAN_PACK_STORE); + +#endif + +#ifdef USE_SEGMENT + + // Global でSegmentとったので、いつか解放しないといかないなぁ。 + +#else + free(free_pp); free(free_spack); + +#endif + free(vMid10); return 0;
--- a/Renderer/Engine/spe/DrawSpan.cc Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/spe/DrawSpan.cc Mon May 09 16:29:30 2011 +0900 @@ -316,8 +316,6 @@ } #endif - - /** * 長さが 1 より大きい Span の描画 * @@ -346,9 +344,13 @@ float normal_y = span->normal_y; float normal_z = span->normal_z; + int js = (x < startx) ? startx - x : 0; 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; @@ -372,31 +374,24 @@ //for (int j = js; j <= je; j++) { for (int j = je; j >= js; j--) { - - float tex_z; + float tex_x, tex_y, tex_z; world_z -= z_inclination; + 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 < g->zRow[localx + (rangex*localy)]) { - - float tex_x, tex_y; - - 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; - - /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ - int tex_xpos, tex_ypos; - - tex_xpos = (int)((span->tex_width-1) * tex_x); - tex_ypos = (int)((span->tex_height-1) * tex_y); - // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と // そのブロックのアドレス(MainMemory) memaddr tex_addr;
--- a/Renderer/Engine/task/AllocateSegment.cc Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/task/AllocateSegment.cc Mon May 09 16:29:30 2011 +0900 @@ -22,12 +22,17 @@ MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE); smanager->global_set(GLOBAL_TILE_LIST, (void *)ml); + /*LSに入らないみたい。Code Load やるか*/ + +#ifdef USE_SEGMENT + ml = smanager->createMemList(sizeof(PolygonPack), POLYGONPACK_SEGMENT_NUM); smanager->global_set(GLOBAL_POLYGONPACK_LIST, (void *)ml); ml = smanager->createMemList(sizeof(SpanPack), SPANPACK_SEGMENT_NUM); smanager->global_set(GLOBAL_SPANPACK_LIST, (void *)ml); +#endif return 0; }
--- a/Renderer/Engine/task/CreateSpan.cc Tue May 10 14:58:24 2011 +0900 +++ b/Renderer/Engine/task/CreateSpan.cc Mon May 09 16:29:30 2011 +0900 @@ -529,7 +529,6 @@ MemList *span_ml = (MemList*)smanager->global_get(GLOBAL_SPANPACK_LIST); MemorySegmentPtr pp_ms = NULL; //Tileみたいに typedef したほうがいいのか。でもPolygonPackはすでに使われてるし。 - PolygonPackPtr next_pp = NULL; MemorySegmentPtr span_put_ms = NULL; MemorySegmentPtr span_get_ms = NULL; @@ -566,17 +565,16 @@ spack = (SpanPackPtr)smanager->get_input(rbuf, 2); -#endif - - // spack と send_spack は swap しながら DMA を繰り返すので // 自分で allocate した send_spack を覚えてないといけない SpanPackPtr free_spack = send_spack; + +#endif + int charge_y_top = (long)smanager->get_param(1); int charge_y_end = (long)smanager->get_param(2); - do { if (pp->next != NULL) { @@ -723,10 +721,10 @@ #else free(free_pp); + free(free_spack); #endif - free(free_spack); free(vMid10); return 0;