diff TaskManager/Test/test_render/task/DrawSpan.cpp @ 233:d734af296d38

fix
author gongo@localhost.localdomain
date Sun, 29 Mar 2009 21:13:17 +0900
parents 401b55a4a4dd
children 7578005fb76b
line wrap: on
line diff
--- a/TaskManager/Test/test_render/task/DrawSpan.cpp	Tue Feb 24 15:28:51 2009 +0900
+++ b/TaskManager/Test/test_render/task/DrawSpan.cpp	Sun Mar 29 21:13:17 2009 +0900
@@ -1,5 +1,6 @@
 #include <stdlib.h>
 #include <string.h>
+#include <spu_intrinsics.h>
 #include "DrawSpan.h"
 #include "polygon_pack.h"
 #include "texture.h"
@@ -19,6 +20,31 @@
     free((void*)((int)linebuf*doneWrite));
 }
 
+inline vector float
+spu_re_nrm(vector float a)
+{
+    vector float unit = (vector float){1.0, 1.0, 1.0, 1.0};
+    vector float approximation;
+
+    approximation = spu_re(a);
+    return spu_madd(spu_nmsub(approximation, a, unit),
+                    approximation, approximation);
+}
+
+
+vector signed int
+getLocalPositionVec(vector signed int d, signed int offset)
+{
+    return spu_and(d, spu_splats(offset-1));
+}
+
+vector signed int
+getLocalXVec(vector signed int x)
+{
+    return getLocalPositionVec(x, split_screen_w);
+}
+
+
 /**
  * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
  *
@@ -110,9 +136,20 @@
     float *buf = (float*)smanager->allocate(sizeof(float)*width*height);
     float def = 65535.0f;
 
+#if 0
     for (int i = 0; i < width*height; i++) {
 	buf[i] = def;
     }
+#else 
+    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];
+
+	*out = spu_add(init, defi);
+    }
+#endif
 
     return buf;
 }
@@ -148,9 +185,6 @@
     tile->texture_addr = addr;
     
     int index = hash->put(tile->texture_addr, tile);
-    if (index < 0) {
-	printf("haosa\n");
-    }
     smanager->dma_load(tile->pixel, (uint32)addr,
 		       sizeof(uint32)*TEXTURE_BLOCK_SIZE, tag);
 }
@@ -315,8 +349,7 @@
     tex_xpos = (int)((span->tex_width-1) * tex);
     tex_ypos = (int)((span->tex_height-1) * tey);
 
-    if (0 < zpos && zpos < zRow[localx + (rangex*localy)]) {
-	//if (zpos < zRow[localx + (rangex*localy)]) {
+    if (zpos < zRow[localx + (rangex*localy)]) {
 	tex_addr = getTile(tex_xpos, tex_ypos,
 			   span->tex_width, span->tex_addr);
 	tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
@@ -341,6 +374,23 @@
     //printf("%d\n", js);
 }
 
+/**
+ * 長さが 1 より大きい Span の描画
+ *
+ * 本来の目的として、この関数(drawLine1) では
+ *   : 既に SPE 上に Tile のある pixel だけ描画
+ *   : それ以外は、ここで予め DMA load しておき、
+ *   : drawLine2 で一気に描画する
+ * ってものだったんだけど、どうも上手く行かなかったので
+ * 今は drawLine1 で load -> wait -> rendering を全部やってます
+ * (rendering といっても、rendering buffer に書き込むだけで
+ *  まだ main memory (frame buffer) に dma store してるわけではない)
+ *      
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @return 「span のどの位置まで rendering が終わったか」の x 座標
+ */
 int
 DrawSpan::drawLine1(SpanPtr span, int startx, int endx, int wait_tag)
 {
@@ -376,36 +426,35 @@
 	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 (0 < tex_z && tex_z < zRow[localx + (rangex*localy)]) {
-	    //if (tex_z < zRow[localx + (rangex*localy)]) {
+	if (tex_z < zRow[localx + (rangex*localy)]) {
 	    // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
 	    // そのブロックのアドレス(MainMemory)
 	    uint32 *tex_addr;
 	    int tex_localx;
 	    int tex_localy;
 
-	    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);
-
 	    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 0
+		// span が必要とするであろう tile を予想紙
+		// set_rgbs で複数同時に load しようとしている図
+		// まあ上手くいかなかったんだけど。。
 		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;
@@ -418,9 +467,7 @@
 		return js;
 #else
 		set_rgb(tex_addr, wait_tag);
-		//ret = j;
 		smanager->dma_wait(wait_tag);
-		//continue;
 #endif
 	    }
 
@@ -432,6 +479,17 @@
     return ret;
 }
 
+/**
+ * 長さが 1 より大きい Span の描画 (2段階目)
+ *
+ * 上にあるように、drawLine2 は今は動いてないです
+ * 正確には、js が startx ~ endx 範囲外にあり開始されないってところ
+ *
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @param js 前回(drawLine1) で span のどこまで終わっているか
+ */
 void
 DrawSpan::drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag)
 {
@@ -484,8 +542,7 @@
 	tex_xpos = (int)((span->tex_width-1) * tex_x);
 	tex_ypos = (int)((span->tex_height-1) * tex_y);
 
-	if (0 < tex_z && tex_z < zRow[localx + (rangex*localy)]) {
-	    //if (tex_z < zRow[localx + (rangex*localy)]) {
+	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;
@@ -531,7 +588,7 @@
     tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
 
     zRow = zRow_init(rangex, rangey);
-    //linebuf = linebuf_init(rangex, rangey, 0xffffffff);
+    //linebuf = linebuf_init(rangex, rangey, 0x00ffffff);
     linebuf = linebuf_init(rangex, rangey, 0);
 
     doneWrite = 0;
@@ -562,6 +619,9 @@
 
 	    span = &spack->span[t];
 
+	    /**
+	     * span の長さによって、drawLine か drawDot を選択している
+	     */ 
 	    next_span_x
 		= (this->*drawFunc1[(span->length_x != 1)])(
 		    span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]);
@@ -580,9 +640,10 @@
 	    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]);
+	// 現在 drawLine2、drawDot2 は機能してないので
+	//(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);