# HG changeset patch # User Shinji KONO # Date 1253775961 -32400 # Node ID 960471b7ee5414d9a223432e226b9ba1b4d97939 # Parent cd77224d42241ee7c75a08f953a878232f63e43a# Parent afb717c43a3ced7b56c87b3f285b680b81cd60b8 merge chain... diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/KeyStat.h --- a/TaskManager/Test/test_render/KeyStat.h Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/KeyStat.h Thu Sep 24 16:06:01 2009 +0900 @@ -7,12 +7,16 @@ PUSH, }; +// 可変長の構造体にする。 +// int で1つ送り bit field でやると typedef struct key_stat { + int length; int right; int left; int up; int down; int circle; + unsigned char data[0]; }; #endif diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/SceneGraphRoot.cc --- a/TaskManager/Test/test_render/SceneGraphRoot.cc Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/SceneGraphRoot.cc Thu Sep 24 16:06:01 2009 +0900 @@ -196,40 +196,14 @@ } /*removeのflagをもとにtreeを形成*/ - while (t) { - SceneGraphPtr c = NULL; - if (!t->isRemoved()) { - c = t->clone(); - addNext(c); - cur_parent->addChild(c); - c->frame = t->frame; - /*親の回転、座標から、子の回転、座標を算出*/ - get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); - } - - if (t->children != NULL && c != NULL) { - cur_parent = c; - t = t->children; - } else if (t->brother != NULL) { - t = t->brother; - } else { - while (t) { - if (t->brother != NULL) { - t = t->brother; - break; - } else { - if (t->parent == NULL) { - t = NULL; - break; - } else { - cur_parent = cur_parent->parent; - t = t->parent; - - } - } - } - } + /* spe から送り返されてきた property の配列を見て生成する for()*/ + /* + for (Property *t = property[0]; is_end(t); t++){ + SceneGraphPtr s = application->scenegraph_factory(t); // SceneGraphNode を作る + t->scenegraph = s; // property list には SceneGraphへのポインタが入っている + application->scenegraph_connector(property[0], s); // add する } + */ diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ChainCal.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/ChainCal.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,91 @@ +#include +#include +#include "ChainCal.h" +#include "Func.h" +#include "types.h" +#include + + +/* これは必須 */ +SchedDefineTask(ChainCal); + +#define CHAIN_LEN 50 + +static double m = 100.0; +static double k = 7000.0; +static double g = 9.8; +static double dt = 0.003; +static double chain_width = 10; +static double safe = 0.995; + +typedef struct { + double x, y, next_x, next_y; + double vx, vy, next_vx, next_vy; + double angle[3]; + int can_move; + uint32 parent; + int id; + //int parent; +} CHAIN_VARS; + +int +ChainCal::run(void *rbuf, void *wbuf) +{ + CHAIN_VARS* property = (CHAIN_VARS*)rbuf; + int id = get_param(0); + + //CHAIN_VARS* o_property = (CHAIN_VARS*)wbuf; + + for(int cnt = 0; cnt < 600; cnt++) { + for(int i = 0; i < CHAIN_LEN; i++) { + if(property[i].can_move) { + double dx = property[i-1].x - property[i].x; + double dy = property[i-1].y - property[i].y; + double l = sqrt(dx * dx + dy * dy); + double a = k * (l - chain_width) / m; + double ax = a * dx / l; + double ay = a * dy / l; + if(i < CHAIN_LEN - 1) { + dx = property[i+1].x - property[i].x; + dy = property[i+1].y - property[i].y; + l = sqrt(dx * dx + dy * dy); + a = k * (l - chain_width) / m; + ax += a * dx / l; + ay += a * dy / l; + } + ay += g; + property[i].vx *= safe; + property[i].vy *= safe; + property[i].next_vx = property[i].vx + ax * dt; + property[i].next_vy = property[i].vy + ay * dt; + property[i].next_x = property[i].x + property[i].vx * dt; + property[i].next_y = property[i].y + property[i].vy * dt; + } else { + property[i].next_x = property[i].x; + property[i].next_y = property[i].y; + } + } + for(int i = 0; i < CHAIN_LEN; i++) { + property[i].vx = property[i].next_vx; + property[i].vy = property[i].next_vy; + property[i].x = property[i].next_x; + property[i].y = property[i].next_y; + } + } + + for (int j = 0; j < CHAIN_LEN; j++) { + int p, n; + id = property[j].id; + p = n = id; + if(p != 0) { + p--; + } + if(n != CHAIN_LEN - 1) { + n++; + } + property[j].angle[2-(id%2)*2] + = 90 + atan((property[p].next_y - property[n].next_y) / (property[p].next_x - property[n].next_x)) * 180 / M_PI; + } + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ChainCal.cpp --- a/TaskManager/Test/test_render/spe/ChainCal.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#include -#include -#include "ChainCal.h" -#include "Func.h" -#include "types.h" -#include - - -/* これは必須 */ -SchedDefineTask(ChainCal); - -#define CHAIN_LEN 50 - -static double m = 100.0; -static double k = 7000.0; -static double g = 9.8; -static double dt = 0.003; -static double chain_width = 10; -static double safe = 0.995; - -typedef struct { - double x, y, next_x, next_y; - double vx, vy, next_vx, next_vy; - double angle[3]; - int can_move; - uint32 parent; - int id; - //int parent; -} CHAIN_VARS; - -int -ChainCal::run(void *rbuf, void *wbuf) -{ - CHAIN_VARS* property = (CHAIN_VARS*)rbuf; - int id = get_param(0); - - //CHAIN_VARS* o_property = (CHAIN_VARS*)wbuf; - - for(int cnt = 0; cnt < 600; cnt++) { - for(int i = 0; i < CHAIN_LEN; i++) { - if(property[i].can_move) { - double dx = property[i-1].x - property[i].x; - double dy = property[i-1].y - property[i].y; - double l = sqrt(dx * dx + dy * dy); - double a = k * (l - chain_width) / m; - double ax = a * dx / l; - double ay = a * dy / l; - if(i < CHAIN_LEN - 1) { - dx = property[i+1].x - property[i].x; - dy = property[i+1].y - property[i].y; - l = sqrt(dx * dx + dy * dy); - a = k * (l - chain_width) / m; - ax += a * dx / l; - ay += a * dy / l; - } - ay += g; - property[i].vx *= safe; - property[i].vy *= safe; - property[i].next_vx = property[i].vx + ax * dt; - property[i].next_vy = property[i].vy + ay * dt; - property[i].next_x = property[i].x + property[i].vx * dt; - property[i].next_y = property[i].y + property[i].vy * dt; - } else { - property[i].next_x = property[i].x; - property[i].next_y = property[i].y; - } - } - for(int i = 0; i < CHAIN_LEN; i++) { - property[i].vx = property[i].next_vx; - property[i].vy = property[i].next_vy; - property[i].x = property[i].next_x; - property[i].y = property[i].next_y; - } - } - - for (int j = 0; j < CHAIN_LEN; j++) { - int p, n; - id = property[j].id; - p = n = id; - if(p != 0) { - p--; - } - if(n != CHAIN_LEN - 1) { - n++; - } - property[j].angle[2-(id%2)*2] - = 90 + atan((property[p].next_y - property[n].next_y) / (property[p].next_x - property[n].next_x)) * 180 / M_PI; - } - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ChainInit.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/ChainInit.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,33 @@ +#include +#include +#include "ChainInit.h" +#include "Func.h" + +/* これは必須 */ +SchedDefineTask(ChainInit); + +/* + spe の global 領域に MemList を生成する + */ + +typedef struct { + double x, y, next_x, next_y; + double vx, vy, next_vx, next_vy; + int can_move; + uint32 parent; +} CHAIN_VARS; + +CHAIN_VARS* property; + +int +ChainInit::run(void *rbuf, void *wbuf) +{ + CHAIN_VARS* idata = (CHAIN_VARS*)get_input(rbuf, 0); + uint32 chain_len = get_param(0); + + // property は spe 上で allocate している(global) + property = (CHAIN_VARS*)global_alloc(DATA_ID, sizeof(CHAIN_VARS)*chain_len); + memcpy(property, idata, sizeof(CHAIN_VARS)*chain_len); + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ChainInit.cpp --- a/TaskManager/Test/test_render/spe/ChainInit.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -#include -#include -#include "ChainInit.h" -#include "Func.h" - -/* これは必須 */ -SchedDefineTask(ChainInit); - -/* - spe の global 領域に MemList を生成する - */ - -typedef struct { - double x, y, next_x, next_y; - double vx, vy, next_vx, next_vy; - int can_move; - uint32 parent; -} CHAIN_VARS; - -CHAIN_VARS* property; - -int -ChainInit::run(void *rbuf, void *wbuf) -{ - CHAIN_VARS* idata = (CHAIN_VARS*)get_input(rbuf, 0); - uint32 chain_len = get_param(0); - - // property は spe 上で allocate している(global) - property = (CHAIN_VARS*)global_alloc(DATA_ID, sizeof(CHAIN_VARS)*chain_len); - memcpy(property, idata, sizeof(CHAIN_VARS)*chain_len); - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/CreatePolygon.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/CreatePolygon.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,196 @@ +/** + * SceneGraph が増えてくると動かなくなるかもしれない。 + * 一応 mainMem とかで動くようになるとは思うけど。 + * だめだったら、そこら辺が怪しいと思うべき + */ + +// #define DEBUG +#include "error.h" + +#include "CreatePolygon.h" +#include "polygon_pack.h" +#include "scene_graph_pack.h" + +SchedDefineTask(CreatePolygon); + +#define SG_PACK_LOAD 10 +#define SG_NODE_LOAD 11 +#define PP_LOAD 12 +#define PP_STORE 13 + +/** + * あとで直す + */ +static void +rotate(float *xyz, float *matrix) +{ + float abc[4]; + + abc[0] = xyz[0]; + abc[1] = xyz[1]; + abc[2] = xyz[2]; + abc[3] = xyz[3]; + + for(int i=0; i<4; i++) + { + xyz[i] = abc[0]*matrix[i] + abc[1]*matrix[i+4] + abc[2]*matrix[i+8] + abc[3]*matrix[i+12]; + } +} + +int +CreatePolygon::run(void *rbuf, void *wbuf) +{ + __debug_spe("CreatePolygon\n"); + + float xyz1[4],xyz2[4],xyz3[4]; + + SceneGraphPackPtr sgp = (SceneGraphPack*)smanager->get_input(0); + SceneGraphPackPtr next_sgp = + (SceneGraphPackPtr)smanager->allocate(sizeof(SceneGraphPack)); + SceneGraphPackPtr free_sgp = next_sgp; + SceneGraphPackPtr tmp_sgp; + + SceneGraphNodePtr node; + SceneGraphNodePtr next_node + = (SceneGraphNodePtr)smanager->allocate(sizeof(SceneGraphNode)); + SceneGraphNodePtr free_node = next_node; + SceneGraphNodePtr tmp_node; + + PolygonPackPtr pp + = (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack)); + PolygonPackPtr send_pp + = (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack)); + PolygonPackPtr pp_addr = (PolygonPackPtr)smanager->get_param(0); + PolygonPackPtr tmp_pp; + + pp->init(); + send_pp->init(); + + do { + if (sgp->next != NULL) { + smanager->dma_load(next_sgp, (uint32)sgp->next, + sizeof(SceneGraphPack), SG_PACK_LOAD); + } else { + next_sgp = NULL; + } + + for (int i = 0; i < sgp->info.size; i++) { + node = &sgp->node[i]; + + do { + if (node->next != NULL) { + smanager->dma_load(next_node, (uint32)node->next, + sizeof(SceneGraphNode), SG_NODE_LOAD); + } else { + next_node = NULL; + } + + for (int n = 0, nt = 0; n < node->size*3; n+=9, nt+=6) { + + if (pp->info.size >= MAX_SIZE_TRIANGLE) { + PolygonPackPtr next; + + // smanager から Task を作る、0 ではなく PolygonPack->task_id が良い + smanager->mainMem_alloc(0, sizeof(PolygonPack)); + smanager->mainMem_wait(); + next = (PolygonPackPtr)smanager->mainMem_get(0); + + pp->next = next; // この部分は TaskManager 側でやるべき + + tmp_pp = pp; + pp = send_pp; + send_pp = tmp_pp; + + smanager->dma_wait(PP_STORE); + smanager->dma_store(send_pp, (uint32)pp_addr, + sizeof(PolygonPack), PP_STORE); + + pp_addr = next; + + smanager->dma_wait(PP_LOAD); // 多分不要 + smanager->dma_load(pp, (uint32)pp_addr, + sizeof(PolygonPack), PP_LOAD); + // 次の dma_wait のコストが高いのでパイプラインで隠す必要がある + + smanager->dma_wait(PP_LOAD); + pp->init(); + + } + + TrianglePack *triangle = &pp->tri[pp->info.size++]; + + xyz1[0] = node->vertex[n]; + xyz1[1] = node->vertex[n+1]; + xyz1[2] = node->vertex[n+2]*-1; + xyz1[3] = 1; + xyz2[0] = node->vertex[n+3]; + xyz2[1] = node->vertex[n+3+1]; + xyz2[2] = node->vertex[n+3+2]*-1; + xyz2[3] = 1; + xyz3[0] = node->vertex[n+6]; + xyz3[1] = node->vertex[n+6+1]; + xyz3[2] = node->vertex[n+6+2]*-1; + xyz3[3] = 1; + + rotate(xyz1, node->translation); + rotate(xyz2, node->translation); + rotate(xyz3, node->translation); + + triangle->ver1.x = xyz1[0]; + triangle->ver1.y = xyz1[1]; + triangle->ver1.z = xyz1[2]; + triangle->ver1.tex_x = node->texture[nt]; + triangle->ver1.tex_y = node->texture[nt+1]; + + triangle->ver2.x = xyz2[0]; + triangle->ver2.y = xyz2[1]; + triangle->ver2.z = xyz2[2]; + triangle->ver2.tex_x = node->texture[nt+2]; + triangle->ver2.tex_y = node->texture[nt+2+1]; + + triangle->ver3.x = xyz3[0]; + triangle->ver3.y = xyz3[1]; + triangle->ver3.z = xyz3[2]; + triangle->ver3.tex_x = node->texture[nt+4]; + triangle->ver3.tex_y = node->texture[nt+4+1]; + +#if 1 + triangle->tex_info.addr = node->tex_addr; + triangle->tex_info.width = node->tex_width; + triangle->tex_info.height = node->tex_height; +#else + triangle->tex_info.addr = node->texture_info.pixels; + triangle->tex_info.width = node->texture_info.t_w; + triangle->tex_info.height = node->texture_info.t_h; +#endif + } + + smanager->dma_wait(SG_NODE_LOAD); + + tmp_node = node; + node = next_node; + next_node = tmp_node; + } while (node); + + next_node = free_node; + } + + smanager->dma_wait(SG_PACK_LOAD); + + tmp_sgp = sgp; + sgp = next_sgp; + next_sgp = tmp_sgp; + } while (sgp); + + smanager->dma_wait(PP_STORE); + smanager->dma_store(pp, (uint32)pp_addr, + sizeof(PolygonPack), PP_STORE); + smanager->dma_wait(PP_STORE); + + free(pp); + free(send_pp); + free(free_node); + free(free_sgp); + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/CreatePolygon.cpp --- a/TaskManager/Test/test_render/spe/CreatePolygon.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,196 +0,0 @@ -/** - * SceneGraph が増えてくると動かなくなるかもしれない。 - * 一応 mainMem とかで動くようになるとは思うけど。 - * だめだったら、そこら辺が怪しいと思うべき - */ - -// #define DEBUG -#include "error.h" - -#include "CreatePolygon.h" -#include "polygon_pack.h" -#include "scene_graph_pack.h" - -SchedDefineTask(CreatePolygon); - -#define SG_PACK_LOAD 10 -#define SG_NODE_LOAD 11 -#define PP_LOAD 12 -#define PP_STORE 13 - -/** - * あとで直す - */ -static void -rotate(float *xyz, float *matrix) -{ - float abc[4]; - - abc[0] = xyz[0]; - abc[1] = xyz[1]; - abc[2] = xyz[2]; - abc[3] = xyz[3]; - - for(int i=0; i<4; i++) - { - xyz[i] = abc[0]*matrix[i] + abc[1]*matrix[i+4] + abc[2]*matrix[i+8] + abc[3]*matrix[i+12]; - } -} - -int -CreatePolygon::run(void *rbuf, void *wbuf) -{ - __debug_spe("CreatePolygon\n"); - - float xyz1[4],xyz2[4],xyz3[4]; - - SceneGraphPackPtr sgp = (SceneGraphPack*)smanager->get_input(0); - SceneGraphPackPtr next_sgp = - (SceneGraphPackPtr)smanager->allocate(sizeof(SceneGraphPack)); - SceneGraphPackPtr free_sgp = next_sgp; - SceneGraphPackPtr tmp_sgp; - - SceneGraphNodePtr node; - SceneGraphNodePtr next_node - = (SceneGraphNodePtr)smanager->allocate(sizeof(SceneGraphNode)); - SceneGraphNodePtr free_node = next_node; - SceneGraphNodePtr tmp_node; - - PolygonPackPtr pp - = (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack)); - PolygonPackPtr send_pp - = (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack)); - PolygonPackPtr pp_addr = (PolygonPackPtr)smanager->get_param(0); - PolygonPackPtr tmp_pp; - - pp->init(); - send_pp->init(); - - do { - if (sgp->next != NULL) { - smanager->dma_load(next_sgp, (uint32)sgp->next, - sizeof(SceneGraphPack), SG_PACK_LOAD); - } else { - next_sgp = NULL; - } - - for (int i = 0; i < sgp->info.size; i++) { - node = &sgp->node[i]; - - do { - if (node->next != NULL) { - smanager->dma_load(next_node, (uint32)node->next, - sizeof(SceneGraphNode), SG_NODE_LOAD); - } else { - next_node = NULL; - } - - for (int n = 0, nt = 0; n < node->size*3; n+=9, nt+=6) { - - if (pp->info.size >= MAX_SIZE_TRIANGLE) { - PolygonPackPtr next; - - // smanager から Task を作る、0 ではなく PolygonPack->task_id が良い - smanager->mainMem_alloc(0, sizeof(PolygonPack)); - smanager->mainMem_wait(); - next = (PolygonPackPtr)smanager->mainMem_get(0); - - pp->next = next; // この部分は TaskManager 側でやるべき - - tmp_pp = pp; - pp = send_pp; - send_pp = tmp_pp; - - smanager->dma_wait(PP_STORE); - smanager->dma_store(send_pp, (uint32)pp_addr, - sizeof(PolygonPack), PP_STORE); - - pp_addr = next; - - smanager->dma_wait(PP_LOAD); // 多分不要 - smanager->dma_load(pp, (uint32)pp_addr, - sizeof(PolygonPack), PP_LOAD); - // 次の dma_wait のコストが高いのでパイプラインで隠す必要がある - - smanager->dma_wait(PP_LOAD); - pp->init(); - - } - - TrianglePack *triangle = &pp->tri[pp->info.size++]; - - xyz1[0] = node->vertex[n]; - xyz1[1] = node->vertex[n+1]; - xyz1[2] = node->vertex[n+2]*-1; - xyz1[3] = 1; - xyz2[0] = node->vertex[n+3]; - xyz2[1] = node->vertex[n+3+1]; - xyz2[2] = node->vertex[n+3+2]*-1; - xyz2[3] = 1; - xyz3[0] = node->vertex[n+6]; - xyz3[1] = node->vertex[n+6+1]; - xyz3[2] = node->vertex[n+6+2]*-1; - xyz3[3] = 1; - - rotate(xyz1, node->translation); - rotate(xyz2, node->translation); - rotate(xyz3, node->translation); - - triangle->ver1.x = xyz1[0]; - triangle->ver1.y = xyz1[1]; - triangle->ver1.z = xyz1[2]; - triangle->ver1.tex_x = node->texture[nt]; - triangle->ver1.tex_y = node->texture[nt+1]; - - triangle->ver2.x = xyz2[0]; - triangle->ver2.y = xyz2[1]; - triangle->ver2.z = xyz2[2]; - triangle->ver2.tex_x = node->texture[nt+2]; - triangle->ver2.tex_y = node->texture[nt+2+1]; - - triangle->ver3.x = xyz3[0]; - triangle->ver3.y = xyz3[1]; - triangle->ver3.z = xyz3[2]; - triangle->ver3.tex_x = node->texture[nt+4]; - triangle->ver3.tex_y = node->texture[nt+4+1]; - -#if 1 - triangle->tex_info.addr = node->tex_addr; - triangle->tex_info.width = node->tex_width; - triangle->tex_info.height = node->tex_height; -#else - triangle->tex_info.addr = node->texture_info.pixels; - triangle->tex_info.width = node->texture_info.t_w; - triangle->tex_info.height = node->texture_info.t_h; -#endif - } - - smanager->dma_wait(SG_NODE_LOAD); - - tmp_node = node; - node = next_node; - next_node = tmp_node; - } while (node); - - next_node = free_node; - } - - smanager->dma_wait(SG_PACK_LOAD); - - tmp_sgp = sgp; - sgp = next_sgp; - next_sgp = tmp_sgp; - } while (sgp); - - smanager->dma_wait(PP_STORE); - smanager->dma_store(pp, (uint32)pp_addr, - sizeof(PolygonPack), PP_STORE); - smanager->dma_wait(PP_STORE); - - free(pp); - free(send_pp); - free(free_node); - free(free_sgp); - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/CreateSpan.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/CreateSpan.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,505 @@ +// #define DEBUG +#include "error.h" +#include "CreateSpan.h" +#include "viewer_types.h" + +// DMA channel +static const int SPAN_PACK_LOAD = 5; +static const int SPAN_PACK_STORE = 6; +static const int POLYGON_PACK_LOAD = 7; +static const int TILE_ALLOCATE = 8; +static const int TILE_LOAD = 9; +static const int TILE_STORE = 10; + +static SpanPackPtr spack = NULL; +static SpanPackPtr send_spack = NULL; +static int prev_index = 0; + +SchedDefineTask(CreateSpan); + +static float +calc(float f1, float f2,int i, float base) +{ + float ans; + ans = f1/f2*i + base; + return ans; +} + + +/** + * TrianglePack から、vMin, vMid, vMax を求める + * + * @param [triPack] TrianglePack + * @param [vMin] [vMid] [vMax] + */ +static void +make_vertex(TrianglePack *triPack, + VertexPackPtr *vMin, VertexPackPtr *vMid, VertexPackPtr *vMax) +{ + if (triPack->ver1.y <= triPack->ver2.y) { + if (triPack->ver2.y <= triPack->ver3.y) { + *vMin = &triPack->ver1; + *vMid = &triPack->ver2; + *vMax = &triPack->ver3; + } else if (triPack->ver3.y <= triPack->ver1.y) { + *vMin = &triPack->ver3; + *vMid = &triPack->ver1; + *vMax = &triPack->ver2; + } else { + *vMin = &triPack->ver1; + *vMid = &triPack->ver3; + *vMax = &triPack->ver2; + } + } else { + if (triPack->ver1.y <= triPack->ver3.y) { + *vMin = &triPack->ver2; + *vMid = &triPack->ver1; + *vMax = &triPack->ver3; + } else if (triPack->ver3.y <= triPack->ver2.y) { + *vMin = &triPack->ver3; + *vMid = &triPack->ver2; + *vMax = &triPack->ver1; + } else { + *vMin = &triPack->ver2; + *vMid = &triPack->ver3; + *vMax = &triPack->ver1; + } + } +} + +static void +make_vMid10(VertexPack *v, VertexPack *vMin, + VertexPack *vMid, VertexPack *vMax) +{ + //int d, d1; + float d; + int d1; + + d = vMax->y - vMin->y; + d1 = (int)(vMid->y - vMin->y); + + v->tex_x = calc(vMax->tex_x - vMin->tex_x, d, d1, vMin->tex_x); + v->tex_y = calc(vMax->tex_y - vMin->tex_y, d, d1, vMin->tex_y); + v->x = calc(vMax->x - vMin->x, d, d1, vMin->x); + v->y = vMid->y; + v->z = calc(vMax->z - vMin->z, d, d1, vMin->z); +} + +/** + * 与えられた scale から、実際に使うテクスチャの Tapestry を選択する + * + * テクスチャは、オリジナルのサイズから、可能なかぎり 1/2 で縮小していき、 + * 下の図の様に連続した領域に入れられる + * + * Tapestry (1) + * +---+---+---+---+ + * | 0 | 1 | 2 | 3 | + * +---+---+---+---+ + * | 4 | 5 | 6 | 7 | (2) + * +---+---+---+---+ +---+---+ + * | 8 | 9 | 10| 11| | 16| 17| (3) + * +---+---+---+---+ +---+---+ +---+ + * | 12| 13| 14| 15| | 18| 19| | 20| + * +---+---+---+---+ +---+---+ +---| + * + * (1) (2) (3) + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20| + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * + * scale の値から、各 Tapestry の先頭アドレスを返す + * + * @param[in] tw Width of texture + * @param[in] th Height of texture + * @param[in] scale テクスチャの縮小率 (= 2^n) + * @param[in] addr_top テクスチャの先頭アドレス (上の図での (1) + * @return scale に対応する Tapestry のアドレス (上の図での (1) or (2) or(3) + */ +static uint32* +getTapestry(int tw, int th, int scale, uint32 *addr_top) +{ + int index = 0; + + for (int s = 1; s < scale; s <<= 1) { + index += tw*th; + tw >>= 1; /* tw /= 2 */ + th >>= 1; + } + + return addr_top + index; +} + + +/** + * span の width,height と texture の width,height を比べて + * span を描画する際に使う texture の比率を求める + * + * @param[in] width Width of span + * @param[in] height Height of span + * @param[in] tex_width Width of 1/1 texture that span use + * @param[in] tex_height Height of 1/1 texture that span use + * @param[in] scale_max この Span で使う texture の最大縮小率 + * 計算結果が scale_max 以上になるのを防ぐ + * @return 描画に使う texture の比率 + * width と height は 1/scale の画像を使う + * + */ +static int +getScale(int width, int height, int tex_width, int tex_height, int scale_max) +{ + int base, tex_base; + int scale = 1; + + /** + * width と height で、長い方を基準に、 + * texture の scale を決める + */ + if (width > height) { + base = width; + tex_base = tex_width; + } else { + base = height; + tex_base = tex_height; + } + + if (tex_base > base) { + int t_scale = tex_base/base; + while (t_scale >>= 1) { + scale <<= 1; + } + } + + return (scale > scale_max) ? scale_max : scale; + //return scale_max; +} + +/** + * x軸に水平な辺を持つ三角形ポリゴンから、 + * Span を抜き出す + * + * @param[in] spackList triangle から生成された span を格納する List + * @param[in] charge_y_top 担当する y の範囲開始地点 + * @param[in] charge_y_end 担当する y の範囲終了地点 + * @param[in] tex_addr triangle が参照するテクスチャの先頭アドレス + * @param[in] tex_width テクスチャの width + * @param[in] tex_height テクスチャの height + * @param[in] tex_scale_max テクスチャの最大縮小率 (2^n) + * @param[in] vMin triangle の座標 + * @param[in] vMid triangle の座標。triangle を二つに分けて出来た新しい座標 + * @param[in] vMid10 triangle の座標 + * @param[in] length_y 分割する前の Triangle の y の長さ + * @param[in] tex_y_len 分割する前の Triangle に貼られている Texture の + * 長さの割合 (0 ... 1) + */ +void +CreateSpan::half_triangle(SchedTask *smanager, SpanPackPtr *spackList, + int charge_y_top, int charge_y_end, + TriangleTexInfoPtr tex_info, + VertexPack *vMin,VertexPack *vMid,VertexPack *vMid10, + int length_y, float tex_y_len) +{ + float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2; + float tmp_xpos,tmp_end,tmp_zpos; + float start_z, end_z; + float start_tex_x, end_tex_x, start_tex_y, end_tex_y; + int x, y, length; + +#if 1 + // これじゃないと + // テクスチャの貼りに微妙に隙間が。謎だ + int start_y = (int)vMid->y; + int end_y = (int)vMin->y; +#else + float start_y = vMid->y; + float end_y = vMin->y; +#endif + float div_y = start_y - end_y; + int k = 0; + int l = 1; + + SpanPackPtr tmp_spack; + + /** + * 三角形ポリゴンをx軸に水平に二つに分けようとして + * ある一辺がすでに水平だった場合、つまり + * + * |\ + * | \ + * | \ + * ----- + * + * + * 上のようなポリゴンだった場合は、本来なら上の部分の三角形にだけ + * half_triangle の処理をするべきだが、現在の処理だと + * この half_triangle に「上の部分の三角形」と、 + * 「『下の部分の三角形と判断してしまった』直線」が来てしまう。 + * 直線の部分が来ると、calc() で 0 除算とかで、値不定で暴走するので + * 現在はこれで代用。 + * half_triangle 呼ぶ前にこれを判断できれば良いかもしれない。 + * てかこんなんでいいのかよ。。。 + */ +#if 1 + if ((int)div_y == 0) { + return; + } +#else + if (vMid10->x == vMin->x && vMid10->y == vMin->y) { + return; + } +#endif + + if (div_y < 0) { + div_y = -div_y; + k = 1; + l = -1; + } + + for (int i = k; i < (int)div_y+1; i++) { + y = (int)vMin->y + i*l; +#if 1 + + /** + * 担当 y 範囲内 + */ + if (charge_y_top <= y && y <= charge_y_end) { + // 1..8 を index0, 9..16 を index1 にするために y を -1 + int index = (y-1) / split_screen_h; + + /** + * 違う SpanPack を扱う場合、 + * 現在の SpanPack をメインメモリに送り、 + * 新しい SpanPack を取ってくる + */ + if (index != prev_index) { + tmp_spack = spack; + spack = send_spack; + send_spack = tmp_spack; + + smanager->dma_wait(SPAN_PACK_STORE); + smanager->dma_store(send_spack, (uint32)spackList[prev_index], + sizeof(SpanPack), SPAN_PACK_STORE); + + smanager->dma_load(spack, (uint32)spackList[index], + sizeof(SpanPack), SPAN_PACK_LOAD); + prev_index = index; + smanager->dma_wait(SPAN_PACK_LOAD); + } + + /** + * 書き込む SpanPack が満杯だったら + * メインメモリで allocate した領域 (next) を持ってきて + * 現在の spack->next につなぎ、next を次の spack とする。 + */ + if (spack->info.size >= MAX_SIZE_SPAN) { + SpanPackPtr next; + + __debug_spe("CreateSpan mainMem_alloc 0x%x\n", (unsigned int)sizeof(SpanPack)); + smanager->mainMem_alloc(0, sizeof(SpanPack)); + smanager->mainMem_wait(); + next = (SpanPackPtr)smanager->mainMem_get(0); + __debug_spe("CreateSpan mainMem_allocated 0x%x\n", (unsigned int)next); + + spack->next = next; // この部分は TaskManager でやる + + tmp_spack = spack; + spack = send_spack; + send_spack = tmp_spack; + + smanager->dma_wait(SPAN_PACK_STORE); + smanager->dma_store(send_spack, (uint32)spackList[index], + sizeof(SpanPack), SPAN_PACK_STORE); + + spackList[index] = next; + + smanager->dma_load(spack, (uint32)spackList[index], + sizeof(SpanPack), SPAN_PACK_LOAD); + smanager->dma_wait(SPAN_PACK_LOAD); + spack->init((index+1)*split_screen_h); + } + } else { + /** + * 担当範囲外だったら無視 + */ + continue; + } + + tmp_xpos = calc(vMid10->x - vMin->x ,div_y, i, vMin->x); + tmp_end = calc(vMid->x - vMin->x ,div_y, i, vMin->x); + tmp_z = calc(vMid10->z - vMin->z ,div_y, i, vMin->z); + tmp_zpos = calc(vMid->z - vMin->z ,div_y, i, vMin->z); + + length = (tmp_xpos > tmp_end) + ? (int)tmp_xpos - (int)tmp_end : (int)tmp_end - (int)tmp_xpos; + if (length == 0) { + continue; + } + + tmp_tex1 =((i/(div_y)) * vMid10->tex_x) + + ( ((div_y - i)/(div_y)) * vMin->tex_x); + tmp_tex2 =( (i/(div_y)) * vMid->tex_x) + + ( ((div_y - i)/(div_y)) * vMin->tex_x); + + tmp_tey1 =( (i/(div_y)) * vMid10->tex_y) + + ( ((div_y - i)/(div_y)) * vMin->tex_y); + tmp_tey2 =( (i/(div_y)) * vMid->tex_y) + + ( ((div_y - i)/(div_y)) * vMin->tex_y); + + if (tmp_xpos > tmp_end) { + x = (int)tmp_end; + length = (int)(tmp_xpos)-(int)(tmp_end)+1; + start_z = tmp_zpos; + end_z = tmp_z; + start_tex_x = tmp_tex2; + end_tex_x = tmp_tex1; + start_tex_y = tmp_tey2; + end_tex_y = tmp_tey1; + } else { + x = (int)tmp_xpos; + length = (int)(tmp_end)-(int)(tmp_xpos)+1; + start_z = tmp_z; + end_z = tmp_zpos; + start_tex_x = tmp_tex1; + end_tex_x = tmp_tex2; + start_tex_y = tmp_tey1; + end_tex_y = tmp_tey2; + } + + smanager->dma_wait(SPAN_PACK_LOAD); + + Span *span = &spack->span[spack->info.size++]; + + span->x = x; + span->y = y; + span->length_x = length; + span->start_z = start_z; + span->end_z = end_z; + span->tex_x1 = start_tex_x; + span->tex_x2 = end_tex_x; + span->tex_y1 = start_tex_y; + span->tex_y2 = end_tex_y; + + + float tex_x_len = span->tex_x2 - span->tex_x1; + + /** + * tex_x_len, tex_y_len を掛ける理由は + * Changelog の 2008-12-16 を参照 + */ + int scale = getScale(span->length_x, length_y, + (int)(span->tex_width*tex_x_len), + (int)(span->tex_height*tex_y_len), + tex_info->scale_max); + //scale = tex_info->scale_max; + + uint32 *tapestry = getTapestry(tex_info->width, + tex_info->height, scale, + tex_info->addr); + span->tex_addr = tapestry; + span->tex_width = tex_info->width/scale; + span->tex_height = tex_info->height/scale; + } +#else + + /** + * ここに SIMD 化した記述をしようとして断念 + */ + +#endif + +} + + +int +CreateSpan::run(SchedTask *smanager, void *rbuf, void *wbuf) +{ + __debug_spe("CreateSpan\n"); + + PolygonPack *pp = (PolygonPack*)smanager->get_input(0); + PolygonPack *next_pp = + (PolygonPack*)smanager->allocate(sizeof(PolygonPack)); + PolygonPack *free_pp = next_pp; + PolygonPack *tmp_pp; + + TrianglePackPtr triPack; + VertexPackPtr vMin, vMid, vMax; + VertexPackPtr vMid10 + = (VertexPackPtr)smanager->allocate(sizeof(VertexPack)); + + SpanPackPtr *spackList = (SpanPackPtr*)smanager->get_input(1); + spack = (SpanPackPtr)smanager->get_input(2); + send_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + prev_index = get_param(0); + + // spack と send_spack は swap しながら DMA を繰り返すので + // 自分で allocate した send_spack を覚えてないといけない + SpanPackPtr free_spack = send_spack; + + int charge_y_top = get_param(1); + int charge_y_end = get_param(2); + + do { + __debug_spe("CreateSpan allocated 0x%x\n",(uint32)next_pp); + + if (pp->next != NULL) { + smanager->dma_load(next_pp, (uint32)pp->next, + sizeof(PolygonPack), POLYGON_PACK_LOAD); + } else { + next_pp = NULL; + } + + for (int i = 0; i < pp->info.size; i++) { + triPack = &pp->tri[i]; + + TriangleTexInfoPtr tri_tex_info = &triPack->tex_info; + + make_vertex(triPack, &vMin, &vMid, &vMax); + make_vMid10(vMid10, vMin, vMid, vMax); + + /** + * ポリゴンを、x軸に水平に分割して二つの三角形を作り、 + * それぞれから Span を求める + * + * vMax + * |\ + * | \ + * | \ + * | \ + * vMid10 ------ vMid + * | / + * | / + * | / + * |/ + * vMin + * + * (vMax, vMid, vMin) という triangle を + * (vMax, vMid, vMid10) (vMin, vMid, vMid10) という + * 二つの Triangle に分けている + */ + half_triangle(smanager, spackList, charge_y_top, charge_y_end, + tri_tex_info, vMin, vMid, vMid10, + (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, + (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); + } + + smanager->dma_wait(POLYGON_PACK_LOAD); + + tmp_pp = pp; + pp = next_pp; + next_pp = tmp_pp; + } while (pp); + + smanager->dma_wait(SPAN_PACK_STORE); + smanager->dma_store(spack, (uint32)spackList[prev_index], + sizeof(SpanPack), SPAN_PACK_STORE); + smanager->dma_wait(SPAN_PACK_STORE); + __debug_spe("CreateSpan spack_stored 0x%x\n",(uint32)spackList[prev_index]); + + // smanager で allocate したのだから free も smanager でやるべき + free(free_pp); + free(free_spack); + free(vMid10); + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/CreateSpan.cpp --- a/TaskManager/Test/test_render/spe/CreateSpan.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,505 +0,0 @@ -// #define DEBUG -#include "error.h" -#include "CreateSpan.h" -#include "viewer_types.h" - -// DMA channel -static const int SPAN_PACK_LOAD = 5; -static const int SPAN_PACK_STORE = 6; -static const int POLYGON_PACK_LOAD = 7; -static const int TILE_ALLOCATE = 8; -static const int TILE_LOAD = 9; -static const int TILE_STORE = 10; - -static SpanPackPtr spack = NULL; -static SpanPackPtr send_spack = NULL; -static int prev_index = 0; - -SchedDefineTask(CreateSpan); - -static float -calc(float f1, float f2,int i, float base) -{ - float ans; - ans = f1/f2*i + base; - return ans; -} - - -/** - * TrianglePack から、vMin, vMid, vMax を求める - * - * @param [triPack] TrianglePack - * @param [vMin] [vMid] [vMax] - */ -static void -make_vertex(TrianglePack *triPack, - VertexPackPtr *vMin, VertexPackPtr *vMid, VertexPackPtr *vMax) -{ - if (triPack->ver1.y <= triPack->ver2.y) { - if (triPack->ver2.y <= triPack->ver3.y) { - *vMin = &triPack->ver1; - *vMid = &triPack->ver2; - *vMax = &triPack->ver3; - } else if (triPack->ver3.y <= triPack->ver1.y) { - *vMin = &triPack->ver3; - *vMid = &triPack->ver1; - *vMax = &triPack->ver2; - } else { - *vMin = &triPack->ver1; - *vMid = &triPack->ver3; - *vMax = &triPack->ver2; - } - } else { - if (triPack->ver1.y <= triPack->ver3.y) { - *vMin = &triPack->ver2; - *vMid = &triPack->ver1; - *vMax = &triPack->ver3; - } else if (triPack->ver3.y <= triPack->ver2.y) { - *vMin = &triPack->ver3; - *vMid = &triPack->ver2; - *vMax = &triPack->ver1; - } else { - *vMin = &triPack->ver2; - *vMid = &triPack->ver3; - *vMax = &triPack->ver1; - } - } -} - -static void -make_vMid10(VertexPack *v, VertexPack *vMin, - VertexPack *vMid, VertexPack *vMax) -{ - //int d, d1; - float d; - int d1; - - d = vMax->y - vMin->y; - d1 = (int)(vMid->y - vMin->y); - - v->tex_x = calc(vMax->tex_x - vMin->tex_x, d, d1, vMin->tex_x); - v->tex_y = calc(vMax->tex_y - vMin->tex_y, d, d1, vMin->tex_y); - v->x = calc(vMax->x - vMin->x, d, d1, vMin->x); - v->y = vMid->y; - v->z = calc(vMax->z - vMin->z, d, d1, vMin->z); -} - -/** - * 与えられた scale から、実際に使うテクスチャの Tapestry を選択する - * - * テクスチャは、オリジナルのサイズから、可能なかぎり 1/2 で縮小していき、 - * 下の図の様に連続した領域に入れられる - * - * Tapestry (1) - * +---+---+---+---+ - * | 0 | 1 | 2 | 3 | - * +---+---+---+---+ - * | 4 | 5 | 6 | 7 | (2) - * +---+---+---+---+ +---+---+ - * | 8 | 9 | 10| 11| | 16| 17| (3) - * +---+---+---+---+ +---+---+ +---+ - * | 12| 13| 14| 15| | 18| 19| | 20| - * +---+---+---+---+ +---+---+ +---| - * - * (1) (2) (3) - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20| - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * - * scale の値から、各 Tapestry の先頭アドレスを返す - * - * @param[in] tw Width of texture - * @param[in] th Height of texture - * @param[in] scale テクスチャの縮小率 (= 2^n) - * @param[in] addr_top テクスチャの先頭アドレス (上の図での (1) - * @return scale に対応する Tapestry のアドレス (上の図での (1) or (2) or(3) - */ -static uint32* -getTapestry(int tw, int th, int scale, uint32 *addr_top) -{ - int index = 0; - - for (int s = 1; s < scale; s <<= 1) { - index += tw*th; - tw >>= 1; /* tw /= 2 */ - th >>= 1; - } - - return addr_top + index; -} - - -/** - * span の width,height と texture の width,height を比べて - * span を描画する際に使う texture の比率を求める - * - * @param[in] width Width of span - * @param[in] height Height of span - * @param[in] tex_width Width of 1/1 texture that span use - * @param[in] tex_height Height of 1/1 texture that span use - * @param[in] scale_max この Span で使う texture の最大縮小率 - * 計算結果が scale_max 以上になるのを防ぐ - * @return 描画に使う texture の比率 - * width と height は 1/scale の画像を使う - * - */ -static int -getScale(int width, int height, int tex_width, int tex_height, int scale_max) -{ - int base, tex_base; - int scale = 1; - - /** - * width と height で、長い方を基準に、 - * texture の scale を決める - */ - if (width > height) { - base = width; - tex_base = tex_width; - } else { - base = height; - tex_base = tex_height; - } - - if (tex_base > base) { - int t_scale = tex_base/base; - while (t_scale >>= 1) { - scale <<= 1; - } - } - - return (scale > scale_max) ? scale_max : scale; - //return scale_max; -} - -/** - * x軸に水平な辺を持つ三角形ポリゴンから、 - * Span を抜き出す - * - * @param[in] spackList triangle から生成された span を格納する List - * @param[in] charge_y_top 担当する y の範囲開始地点 - * @param[in] charge_y_end 担当する y の範囲終了地点 - * @param[in] tex_addr triangle が参照するテクスチャの先頭アドレス - * @param[in] tex_width テクスチャの width - * @param[in] tex_height テクスチャの height - * @param[in] tex_scale_max テクスチャの最大縮小率 (2^n) - * @param[in] vMin triangle の座標 - * @param[in] vMid triangle の座標。triangle を二つに分けて出来た新しい座標 - * @param[in] vMid10 triangle の座標 - * @param[in] length_y 分割する前の Triangle の y の長さ - * @param[in] tex_y_len 分割する前の Triangle に貼られている Texture の - * 長さの割合 (0 ... 1) - */ -void -CreateSpan::half_triangle(SchedTask *smanager, SpanPackPtr *spackList, - int charge_y_top, int charge_y_end, - TriangleTexInfoPtr tex_info, - VertexPack *vMin,VertexPack *vMid,VertexPack *vMid10, - int length_y, float tex_y_len) -{ - float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2; - float tmp_xpos,tmp_end,tmp_zpos; - float start_z, end_z; - float start_tex_x, end_tex_x, start_tex_y, end_tex_y; - int x, y, length; - -#if 1 - // これじゃないと - // テクスチャの貼りに微妙に隙間が。謎だ - int start_y = (int)vMid->y; - int end_y = (int)vMin->y; -#else - float start_y = vMid->y; - float end_y = vMin->y; -#endif - float div_y = start_y - end_y; - int k = 0; - int l = 1; - - SpanPackPtr tmp_spack; - - /** - * 三角形ポリゴンをx軸に水平に二つに分けようとして - * ある一辺がすでに水平だった場合、つまり - * - * |\ - * | \ - * | \ - * ----- - * - * - * 上のようなポリゴンだった場合は、本来なら上の部分の三角形にだけ - * half_triangle の処理をするべきだが、現在の処理だと - * この half_triangle に「上の部分の三角形」と、 - * 「『下の部分の三角形と判断してしまった』直線」が来てしまう。 - * 直線の部分が来ると、calc() で 0 除算とかで、値不定で暴走するので - * 現在はこれで代用。 - * half_triangle 呼ぶ前にこれを判断できれば良いかもしれない。 - * てかこんなんでいいのかよ。。。 - */ -#if 1 - if ((int)div_y == 0) { - return; - } -#else - if (vMid10->x == vMin->x && vMid10->y == vMin->y) { - return; - } -#endif - - if (div_y < 0) { - div_y = -div_y; - k = 1; - l = -1; - } - - for (int i = k; i < (int)div_y+1; i++) { - y = (int)vMin->y + i*l; -#if 1 - - /** - * 担当 y 範囲内 - */ - if (charge_y_top <= y && y <= charge_y_end) { - // 1..8 を index0, 9..16 を index1 にするために y を -1 - int index = (y-1) / split_screen_h; - - /** - * 違う SpanPack を扱う場合、 - * 現在の SpanPack をメインメモリに送り、 - * 新しい SpanPack を取ってくる - */ - if (index != prev_index) { - tmp_spack = spack; - spack = send_spack; - send_spack = tmp_spack; - - smanager->dma_wait(SPAN_PACK_STORE); - smanager->dma_store(send_spack, (uint32)spackList[prev_index], - sizeof(SpanPack), SPAN_PACK_STORE); - - smanager->dma_load(spack, (uint32)spackList[index], - sizeof(SpanPack), SPAN_PACK_LOAD); - prev_index = index; - smanager->dma_wait(SPAN_PACK_LOAD); - } - - /** - * 書き込む SpanPack が満杯だったら - * メインメモリで allocate した領域 (next) を持ってきて - * 現在の spack->next につなぎ、next を次の spack とする。 - */ - if (spack->info.size >= MAX_SIZE_SPAN) { - SpanPackPtr next; - - __debug_spe("CreateSpan mainMem_alloc 0x%x\n", (unsigned int)sizeof(SpanPack)); - smanager->mainMem_alloc(0, sizeof(SpanPack)); - smanager->mainMem_wait(); - next = (SpanPackPtr)smanager->mainMem_get(0); - __debug_spe("CreateSpan mainMem_allocated 0x%x\n", (unsigned int)next); - - spack->next = next; // この部分は TaskManager でやる - - tmp_spack = spack; - spack = send_spack; - send_spack = tmp_spack; - - smanager->dma_wait(SPAN_PACK_STORE); - smanager->dma_store(send_spack, (uint32)spackList[index], - sizeof(SpanPack), SPAN_PACK_STORE); - - spackList[index] = next; - - smanager->dma_load(spack, (uint32)spackList[index], - sizeof(SpanPack), SPAN_PACK_LOAD); - smanager->dma_wait(SPAN_PACK_LOAD); - spack->init((index+1)*split_screen_h); - } - } else { - /** - * 担当範囲外だったら無視 - */ - continue; - } - - tmp_xpos = calc(vMid10->x - vMin->x ,div_y, i, vMin->x); - tmp_end = calc(vMid->x - vMin->x ,div_y, i, vMin->x); - tmp_z = calc(vMid10->z - vMin->z ,div_y, i, vMin->z); - tmp_zpos = calc(vMid->z - vMin->z ,div_y, i, vMin->z); - - length = (tmp_xpos > tmp_end) - ? (int)tmp_xpos - (int)tmp_end : (int)tmp_end - (int)tmp_xpos; - if (length == 0) { - continue; - } - - tmp_tex1 =((i/(div_y)) * vMid10->tex_x) + - ( ((div_y - i)/(div_y)) * vMin->tex_x); - tmp_tex2 =( (i/(div_y)) * vMid->tex_x) + - ( ((div_y - i)/(div_y)) * vMin->tex_x); - - tmp_tey1 =( (i/(div_y)) * vMid10->tex_y) + - ( ((div_y - i)/(div_y)) * vMin->tex_y); - tmp_tey2 =( (i/(div_y)) * vMid->tex_y) + - ( ((div_y - i)/(div_y)) * vMin->tex_y); - - if (tmp_xpos > tmp_end) { - x = (int)tmp_end; - length = (int)(tmp_xpos)-(int)(tmp_end)+1; - start_z = tmp_zpos; - end_z = tmp_z; - start_tex_x = tmp_tex2; - end_tex_x = tmp_tex1; - start_tex_y = tmp_tey2; - end_tex_y = tmp_tey1; - } else { - x = (int)tmp_xpos; - length = (int)(tmp_end)-(int)(tmp_xpos)+1; - start_z = tmp_z; - end_z = tmp_zpos; - start_tex_x = tmp_tex1; - end_tex_x = tmp_tex2; - start_tex_y = tmp_tey1; - end_tex_y = tmp_tey2; - } - - smanager->dma_wait(SPAN_PACK_LOAD); - - Span *span = &spack->span[spack->info.size++]; - - span->x = x; - span->y = y; - span->length_x = length; - span->start_z = start_z; - span->end_z = end_z; - span->tex_x1 = start_tex_x; - span->tex_x2 = end_tex_x; - span->tex_y1 = start_tex_y; - span->tex_y2 = end_tex_y; - - - float tex_x_len = span->tex_x2 - span->tex_x1; - - /** - * tex_x_len, tex_y_len を掛ける理由は - * Changelog の 2008-12-16 を参照 - */ - int scale = getScale(span->length_x, length_y, - (int)(span->tex_width*tex_x_len), - (int)(span->tex_height*tex_y_len), - tex_info->scale_max); - //scale = tex_info->scale_max; - - uint32 *tapestry = getTapestry(tex_info->width, - tex_info->height, scale, - tex_info->addr); - span->tex_addr = tapestry; - span->tex_width = tex_info->width/scale; - span->tex_height = tex_info->height/scale; - } -#else - - /** - * ここに SIMD 化した記述をしようとして断念 - */ - -#endif - -} - - -int -CreateSpan::run(SchedTask *smanager, void *rbuf, void *wbuf) -{ - __debug_spe("CreateSpan\n"); - - PolygonPack *pp = (PolygonPack*)smanager->get_input(0); - PolygonPack *next_pp = - (PolygonPack*)smanager->allocate(sizeof(PolygonPack)); - PolygonPack *free_pp = next_pp; - PolygonPack *tmp_pp; - - TrianglePackPtr triPack; - VertexPackPtr vMin, vMid, vMax; - VertexPackPtr vMid10 - = (VertexPackPtr)smanager->allocate(sizeof(VertexPack)); - - SpanPackPtr *spackList = (SpanPackPtr*)smanager->get_input(1); - spack = (SpanPackPtr)smanager->get_input(2); - send_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); - prev_index = get_param(0); - - // spack と send_spack は swap しながら DMA を繰り返すので - // 自分で allocate した send_spack を覚えてないといけない - SpanPackPtr free_spack = send_spack; - - int charge_y_top = get_param(1); - int charge_y_end = get_param(2); - - do { - __debug_spe("CreateSpan allocated 0x%x\n",(uint32)next_pp); - - if (pp->next != NULL) { - smanager->dma_load(next_pp, (uint32)pp->next, - sizeof(PolygonPack), POLYGON_PACK_LOAD); - } else { - next_pp = NULL; - } - - for (int i = 0; i < pp->info.size; i++) { - triPack = &pp->tri[i]; - - TriangleTexInfoPtr tri_tex_info = &triPack->tex_info; - - make_vertex(triPack, &vMin, &vMid, &vMax); - make_vMid10(vMid10, vMin, vMid, vMax); - - /** - * ポリゴンを、x軸に水平に分割して二つの三角形を作り、 - * それぞれから Span を求める - * - * vMax - * |\ - * | \ - * | \ - * | \ - * vMid10 ------ vMid - * | / - * | / - * | / - * |/ - * vMin - * - * (vMax, vMid, vMin) という triangle を - * (vMax, vMid, vMid10) (vMin, vMid, vMid10) という - * 二つの Triangle に分けている - */ - half_triangle(smanager, spackList, charge_y_top, charge_y_end, - tri_tex_info, vMin, vMid, vMid10, - (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, - (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y); - } - - smanager->dma_wait(POLYGON_PACK_LOAD); - - tmp_pp = pp; - pp = next_pp; - next_pp = tmp_pp; - } while (pp); - - smanager->dma_wait(SPAN_PACK_STORE); - smanager->dma_store(spack, (uint32)spackList[prev_index], - sizeof(SpanPack), SPAN_PACK_STORE); - smanager->dma_wait(SPAN_PACK_STORE); - __debug_spe("CreateSpan spack_stored 0x%x\n",(uint32)spackList[prev_index]); - - // smanager で allocate したのだから free も smanager でやるべき - free(free_pp); - free(free_spack); - free(vMid10); - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawBack.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/DrawBack.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,36 @@ +// #define DEBUG +#include "error.h" + +#include +#include +#include "DrawBack.h" +#include "viewer_types.h" + +SchedDefineTask(DrawBack); + +void +DrawBack::linebuf_init(int *buf, int x, int rgb) +{ + for (int i = 0; i < x; i++) { + buf[i] = rgb; + } +} + +int +DrawBack::run(SchedTask *smanager, void *rbuf, void *wbuf) +{ + __debug_spe("DrawBack\n"); + int rgb = smanager->get_param(0); + int rangex_start = smanager->get_param(1); + int rangex_end = smanager->get_param(2); + int rangey = smanager->get_param(3); + int rangex = rangex_end - rangex_start + 1; + int *linebuf; + + for (int i = 0; i < rangey; i++) { + linebuf = (int*)smanager->get_output(i); + linebuf_init(linebuf, rangex, rgb); + } + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawBack.cpp --- a/TaskManager/Test/test_render/spe/DrawBack.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -// #define DEBUG -#include "error.h" - -#include -#include -#include "DrawBack.h" -#include "viewer_types.h" - -SchedDefineTask(DrawBack); - -void -DrawBack::linebuf_init(int *buf, int x, int rgb) -{ - for (int i = 0; i < x; i++) { - buf[i] = rgb; - } -} - -int -DrawBack::run(SchedTask *smanager, void *rbuf, void *wbuf) -{ - __debug_spe("DrawBack\n"); - int rgb = smanager->get_param(0); - int rangex_start = smanager->get_param(1); - int rangex_end = smanager->get_param(2); - int rangey = smanager->get_param(3); - int rangex = rangex_end - rangex_start + 1; - int *linebuf; - - for (int i = 0; i < rangey; i++) { - linebuf = (int*)smanager->get_output(i); - linebuf_init(linebuf, rangex, rgb); - } - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawSpan.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/DrawSpan.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,497 @@ +// #define DEBUG +#include "error.h" + +#include +#include +#include +#include "DrawSpan.h" +#include "polygon_pack.h" +#include "texture.h" +#include "viewer_types.h" +#include "Func.h" +#include "global_alloc.h" + +SchedDefineTask(DrawSpan); + +#define TEX_LOAD1 0 +#define TEX_LOAD2 1 +#define SPAN_PACK_LOAD 2 +#define FB_STORE 3 + +DrawSpan::~DrawSpan(void) +{ + smanager->dma_wait(FB_STORE); + 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 のブロックに分割する + * + * +---+---+---+---+---+---+ + * | 0 | 1 | 2 | 3 | 4 | 5 | + * +---+---+---+---+---+---+ + * | | | | | |11 | + * +---+---+---+---+---+---+ + * | | | | | |17 | + * +---+---+---+---+---+---+ + * | | | | | |23 | + * +---+---+---+---+---+---+ + * | | | | | |29 | + * +---+---+---+---+---+---+ + * | | | | | |35 | + * +---+---+---+---+---+---+ + * + * 一辺を TEXTURE_SPLIT とする + * 各ブロックの数字がブロックIDとなる。 + */ + +/** + * テクスチャの座標から、 + * テクスチャのどのブロックかを求める + * + * @param[in] tx X coordinates of texture + * @param[in] tx Y coordinates of texture + * @param[in] twidth Width of texture + * @return block ID + */ +int +DrawSpan::getTexBlock(int tx, int ty, int twidth) +{ + int blockX, blockY; + + blockX = tx / TEXTURE_SPLIT_PIXEL; + blockY = ty / TEXTURE_SPLIT_PIXEL; + + return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY; +} + +/** + * block ID と、テクスチャの TOP address から + * (tx,ty) で使われるテクスチャの Tile addres を求める + * + * @param[in] tx X coordinates of texture + * @param[in] tx Y coordinates of texture + * @param[in] tw Width of texture + * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address + * @return block ID + */ +memaddr +DrawSpan::getTile(int tx, int ty, int tw, memaddr tex_addr_top) +{ + int block = getTexBlock(tx, ty, tw); + return tex_addr_top + block*TEXTURE_BLOCK_SIZE * sizeof(uint32); +} + +/** + * FrameBuffer に書き込む rgb の領域初期化 + * + * @param width Width of Buffer + * @param height Height of Buffer + * @param rgb Initial value of RGB at Buffer + * @return Buffer + */ +int* +DrawSpan::linebuf_init(int width, int height, int rgb) +{ + int *buf = (int*)smanager->allocate(sizeof(int)*width*height); + + for (int i = 0; i < width*height; i++) { + buf[i] = rgb; + } + + return buf; +} + +/** + * Z-Buffer の初期化 + * + * @param width Width of Z-Buffer + * @param height Height of Z-Buffer + * @return Z-Buffer + */ +float* +DrawSpan::zRow_init(int width, int height) +{ + float *buf = (float*)smanager->allocate(sizeof(float)*width*height); + float def = 65535.0f; + + 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); + } + + return buf; +} + + +uint32 +DrawSpan::get_rgb(int tx, int ty, TilePtr tile) +{ + uint32 *data = (uint32 *)tile->data; + return data[(TEXTURE_SPLIT_PIXEL)*ty+tx]; +} + +#if 0 +/** + * DrawSpan の再起動 (DrawSpanRenew 生成) + * + * @param[in] spack 現在処理している SpanPack + * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で + * どこまで進んでいるか + */ +void +DrawSpan::reboot(SpanPackPtr spack, int cur_span_x) +{ + DrawSpanArgPtr args = + (DrawSpanArgPtr)smanager->allocate(sizeof(DrawSpanArg)); + TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); + + // 数が多いので構造体で渡す + args->display = smanager->get_param(0); + args->screen_width = smanager->get_param(1); + args->rangex_start = smanager->get_param(2); + args->rangex_end = smanager->get_param(3); + args->rangey = smanager->get_param(4); + renew_task->add_param((int)args); + + /** + * SpanPack は続きから開始するので、 + * 現在の状態をコピーしておく。 + * spack は rbuf から取得してる可能性があり + * rbuf はシステムが自動的に free() するため + * アドレスだけ渡すのはNG + */ + SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + memcpy(curr, spack, sizeof(SpanPack)); + renew_task->add_param((int)curr); + renew_task->add_param(cur_span_x); + + // linebuf と zRow も引き継がせる + renew_task->add_param((int)linebuf); + renew_task->add_param((int)zRow); + + /** + * 再起動したタスクを待つ + */ + smanager->wait_task(renew_task); + + // next_spack は free() するので wait する + smanager->dma_wait(SPAN_PACK_LOAD); +} +#endif + +void +DrawSpan::writebuffer(unsigned int display, int buf_width, int height, + int screen_width) +{ + for (int i = 0; i < height; i++) { + smanager->dma_store(&linebuf[i*buf_width], + display + (sizeof(int)*screen_width*i), + sizeof(int)*buf_width, FB_STORE); + } + + doneWrite = 1; +} + +/** + * zRow と Linebuf を更新する + * + * @param zpos 更新する pixel のZ座標 + * @param rangex このタスクが処理する描画領域の x の長さ + * @param x pixel の、描画領域内での x 座標 + * @param y 〃 の、y 座標 + * @param tex_x pixel が使用するテクスチャの、Tile (8x8) 内での x 座標 + * @param tex_y 〃 の y 座標 + * @param tex_addr テクスチャのアドレス(MainMemory) + */ +void +DrawSpan::updateBuffer(float zpos, int rangex, int x, int y, + int tex_x, int tex_y, TilePtr tile) +{ + int rgb = get_rgb(tex_x, tex_y, tile); + + zRow[x + (rangex*y)] = zpos; + linebuf[x + (rangex*y)] = rgb; +} + +/** + * 長さが 1 の Span の描画 (要するに 1 pixel) + * + * @param span Span + * @param startx 描画開始範囲 + * @param endx 描画終了範囲 + */ +int +DrawSpan::drawDot1(SpanPtr span, int startx, int endx, int wait_tag) +{ + int rangex = endx - startx + 1; + + /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ + int tex_xpos, tex_ypos; + + // span の始点に対応する Texture の座標 (tex1, tey1) + float tex = span->tex_x1; + float tey = span->tex_y1; + + // span の始点に対応する z 座標 + float zpos = span->start_z; + + /* Tile 内での座標 */ + int localx = getLocalX(span->x-1); + int localy = getLocalY(span->y-1); + + /** + * (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と + * そのブロックのアドレス(MainMemory) + */ + int tex_localx; + int tex_localy; + memaddr tex_addr; + + if (span->x < startx || endx < span->x) { + return -1; + } + + tex_xpos = (int)((span->tex_width-1) * tex); + tex_ypos = (int)((span->tex_height-1) * tey); + + if (zpos < zRow[localx + (rangex*localy)]) { + 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,tileList); + smanager->wait_segment(tile); + + updateBuffer(zpos, rangex, localx, localy, + tex_localx, tex_localy, tile); + } + + return -1; +} + + +/** + * 長さが 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) +{ + int x = span->x; + int rangex = endx - startx + 1; + int x_len = span->length_x; + + 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; + + // 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; + + // 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_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 (tex_z < zRow[localx + (rangex*localy)]) { + // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と + // そのブロックのアドレス(MainMemory) + memaddr tex_addr; + int tex_localx; + int tex_localy; + + 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,tileList); + smanager->wait_segment(tile); + + updateBuffer(tex_z, rangex, localx, localy, + tex_localx, tex_localy, tile); + } + } + + return ret; +} + +int +DrawSpan::run(SchedTask *smanager, void *rbuf, void *wbuf) +{ + __debug_spe("DrawSpan\n"); + this->smanager = smanager; + SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0); + SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + SpanPackPtr free_spack = next_spack; // next_spack の free() 用 + Span *span; + + Span nop_span; + nop_span.length_x = 1; + + int (DrawSpan::*drawFunc1[2])(SpanPtr, int, int, int) = { + &DrawSpan::drawDot1, &DrawSpan::drawLine1 + }; + + uint32 display = smanager->get_param(0); + int screen_width = smanager->get_param(1); + int rangex_start = smanager->get_param(2); + int rangex_end = smanager->get_param(3); + + // このタスクが担当する x の範囲 + int rangex = rangex_end - rangex_start + 1; + + // y の範囲 + int rangey = smanager->get_param(4); + + tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); + + zRow = zRow_init(rangex, rangey); + //linebuf = linebuf_init(rangex, rangey, 0x00ffffff); + linebuf = linebuf_init(rangex, rangey, 0); + + doneWrite = 0; + + int tl_tag[2] = {TEX_LOAD1, TEX_LOAD2}; + int tl_tag_flg1 = 0; + int tl_tag_flg2 = 1; + + do { + /** + * SpanPack->next が存在する場合、 + * 現在の SpanPack を処理してる間に + * 次の SpanPack の DMA 転送を行う + */ + if (spack->next != NULL) { + smanager->dma_load(next_spack, (memaddr)spack->next, + sizeof(SpanPack), SPAN_PACK_LOAD); + } else { + next_spack = NULL; + } + + SpanPtr resume_span = &nop_span; + int resume_span_x = 0; + + for (int t = 0; t < spack->info.size; t++) { + SpanPtr next_span; + int next_span_x; + + 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]); + next_span = span; + + resume_span = next_span; + resume_span_x = next_span_x; + + //smanager->dma_wait(tl_tag[tl_tag_flg1]); + + tl_tag_flg1 ^= 1; + tl_tag_flg2 ^= 1; + } + + // 現在 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); + + SpanPackPtr tmp_spack = spack; + spack = next_spack; + next_spack = tmp_spack; + } while (spack); + + writebuffer(display, rangex, rangey, screen_width); + + // linebuf は、writebuffer() の dma_store を wait する + // DrawSpan::~DrawSpan() 内で free する。 + //free(linebuf); + free(zRow); + +//FINISH: + /** + * goto FINISH; の時は reboot なので + * linebuf, zRow は free() しない + */ + + free(free_spack); + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawSpan.cpp --- a/TaskManager/Test/test_render/spe/DrawSpan.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,497 +0,0 @@ -// #define DEBUG -#include "error.h" - -#include -#include -#include -#include "DrawSpan.h" -#include "polygon_pack.h" -#include "texture.h" -#include "viewer_types.h" -#include "Func.h" -#include "global_alloc.h" - -SchedDefineTask(DrawSpan); - -#define TEX_LOAD1 0 -#define TEX_LOAD2 1 -#define SPAN_PACK_LOAD 2 -#define FB_STORE 3 - -DrawSpan::~DrawSpan(void) -{ - smanager->dma_wait(FB_STORE); - 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 のブロックに分割する - * - * +---+---+---+---+---+---+ - * | 0 | 1 | 2 | 3 | 4 | 5 | - * +---+---+---+---+---+---+ - * | | | | | |11 | - * +---+---+---+---+---+---+ - * | | | | | |17 | - * +---+---+---+---+---+---+ - * | | | | | |23 | - * +---+---+---+---+---+---+ - * | | | | | |29 | - * +---+---+---+---+---+---+ - * | | | | | |35 | - * +---+---+---+---+---+---+ - * - * 一辺を TEXTURE_SPLIT とする - * 各ブロックの数字がブロックIDとなる。 - */ - -/** - * テクスチャの座標から、 - * テクスチャのどのブロックかを求める - * - * @param[in] tx X coordinates of texture - * @param[in] tx Y coordinates of texture - * @param[in] twidth Width of texture - * @return block ID - */ -int -DrawSpan::getTexBlock(int tx, int ty, int twidth) -{ - int blockX, blockY; - - blockX = tx / TEXTURE_SPLIT_PIXEL; - blockY = ty / TEXTURE_SPLIT_PIXEL; - - return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY; -} - -/** - * block ID と、テクスチャの TOP address から - * (tx,ty) で使われるテクスチャの Tile addres を求める - * - * @param[in] tx X coordinates of texture - * @param[in] tx Y coordinates of texture - * @param[in] tw Width of texture - * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address - * @return block ID - */ -memaddr -DrawSpan::getTile(int tx, int ty, int tw, memaddr tex_addr_top) -{ - int block = getTexBlock(tx, ty, tw); - return tex_addr_top + block*TEXTURE_BLOCK_SIZE * sizeof(uint32); -} - -/** - * FrameBuffer に書き込む rgb の領域初期化 - * - * @param width Width of Buffer - * @param height Height of Buffer - * @param rgb Initial value of RGB at Buffer - * @return Buffer - */ -int* -DrawSpan::linebuf_init(int width, int height, int rgb) -{ - int *buf = (int*)smanager->allocate(sizeof(int)*width*height); - - for (int i = 0; i < width*height; i++) { - buf[i] = rgb; - } - - return buf; -} - -/** - * Z-Buffer の初期化 - * - * @param width Width of Z-Buffer - * @param height Height of Z-Buffer - * @return Z-Buffer - */ -float* -DrawSpan::zRow_init(int width, int height) -{ - float *buf = (float*)smanager->allocate(sizeof(float)*width*height); - float def = 65535.0f; - - 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); - } - - return buf; -} - - -uint32 -DrawSpan::get_rgb(int tx, int ty, TilePtr tile) -{ - uint32 *data = (uint32 *)tile->data; - return data[(TEXTURE_SPLIT_PIXEL)*ty+tx]; -} - -#if 0 -/** - * DrawSpan の再起動 (DrawSpanRenew 生成) - * - * @param[in] spack 現在処理している SpanPack - * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で - * どこまで進んでいるか - */ -void -DrawSpan::reboot(SpanPackPtr spack, int cur_span_x) -{ - DrawSpanArgPtr args = - (DrawSpanArgPtr)smanager->allocate(sizeof(DrawSpanArg)); - TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); - - // 数が多いので構造体で渡す - args->display = smanager->get_param(0); - args->screen_width = smanager->get_param(1); - args->rangex_start = smanager->get_param(2); - args->rangex_end = smanager->get_param(3); - args->rangey = smanager->get_param(4); - renew_task->add_param((int)args); - - /** - * SpanPack は続きから開始するので、 - * 現在の状態をコピーしておく。 - * spack は rbuf から取得してる可能性があり - * rbuf はシステムが自動的に free() するため - * アドレスだけ渡すのはNG - */ - SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); - memcpy(curr, spack, sizeof(SpanPack)); - renew_task->add_param((int)curr); - renew_task->add_param(cur_span_x); - - // linebuf と zRow も引き継がせる - renew_task->add_param((int)linebuf); - renew_task->add_param((int)zRow); - - /** - * 再起動したタスクを待つ - */ - smanager->wait_task(renew_task); - - // next_spack は free() するので wait する - smanager->dma_wait(SPAN_PACK_LOAD); -} -#endif - -void -DrawSpan::writebuffer(unsigned int display, int buf_width, int height, - int screen_width) -{ - for (int i = 0; i < height; i++) { - smanager->dma_store(&linebuf[i*buf_width], - display + (sizeof(int)*screen_width*i), - sizeof(int)*buf_width, FB_STORE); - } - - doneWrite = 1; -} - -/** - * zRow と Linebuf を更新する - * - * @param zpos 更新する pixel のZ座標 - * @param rangex このタスクが処理する描画領域の x の長さ - * @param x pixel の、描画領域内での x 座標 - * @param y 〃 の、y 座標 - * @param tex_x pixel が使用するテクスチャの、Tile (8x8) 内での x 座標 - * @param tex_y 〃 の y 座標 - * @param tex_addr テクスチャのアドレス(MainMemory) - */ -void -DrawSpan::updateBuffer(float zpos, int rangex, int x, int y, - int tex_x, int tex_y, TilePtr tile) -{ - int rgb = get_rgb(tex_x, tex_y, tile); - - zRow[x + (rangex*y)] = zpos; - linebuf[x + (rangex*y)] = rgb; -} - -/** - * 長さが 1 の Span の描画 (要するに 1 pixel) - * - * @param span Span - * @param startx 描画開始範囲 - * @param endx 描画終了範囲 - */ -int -DrawSpan::drawDot1(SpanPtr span, int startx, int endx, int wait_tag) -{ - int rangex = endx - startx + 1; - - /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ - int tex_xpos, tex_ypos; - - // span の始点に対応する Texture の座標 (tex1, tey1) - float tex = span->tex_x1; - float tey = span->tex_y1; - - // span の始点に対応する z 座標 - float zpos = span->start_z; - - /* Tile 内での座標 */ - int localx = getLocalX(span->x-1); - int localy = getLocalY(span->y-1); - - /** - * (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と - * そのブロックのアドレス(MainMemory) - */ - int tex_localx; - int tex_localy; - memaddr tex_addr; - - if (span->x < startx || endx < span->x) { - return -1; - } - - tex_xpos = (int)((span->tex_width-1) * tex); - tex_ypos = (int)((span->tex_height-1) * tey); - - if (zpos < zRow[localx + (rangex*localy)]) { - 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,tileList); - smanager->wait_segment(tile); - - updateBuffer(zpos, rangex, localx, localy, - tex_localx, tex_localy, tile); - } - - return -1; -} - - -/** - * 長さが 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) -{ - int x = span->x; - int rangex = endx - startx + 1; - int x_len = span->length_x; - - 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; - - // 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; - - // 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_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 (tex_z < zRow[localx + (rangex*localy)]) { - // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と - // そのブロックのアドレス(MainMemory) - memaddr tex_addr; - int tex_localx; - int tex_localy; - - 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,tileList); - smanager->wait_segment(tile); - - updateBuffer(tex_z, rangex, localx, localy, - tex_localx, tex_localy, tile); - } - } - - return ret; -} - -int -DrawSpan::run(SchedTask *smanager, void *rbuf, void *wbuf) -{ - __debug_spe("DrawSpan\n"); - this->smanager = smanager; - SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0); - SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); - SpanPackPtr free_spack = next_spack; // next_spack の free() 用 - Span *span; - - Span nop_span; - nop_span.length_x = 1; - - int (DrawSpan::*drawFunc1[2])(SpanPtr, int, int, int) = { - &DrawSpan::drawDot1, &DrawSpan::drawLine1 - }; - - uint32 display = smanager->get_param(0); - int screen_width = smanager->get_param(1); - int rangex_start = smanager->get_param(2); - int rangex_end = smanager->get_param(3); - - // このタスクが担当する x の範囲 - int rangex = rangex_end - rangex_start + 1; - - // y の範囲 - int rangey = smanager->get_param(4); - - tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); - - zRow = zRow_init(rangex, rangey); - //linebuf = linebuf_init(rangex, rangey, 0x00ffffff); - linebuf = linebuf_init(rangex, rangey, 0); - - doneWrite = 0; - - int tl_tag[2] = {TEX_LOAD1, TEX_LOAD2}; - int tl_tag_flg1 = 0; - int tl_tag_flg2 = 1; - - do { - /** - * SpanPack->next が存在する場合、 - * 現在の SpanPack を処理してる間に - * 次の SpanPack の DMA 転送を行う - */ - if (spack->next != NULL) { - smanager->dma_load(next_spack, (memaddr)spack->next, - sizeof(SpanPack), SPAN_PACK_LOAD); - } else { - next_spack = NULL; - } - - SpanPtr resume_span = &nop_span; - int resume_span_x = 0; - - for (int t = 0; t < spack->info.size; t++) { - SpanPtr next_span; - int next_span_x; - - 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]); - next_span = span; - - resume_span = next_span; - resume_span_x = next_span_x; - - //smanager->dma_wait(tl_tag[tl_tag_flg1]); - - tl_tag_flg1 ^= 1; - tl_tag_flg2 ^= 1; - } - - // 現在 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); - - SpanPackPtr tmp_spack = spack; - spack = next_spack; - next_spack = tmp_spack; - } while (spack); - - writebuffer(display, rangex, rangey, screen_width); - - // linebuf は、writebuffer() の dma_store を wait する - // DrawSpan::~DrawSpan() 内で free する。 - //free(linebuf); - free(zRow); - -//FINISH: - /** - * goto FINISH; の時は reboot なので - * linebuf, zRow は free() しない - */ - - free(free_spack); - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawSpanRenew.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/DrawSpanRenew.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,220 @@ +#if 0 +// #define DEBUG +#include "error.h" + +#include +#include +#include +#include "DrawSpanRenew.h" +#include "polygon_pack.h" +#include "SpanPack.h" +#include "texture.h" +#include "viewer_types.h" +#include "Func.h" +#include "global_alloc.h" + +#define SPAN_PACK_LOAD 0 +#define TEX_LOAD 1 +#define FB_STORE 2 + +SchedDefineTask(DrawSpanRenew); + +void +DrawSpanRenew::reboot(SpanPackPtr spack, int cur_span_x) +{ + TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); + + renew_task->add_param((int)args); + + SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + memcpy(curr, spack, sizeof(SpanPack)); + renew_task->add_param((int)curr); + renew_task->add_param(cur_span_x); + + // linebuf と zRow も引き継がせる + renew_task->add_param((int)linebuf); + renew_task->add_param((int)zRow); + + //fprintf(stderr, "[%p] start %u\n", curr, spu_readch(SPU_RdDec)); + + /** + * 再起動したタスクを待つ + */ + smanager->wait_task(renew_task); + + // next_spack は free() するので wait する + smanager->dma_wait(SPAN_PACK_LOAD); +} + +int +DrawSpanRenew::run(void *rbuf, void *wbuf) +{ + __debug_spe("DrawSpanRenew\n"); + SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1); + SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); + SpanPackPtr free_spack1 = spack; + SpanPackPtr free_spack2 = next_spack; + Span *span; + + args = (DrawSpanArgPtr)smanager->get_param(0); + uint32 display = args->display; + int screen_width = args->screen_width; + int rangex_start = args->rangex_start; + int rangex_end = args->rangex_end; + + // このタスクが担当する x の範囲 + int rangex = rangex_end - rangex_start + 1; + + // y の範囲 (render_y + rangey - 1) + int rangey = args->rangey; + + hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH); + tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); + + linebuf = (int*)smanager->get_param(3); + zRow = (float*)smanager->get_param(4); + + doneWrite = 0; + + // span->length_x の処理での再起動位置 + int js_cont = smanager->get_param(2); + + //fprintf(stderr, "[%p] end %u\n", spack, spu_readch(SPU_RdDec)); + + smanager->dma_wait(TEX_LOAD); + + do { + /** + * SpanPack->next が存在する場合、 + * 現在の SpanPack を処理してる間に + * 次の SpanPack の DMA 転送を行う + */ + if (spack->next != NULL) { + smanager->dma_load(next_spack, (memaddr)spack->next, + sizeof(SpanPack), SPAN_PACK_LOAD); + } else { + next_spack = NULL; + } + + for (int t = spack->info.start; t < spack->info.size; t++) { + span = &spack->span[t]; + + uint32 rgb = 0x00ff0000; + float tex1 = span->tex_x1; + float tex2 = span->tex_x2; + float tey1 = span->tex_y1; + float tey2 = span->tex_y2; + + /** + * Span が持つ 1 pixel 毎の + * テクスチャの座標 + */ + int tex_xpos; + int tex_ypos; + + /** + * (tex_xpos, tex_ypos) の、ブロック内(上の図参照)での座標と + * そのブロックのアドレス(MainMemory) + */ + int tex_localx; + int tex_localy; + memaddr tex_addr; + + int x = span->x; + int y = span->y; + int x_len = span->length_x; + float z = span->start_z; + float zpos = span->end_z; + + // 座標が [0 .. split_screen_w-1] に入るように x,y を -1 + int localx = getLocalX(x-1); + int localy = getLocalY(y-1); + + if (x_len == 1) { + if (x < rangex_start || rangex_end < x) { + continue; + } + + tex_xpos = (int)((span->tex_width-1) * tex1); + tex_ypos = (int)((span->tex_height-1) * tey1); + + if (zpos < zRow[localx + (rangex * localy)]) { + 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,tileList); + smanager->wait_segment(tile); + + rgb = get_rgb(tex_localx, tex_localy, tile); + + zRow[localx + (rangex*localy)] = zpos; + linebuf[localx + (rangex*localy)] = rgb; + } + } else { + int js = (x < rangex_start) ? rangex_start - x : 0; + int je = (x + x_len > rangex_end) ? rangex_end - x : x_len; + float tex_x, tex_y, tex_z; + + /** + * 一回比較すれば、以後再起動するまでは + * js_cont は使わないから 0 にしてるわけだけど、 + * 最初の一回のためだけにこれはめんどくさいのー。 + */ + js = (js < js_cont) ? js_cont : js; + js_cont = 0; + + for (int j = js; j <= je; j++) { + localx = getLocalX(x-1+j); + + tex_z = z*(x_len-1-j)/(x_len-1) + zpos*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 < zRow[localx + (rangex*localy)]) { + 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,tileList); + smanager->wait_segment(tile); + + rgb = get_rgb(tex_localx, tex_localy, tile); + + zRow[localx + (rangex*localy)] = tex_z; + linebuf[localx + (rangex*localy)] = rgb; + } + } + } + } + + smanager->dma_wait(SPAN_PACK_LOAD); + + SpanPackPtr tmp_spack = spack; + spack = next_spack; + next_spack = tmp_spack; + } while (spack); + + writebuffer(display, rangex, rangey, screen_width); + + free(zRow); + free(args); + + /** + * linebuf, zRow, args は RenewTask が引き継ぐ + */ + free(free_spack1); + free(free_spack2); + + return 0; +} +#endif diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/DrawSpanRenew.cpp --- a/TaskManager/Test/test_render/spe/DrawSpanRenew.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -#if 0 -// #define DEBUG -#include "error.h" - -#include -#include -#include -#include "DrawSpanRenew.h" -#include "polygon_pack.h" -#include "SpanPack.h" -#include "texture.h" -#include "viewer_types.h" -#include "Func.h" -#include "global_alloc.h" - -#define SPAN_PACK_LOAD 0 -#define TEX_LOAD 1 -#define FB_STORE 2 - -SchedDefineTask(DrawSpanRenew); - -void -DrawSpanRenew::reboot(SpanPackPtr spack, int cur_span_x) -{ - TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); - - renew_task->add_param((int)args); - - SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); - memcpy(curr, spack, sizeof(SpanPack)); - renew_task->add_param((int)curr); - renew_task->add_param(cur_span_x); - - // linebuf と zRow も引き継がせる - renew_task->add_param((int)linebuf); - renew_task->add_param((int)zRow); - - //fprintf(stderr, "[%p] start %u\n", curr, spu_readch(SPU_RdDec)); - - /** - * 再起動したタスクを待つ - */ - smanager->wait_task(renew_task); - - // next_spack は free() するので wait する - smanager->dma_wait(SPAN_PACK_LOAD); -} - -int -DrawSpanRenew::run(void *rbuf, void *wbuf) -{ - __debug_spe("DrawSpanRenew\n"); - SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1); - SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); - SpanPackPtr free_spack1 = spack; - SpanPackPtr free_spack2 = next_spack; - Span *span; - - args = (DrawSpanArgPtr)smanager->get_param(0); - uint32 display = args->display; - int screen_width = args->screen_width; - int rangex_start = args->rangex_start; - int rangex_end = args->rangex_end; - - // このタスクが担当する x の範囲 - int rangex = rangex_end - rangex_start + 1; - - // y の範囲 (render_y + rangey - 1) - int rangey = args->rangey; - - hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH); - tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); - - linebuf = (int*)smanager->get_param(3); - zRow = (float*)smanager->get_param(4); - - doneWrite = 0; - - // span->length_x の処理での再起動位置 - int js_cont = smanager->get_param(2); - - //fprintf(stderr, "[%p] end %u\n", spack, spu_readch(SPU_RdDec)); - - smanager->dma_wait(TEX_LOAD); - - do { - /** - * SpanPack->next が存在する場合、 - * 現在の SpanPack を処理してる間に - * 次の SpanPack の DMA 転送を行う - */ - if (spack->next != NULL) { - smanager->dma_load(next_spack, (memaddr)spack->next, - sizeof(SpanPack), SPAN_PACK_LOAD); - } else { - next_spack = NULL; - } - - for (int t = spack->info.start; t < spack->info.size; t++) { - span = &spack->span[t]; - - uint32 rgb = 0x00ff0000; - float tex1 = span->tex_x1; - float tex2 = span->tex_x2; - float tey1 = span->tex_y1; - float tey2 = span->tex_y2; - - /** - * Span が持つ 1 pixel 毎の - * テクスチャの座標 - */ - int tex_xpos; - int tex_ypos; - - /** - * (tex_xpos, tex_ypos) の、ブロック内(上の図参照)での座標と - * そのブロックのアドレス(MainMemory) - */ - int tex_localx; - int tex_localy; - memaddr tex_addr; - - int x = span->x; - int y = span->y; - int x_len = span->length_x; - float z = span->start_z; - float zpos = span->end_z; - - // 座標が [0 .. split_screen_w-1] に入るように x,y を -1 - int localx = getLocalX(x-1); - int localy = getLocalY(y-1); - - if (x_len == 1) { - if (x < rangex_start || rangex_end < x) { - continue; - } - - tex_xpos = (int)((span->tex_width-1) * tex1); - tex_ypos = (int)((span->tex_height-1) * tey1); - - if (zpos < zRow[localx + (rangex * localy)]) { - 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,tileList); - smanager->wait_segment(tile); - - rgb = get_rgb(tex_localx, tex_localy, tile); - - zRow[localx + (rangex*localy)] = zpos; - linebuf[localx + (rangex*localy)] = rgb; - } - } else { - int js = (x < rangex_start) ? rangex_start - x : 0; - int je = (x + x_len > rangex_end) ? rangex_end - x : x_len; - float tex_x, tex_y, tex_z; - - /** - * 一回比較すれば、以後再起動するまでは - * js_cont は使わないから 0 にしてるわけだけど、 - * 最初の一回のためだけにこれはめんどくさいのー。 - */ - js = (js < js_cont) ? js_cont : js; - js_cont = 0; - - for (int j = js; j <= je; j++) { - localx = getLocalX(x-1+j); - - tex_z = z*(x_len-1-j)/(x_len-1) + zpos*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 < zRow[localx + (rangex*localy)]) { - 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,tileList); - smanager->wait_segment(tile); - - rgb = get_rgb(tex_localx, tex_localy, tile); - - zRow[localx + (rangex*localy)] = tex_z; - linebuf[localx + (rangex*localy)] = rgb; - } - } - } - } - - smanager->dma_wait(SPAN_PACK_LOAD); - - SpanPackPtr tmp_spack = spack; - spack = next_spack; - next_spack = tmp_spack; - } while (spack); - - writebuffer(display, rangex, rangey, screen_width); - - free(zRow); - free(args); - - /** - * linebuf, zRow, args は RenewTask が引き継ぐ - */ - free(free_spack1); - free(free_spack2); - - return 0; -} -#endif diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/Load_Texture.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/Load_Texture.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,29 @@ +// #define DEBUG +#include "error.h" + +#include +#include +#include "Load_Texture.h" +#include "texture.h" +#if !USE_MEMHASH +#include "TileHash.h" +#endif +#include "Func.h" +#include "global_alloc.h" + +SchedDefineTask(LoadTexture); + +/** + * 「Load」といいながら、結局 DrawSpan で使う + * Hash の準備だけなので、名前変えないとなー + */ +int +LoadTexture::run(SchedTask *smanager, void *rbuf , void *wbuf) +{ + __debug_spe("LoadTexture\n"); + + MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE); + smanager->global_set(GLOBAL_TILE_LIST, (void *)ml); + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/Load_Texture.cpp --- a/TaskManager/Test/test_render/spe/Load_Texture.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -// #define DEBUG -#include "error.h" - -#include -#include -#include "Load_Texture.h" -#include "texture.h" -#if !USE_MEMHASH -#include "TileHash.h" -#endif -#include "Func.h" -#include "global_alloc.h" - -SchedDefineTask(LoadTexture); - -/** - * 「Load」といいながら、結局 DrawSpan で使う - * Hash の準備だけなので、名前変えないとなー - */ -int -LoadTexture::run(SchedTask *smanager, void *rbuf , void *wbuf) -{ - __debug_spe("LoadTexture\n"); - - MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE); - smanager->global_set(GLOBAL_TILE_LIST, (void *)ml); - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/Makefile --- a/TaskManager/Test/test_render/spe/Makefile Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/spe/Makefile Thu Sep 24 16:06:01 2009 +0900 @@ -4,19 +4,19 @@ TOP = ../$(CERIUM) -SRCS_TMP = $(wildcard *.cpp) -SRCS_EXCLUDE = CreatePolygon.cpp +SRCS_TMP = $(wildcard *.cc) +SRCS_EXCLUDE = CreatePolygon.cc SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP)) -OBJS = $(SRCS:.cpp=.o) +OBJS = $(SRCS:.cc=.o) CC = spu-g++ CFLAGS = -O9 -Wall -g -fno-exceptions -fno-rtti -DUSE_MEMLIST=1 -DUSE_MEMHASH=1 #-DDEBUG INCLUDE = -I$(TOP)/include/TaskManager -I. -I.. LIBS = -L$(TOP)/TaskManager -lspemanager -.SUFFIXES: .cpp .o +.SUFFIXES: .cc .o -.cpp.o: +.cc.o: $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ all: $(TARGET) diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/Set_Texture.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/Set_Texture.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,35 @@ +// #define DEBUG +#include "error.h" +#include +#include "Set_Texture.h" +#include "texture.h" +#include "global_alloc.h" + +SchedDefineTask(SetTexture); + +//texture をglobal 領域にコピーするタスク +int +SetTexture::run(void *rbuf, void *wbuf) +{ + __debug_spe("SetTexture\n"); + void *src[4]; + + src[0] = get_input(rbuf, 0); + src[1] = get_input(rbuf, 1); + src[2] = get_input(rbuf, 2); + src[3] = get_input(rbuf, 3); + + if (global_get(TEXTURE_ID)) { + return 0; + } else { + //タスクが共有できる領域確保 + void *data = global_alloc(TEXTURE_ID, MAX_LOAD_SIZE*4); + + memcpy(data, src[0], MAX_LOAD_SIZE); + memcpy((void*)((int)data + MAX_LOAD_SIZE), src[1], MAX_LOAD_SIZE); + memcpy((void*)((int)data + MAX_LOAD_SIZE*2), src[2], MAX_LOAD_SIZE); + memcpy((void*)((int)data + MAX_LOAD_SIZE*3), src[3], MAX_LOAD_SIZE); + } + + return 0; +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/Set_Texture.cpp --- a/TaskManager/Test/test_render/spe/Set_Texture.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -// #define DEBUG -#include "error.h" -#include -#include "Set_Texture.h" -#include "texture.h" -#include "global_alloc.h" - -SchedDefineTask(SetTexture); - -//texture をglobal 領域にコピーするタスク -int -SetTexture::run(void *rbuf, void *wbuf) -{ - __debug_spe("SetTexture\n"); - void *src[4]; - - src[0] = get_input(rbuf, 0); - src[1] = get_input(rbuf, 1); - src[2] = get_input(rbuf, 2); - src[3] = get_input(rbuf, 3); - - if (global_get(TEXTURE_ID)) { - return 0; - } else { - //タスクが共有できる領域確保 - void *data = global_alloc(TEXTURE_ID, MAX_LOAD_SIZE*4); - - memcpy(data, src[0], MAX_LOAD_SIZE); - memcpy((void*)((int)data + MAX_LOAD_SIZE), src[1], MAX_LOAD_SIZE); - memcpy((void*)((int)data + MAX_LOAD_SIZE*2), src[2], MAX_LOAD_SIZE); - memcpy((void*)((int)data + MAX_LOAD_SIZE*3), src[3], MAX_LOAD_SIZE); - } - - return 0; -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ShowTime.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/ShowTime.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,17 @@ +#include "ShowTime.h" +#include "stdio.h" + +SchedDefineTask(ShowTime); + +int +ShowTime::run(SchedTask *smanager, void *rbuf, void *wbuf) +{ + /* + * ここで show_dma_wait() を呼びたい + */ + smanager->show_dma_wait(); + //printf("Show Time !\n"); + + return 0; +} + diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/ShowTime.cpp --- a/TaskManager/Test/test_render/spe/ShowTime.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -#include "ShowTime.h" -#include "stdio.h" - -SchedDefineTask(ShowTime); - -int -ShowTime::run(SchedTask *smanager, void *rbuf, void *wbuf) -{ - /* - * ここで show_dma_wait() を呼びたい - */ - smanager->show_dma_wait(); - //printf("Show Time !\n"); - - return 0; -} - diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/TileHash.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/TileHash.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,88 @@ +#include +#include +#include +#include "TileHash.h" + +static unsigned short PRIME[8] = { + 0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd, +}; + +int +TileHash::hash(memaddr data) +{ + int value = 0; + int n = 0; + int key; + + for (uint32 i = 0; i < sizeof(memaddr) * 2; i ++) { + key = data & 0xf; + value += key * PRIME[n++ & 7]; + data >>= 4; + } + + return value % hashSize; +} + +TileHash::TileHash(void) +{ + //hashSize = 263; + //tableSize = sizeof(TilePtr)*hashSize; + + table = (TilePtr*)malloc(tableSize); + clear(); +} + +int +TileHash::put(memaddr key, TilePtr data) +{ + int hashval = hash(key); + + for (int i = 0; i < hashSize/2; i++) { + int index = (hashval + i*i)%hashSize; + + if (table[index] == 0) { // 空の table に入れる + table[index] = data; + return index; + } + } + + return -1; +} + +TilePtr +TileHash::get(memaddr key) +{ + int hashval = hash(key); + + for (int i = 0; i < hashSize/2; i++) { + int index = (hashval + i*i)%hashSize; + + if (table[index] != NULL && + table[index]->address == key) { + return table[index]; + } + } + + return NULL; +} + +void +TileHash::remove(memaddr key) +{ + int hashval = hash(key); + + for (int i = 0; i < hashSize/2; i++) { + int index = (hashval + i*i)%hashSize; + + if (table[index] != NULL && + table[index]->address == key) { + table[index] = NULL; + } + } +} + +void +TileHash::clear(void) +{ + bzero(table, tableSize); +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/TileHash.cpp --- a/TaskManager/Test/test_render/spe/TileHash.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -#include -#include -#include -#include "TileHash.h" - -static unsigned short PRIME[8] = { - 0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd, -}; - -int -TileHash::hash(memaddr data) -{ - int value = 0; - int n = 0; - int key; - - for (uint32 i = 0; i < sizeof(memaddr) * 2; i ++) { - key = data & 0xf; - value += key * PRIME[n++ & 7]; - data >>= 4; - } - - return value % hashSize; -} - -TileHash::TileHash(void) -{ - //hashSize = 263; - //tableSize = sizeof(TilePtr)*hashSize; - - table = (TilePtr*)malloc(tableSize); - clear(); -} - -int -TileHash::put(memaddr key, TilePtr data) -{ - int hashval = hash(key); - - for (int i = 0; i < hashSize/2; i++) { - int index = (hashval + i*i)%hashSize; - - if (table[index] == 0) { // 空の table に入れる - table[index] = data; - return index; - } - } - - return -1; -} - -TilePtr -TileHash::get(memaddr key) -{ - int hashval = hash(key); - - for (int i = 0; i < hashSize/2; i++) { - int index = (hashval + i*i)%hashSize; - - if (table[index] != NULL && - table[index]->address == key) { - return table[index]; - } - } - - return NULL; -} - -void -TileHash::remove(memaddr key) -{ - int hashval = hash(key); - - for (int i = 0; i < hashSize/2; i++) { - int index = (hashval + i*i)%hashSize; - - if (table[index] != NULL && - table[index]->address == key) { - table[index] = NULL; - } - } -} - -void -TileHash::clear(void) -{ - bzero(table, tableSize); -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/spe-main.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/spe-main.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,36 @@ +#include "../Func.h" +#include "SchedTask.h" + +SchedExternTask(LoadTexture); +SchedExternTask(SetTexture); +SchedExternTask(DrawSpan); +SchedExternTask(DrawSpanRenew); +SchedExternTask(DrawBack); + +SchedExternTask(ChainCal); +SchedExternTask(ChainInit); + +SchedExternTask(CreateSpan); +//SchedExternTask(CreatePolygon); + +SchedExternTask(ShowTime); + +void +task_init(void) +{ + SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture); + SchedRegisterTask(TASK_SET_TEXTURE, SetTexture); + SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan); + + SchedRegisterTask(CHAINCAL_TASK, ChainCal); + SchedRegisterTask(CHAININIT_TASK, ChainInit); +#if 0 + SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew); +#endif + SchedRegisterTask(TASK_DRAW_BACK, DrawBack); + + SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan); + //SchedRegisterTask(TASK_CREATE_PP, CreatePolygon); + + SchedRegisterTask(SHOW_TIME, ShowTime); +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/spe-main.cpp --- a/TaskManager/Test/test_render/spe/spe-main.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#include "../Func.h" -#include "SchedTask.h" - -SchedExternTask(LoadTexture); -SchedExternTask(SetTexture); -SchedExternTask(DrawSpan); -SchedExternTask(DrawSpanRenew); -SchedExternTask(DrawBack); - -SchedExternTask(ChainCal); -SchedExternTask(ChainInit); - -SchedExternTask(CreateSpan); -//SchedExternTask(CreatePolygon); - -SchedExternTask(ShowTime); - -void -task_init(void) -{ - SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture); - SchedRegisterTask(TASK_SET_TEXTURE, SetTexture); - SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan); - - SchedRegisterTask(CHAINCAL_TASK, ChainCal); - SchedRegisterTask(CHAININIT_TASK, ChainInit); -#if 0 - SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew); -#endif - SchedRegisterTask(TASK_DRAW_BACK, DrawBack); - - SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan); - //SchedRegisterTask(TASK_CREATE_PP, CreatePolygon); - - SchedRegisterTask(SHOW_TIME, ShowTime); -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/viewer_types.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/spe/viewer_types.cc Thu Sep 24 16:06:01 2009 +0900 @@ -0,0 +1,30 @@ +#include "viewer_types.h" + +int +getLocalPosition(int d, int offset) +{ + return d & (offset-1); +} + +/** + * ワールド座標における x の値を + * split_screen_w で分割した領域(1 〜 split_screen_w)での座標に変換する + * (ex. split_screen_w が 256 の場合、 + * x = 1 -> 1 + * x = 256 -> 256 + * x = 257 -> 1 + */ +int +getLocalX(int x) +{ + return getLocalPosition(x, split_screen_w); +} + +/** + * getLocalX に同じ + */ +int +getLocalY(int y) +{ + return getLocalPosition(y, split_screen_h); +} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/spe/viewer_types.cpp --- a/TaskManager/Test/test_render/spe/viewer_types.cpp Thu Sep 24 16:04:23 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -#include "viewer_types.h" - -int -getLocalPosition(int d, int offset) -{ - return d & (offset-1); -} - -/** - * ワールド座標における x の値を - * split_screen_w で分割した領域(1 〜 split_screen_w)での座標に変換する - * (ex. split_screen_w が 256 の場合、 - * x = 1 -> 1 - * x = 256 -> 256 - * x = 257 -> 1 - */ -int -getLocalX(int x) -{ - return getLocalPosition(x, split_screen_w); -} - -/** - * getLocalX に同じ - */ -int -getLocalY(int y) -{ - return getLocalPosition(y, split_screen_h); -} diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/task/Switch.cc --- a/TaskManager/Test/test_render/task/Switch.cc Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/task/Switch.cc Thu Sep 24 16:06:01 2009 +0900 @@ -9,6 +9,7 @@ int Switch::run(void *rbuf, void *wbuf) { +// 配列にする SceneGraphRootPtr tmp = sgroot; sgroot = sgroot_2; sgroot_2 = tmp; diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/viewer.cc --- a/TaskManager/Test/test_render/viewer.cc Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/viewer.cc Thu Sep 24 16:06:01 2009 +0900 @@ -117,7 +117,7 @@ sgroot = new SceneGraphRoot(this->width, this->height); sgroot_2 = new SceneGraphRoot(this->width, this->height); //sgroot->createFromXMLFile(xml); - + // ここの switch は application->init(this, manager, sg_no); になるべき switch (sg_number) { case 0: case 1: @@ -243,8 +243,8 @@ this->keyPtr = key; // post2runLoop は旧バージョン用なので post2speRunLoop の様なものを別につくるべき - task_next->set_post(post2speRunLoop, (void*)this); // set_post(function(this->run_loop()), NULL) - task_next->spawn(); + //task_next->set_post(post2speRunLoop, (void*)this); // set_post(function(this->run_loop()), NULL) + //task_next->spawn(); // TASK_INIT_TEXTURE が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ /* test */ @@ -314,12 +314,15 @@ update_key->add_inData(viewer->keyPtr, sizeof(key_stat)); update_key->spawn(); - HTaskPtr move_task = viewer->manager->create_task(TASK_MOVE); + /* TASK_MOVE は外から引数で取ってくるべき */ + //HTaskPtr move_task = viewer->manager->create_task(viewer->move_taskid); + HTaskPtr move_task = viewer->manager->create_task(TASK_MOVE); //move_task->add_param(sgroot); HTaskPtr draw_task = viewer->manager->create_task(TASK_DRAW); HTaskPtr switch_task = viewer->manager->create_task(TASK_SWITCH); + switch_task->wait_for(move_task); switch_task->wait_for(draw_task); move_task->spawn(); @@ -338,36 +341,6 @@ viewer->run_move(task_next); } -/* -void -Viewer::spe_run_loop() -{ - - bool quit_flg; - quit_flg = quit_check(); - if (quit_flg == true) { - this_time = get_ticks(); - run_finish(); - return; - } - - clean_pixels(); - - for (int i = 1; i <= spackList_length; i++) { - spackList[i-1].reinit(i*split_screen_h); - } - - //run_move(task_next); - sgroot->updateControllerState(); - sgroot->speExecute(width, height); - //sgroot->checkRemove(); - - // ここから下は Rendering という関数にする - rendering(task_next); - -} - -*/ void Viewer::mainLoop() { @@ -375,40 +348,8 @@ task_next->set_post(&post2runLoop, (void *)this); // set_post(function(this->run_loop()), NULL) task_next->spawn(); - // TASK_INIT_TEXTURE が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ } - -/* -static void -post2exchange_sgroot(void *viewer_) -{ - Viewer *viewer = (Viewer*)viewer_; - HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY); - viewer->exchange_sgroot(task_next); -} - -void -Viewer::exchange_sgroot(TaskManager *manager) -{ - - SceneGraphRootPtr tmp = sgroot; - sgroot = sgroot_2; - sgroot_2 = tmp; - -} -*/ - -/* -void -Viewer::spe_run_move(HTaskPtr task_next) -{ - HTaskPtr move_task = manager->create_task(MOVE_TASK); - move_task->add_param(sgroot); - task_next->wait_for(move_task); -} -*/ - static void post2runMove(void *viewer_) { @@ -600,3 +541,5 @@ delete sgroot_2; quit(); } + +/* end */ diff -r cd77224d4224 -r 960471b7ee54 TaskManager/Test/test_render/viewer.h --- a/TaskManager/Test/test_render/viewer.h Thu Sep 24 16:04:23 2009 +0900 +++ b/TaskManager/Test/test_render/viewer.h Thu Sep 24 16:06:01 2009 +0900 @@ -14,6 +14,8 @@ virtual ~Viewer(void) {} + //Application *application; + TaskManager *manager; key_stat *keyPtr;