Mercurial > hg > Game > Cerium
changeset 1163:b417abf82193 draft
use Segment API for spackload
author | Yutaka_Kinjyo |
---|---|
date | Tue, 10 May 2011 14:58:24 +0900 |
parents | 8917aff8629c |
children | d7637cb85bd8 |
files | Renderer/Engine/Makefile.def Renderer/Engine/global_alloc.h Renderer/Engine/task/CreateSpan.cc Renderer/Engine/task/CreateSpan.h Renderer/Engine/task/DrawSpan.cc Renderer/Engine/viewer.cc Renderer/Test/Makefile.def TaskManager/Makefile.def TaskManager/kernel/schedule/Scheduler.cc |
diffstat | 9 files changed, 272 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/Makefile.def Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/Makefile.def Tue May 10 14:58:24 2011 +0900 @@ -5,8 +5,10 @@ ABIBIT = 64 ABI = -m$(ABIBIT) CC = g++ -OPT = -DUSE_SEGMENT -DUSE_TASKARRAY -DUSE_PIPELINE -g #-O9 # -#OPT = -O9 -DUSE_TASKARRAY -DUSE_PIPELINE -g +#OPT = -g -DUSE_TASKARRAY -DUSE_PIPELINE -DUSE_SEGMENT +OPT = -O9 -DUSE_TASKARRAY -DUSE_PIPELINE -DUSE_SEGMENT + + CFLAGS = -Wall $(ABI) $(OPT) # -DDEBUG
--- a/Renderer/Engine/global_alloc.h Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/global_alloc.h Tue May 10 14:58:24 2011 +0900 @@ -8,6 +8,7 @@ GLOBAL_TEXTURE_HASH, GLOBAL_TILE_LIST, GLOBAL_POLYGONPACK_LIST, + GLOBAL_SPANPACK_LIST, KEY_STATUS, LOAD_ID,
--- a/Renderer/Engine/task/CreateSpan.cc Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/task/CreateSpan.cc Tue May 10 14:58:24 2011 +0900 @@ -18,6 +18,7 @@ static SpanPackPtr send_spack = NULL; static int prev_index = 0; + SchedDefineTask(CreateSpan); static float @@ -205,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; @@ -219,6 +226,7 @@ float start_tex_x, end_tex_x, start_tex_y, end_tex_y; int x, y, length; + #if 1 // これじゃないと // テクスチャの貼りに微妙に隙間が。謎だ @@ -232,8 +240,15 @@ int k = 0; int l = 1; +#ifdef USE_SEGMENT + + +#else + SpanPackPtr tmp_spack; +#endif + /** * 三角形ポリゴンをx軸に水平に二つに分けようとして * ある一辺がすでに水平だった場合、つまり @@ -285,44 +300,84 @@ * 現在の 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; - - /* - smanager->wait_segment(prev_ms); - send_ms = smanager->put_segment(); - smanager->put_segment(cur_ms); - cur_ms = smanager->get_segment((memaddr)spackList[index], ml); - smanager->wait_segment(cur_ms); - - */ 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; @@ -331,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 { /** @@ -386,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++]; @@ -399,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; @@ -454,16 +518,21 @@ そうすると、Task の input , output のデータの大きさはスケーラブルになるのか。 */ + PolygonPack *pp = (PolygonPack*)smanager->get_input(rbuf, 0); + #ifdef USE_SEGMENT - int stock_num = 2; //2つの領域を使い回すイメージで。最初、rbufのinputで受けてるけど、これどうなん? - // global に取った。 このListどうやって消してやろうか。 - MemList *ml = (MemList*)smanager->global_get(GLOBAL_POLYGONPACK_LIST); - MemorySegmentPtr ms; //Tileみたいに typedef したほうがいいのか。でもPolygonPackはすでに使われてるし。 + // global に取ってみた。いづれはひとつにまとめて、サイズを可変にするのかね。 + MemList *pp_ml = (MemList*)smanager->global_get(GLOBAL_POLYGONPACK_LIST); + MemList *span_ml = (MemList*)smanager->global_get(GLOBAL_SPANPACK_LIST); - PolygonPackPtr next_pp; + MemorySegmentPtr pp_ms = NULL; //Tileみたいに typedef したほうがいいのか。でもPolygonPackはすでに使われてるし。 + PolygonPackPtr next_pp = NULL; + + MemorySegmentPtr span_put_ms = NULL; + MemorySegmentPtr span_get_ms = NULL; #else @@ -481,10 +550,25 @@ = (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); + +#endif + + // spack と send_spack は swap しながら DMA を繰り返すので // 自分で allocate した send_spack を覚えてないといけない SpanPackPtr free_spack = send_spack; @@ -493,8 +577,6 @@ int charge_y_end = (long)smanager->get_param(2); - - do { if (pp->next != NULL) { @@ -502,13 +584,10 @@ #ifdef USE_SEGMENT /* - - Segmentの数は2つにしてそれを交互に使っている。 - ユーザはそれを意識しなくていいから、使いやすいなこれ。 - + Segmentの数は2つにしてその領域のアドレスが交互に返される */ - ms = smanager->get_segment((memaddr)pp->next, ml); + pp_ms = smanager->get_segment((memaddr)pp->next, pp_ml); #else @@ -517,7 +596,18 @@ #endif } else { + + +#ifdef USE_SEGMENT + + pp_ms = NULL; + +#else next_pp = NULL; + +#endif + + } for (int i = 0; i < pp->info.size; i++) { @@ -548,28 +638,52 @@ * (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 (next_pp != NULL) { - smanager->wait_segment(ms); - pp = (PolygonPackPtr)ms->data; + if (pp_ms != NULL) { + smanager->wait_segment(pp_ms); + pp = (PolygonPackPtr)pp_ms->data; } else { pp = NULL; } - + #else smanager->dma_wait(POLYGON_PACK_LOAD); @@ -584,19 +698,24 @@ } while (pp); - /* + +#ifdef USE_SEGMENT - smanager->wait_segment(spack); - smanager->put_segment(spackList[prev_index], g->spanList); - smanager->wait_segment(spack); + 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); smanager->dma_wait(SPAN_PACK_STORE); + +#endif + #ifdef USE_SEGMENT // Global でSegmentとったので、いつか解放しないといかないなぁ。
--- a/Renderer/Engine/task/CreateSpan.h Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/task/CreateSpan.h Tue May 10 14:58:24 2011 +0900 @@ -5,11 +5,6 @@ #include "polygon_pack.h" #include "SpanPack.h" -static void half_triangle(SchedTask *smanager, SpanPackPtr *spackList, - int charge_y_top, int charge_y_end, - TriangleTexInfoPtr tex_info, - VertexPack *vMin,VertexPack *vMid,VertexPack *vMid1, - NormalPack *normal1, NormalPack *normal2, NormalPack *normal3, - int length_y, float tex_y_len); + #endif
--- a/Renderer/Engine/task/DrawSpan.cc Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/task/DrawSpan.cc Tue May 10 14:58:24 2011 +0900 @@ -328,6 +328,9 @@ drawLine1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag) { + +#ifdef PIPE_TILE + int cur = 0; DrawParam param[2]; @@ -341,6 +344,7 @@ int ret = je+1; int index = 1; + getDrawParam(smanager, g, span, localy, startx, endx, index, je, ¶m[cur]); //for (int j = je; j >= js; j--) { <-もとはこうで、一度先にtextureをloadしておくから、je-1にしてる @@ -374,6 +378,95 @@ } */ + +#else + + + int x = span->x; + int rangex = endx - startx + 1; + int x_len = span->length_x; + + float normal_x = span->normal_x; + 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 の始点に対応する座標 (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; + + //spanを右から左に見ていくうちに、zが下がるのか、上がっていくのか。 + float z_inclination = (zpos2 - zpos1) / x_len; + float world_z = zpos2; + + // 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_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); + + 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; + int tex_localx; + int tex_localy; + + if (!span->tex_addr) return -1; // broken case, I'd like to write some thing... + tex_addr = getTile(tex_xpos, tex_ypos, + span->tex_width, (memaddr)span->tex_addr); + tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; + tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; + + TilePtr tile = smanager->get_segment(tex_addr,g->tileList); + smanager->wait_segment(tile); + + updateBuffer(g, tex_z, rangex, localx, localy, + tex_localx, tex_localy, + normal_x, normal_y, normal_z, tile, + span->x+j, span->y, world_z, smanager); + } + } + + + +#endif + return ret; }
--- a/Renderer/Engine/viewer.cc Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Engine/viewer.cc Tue May 10 14:58:24 2011 +0900 @@ -31,10 +31,6 @@ int ppi, spi = 0; -/** - * - */ - Viewer::Viewer(TaskManager *m, ViewerDevice *vd, int b, int w, int h, int _num) { spe_num = _num; @@ -148,6 +144,15 @@ HTaskPtr task_next; HTaskPtr task_tex; + /* + + こうかな + + manager->createMemList(sizeof(SpanPack), POOL_SPANPACK); + + + */ + for(int i=0;i<2;i++) {
--- a/Renderer/Test/Makefile.def Thu May 05 13:11:59 2011 +0900 +++ b/Renderer/Test/Makefile.def Tue May 10 14:58:24 2011 +0900 @@ -4,8 +4,10 @@ ABIBIT = 64 ABI = -m$(ABIBIT) CC = g++ +#CFLAGS = -Wall $(ABI) -g CFLAGS = -Wall $(ABI) -O9 #-g # -O -DDEBUG + INCLUDE = -I$(CERIUM)/include/TaskManager -I$(CERIUM)/Renderer/Engine -I. -I$(CERIUM)/include/Cerium LIBS = -L$(CERIUM)/TaskManager -L$(CERIUM)/Renderer/Engine $(ABI) TOOL = $(CERIUM)/bin
--- a/TaskManager/Makefile.def Thu May 05 13:11:59 2011 +0900 +++ b/TaskManager/Makefile.def Tue May 10 14:58:24 2011 +0900 @@ -29,8 +29,9 @@ ABIBIT = 64 -OPT = -g -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE -#OPT = -g #-DMAIL_QUEUE -DNOT_CHECK#-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE +#OPT = -g -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE +OPT = -O9 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE + CC = g++
--- a/TaskManager/kernel/schedule/Scheduler.cc Thu May 05 13:11:59 2011 +0900 +++ b/TaskManager/kernel/schedule/Scheduler.cc Tue May 10 14:58:24 2011 +0900 @@ -412,6 +412,7 @@ MemorySegment *s = m->getLast(); m->moveToFirst(s); s->tag = get_tag(); + s->address = addr; dma_load(s->data, addr, s->size, s->tag); return s; @@ -480,6 +481,8 @@ void Scheduler::put_segment(MemorySegment *s) { + + if (s == NULL) return; s->tag = get_tag(); dma_store(s->data, s->address, s->size, s->tag); @@ -497,6 +500,7 @@ { // えーと、dma してない時には、skip しないとだめなんじゃないの? + if (s == NULL) return; if (s->tag) dma_wait(s->tag); s->tag = 0; }