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, &param[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;
 }