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;