comparison TaskManager/Test/test_render/spe/DrawSpan.cpp @ 184:a19d3ed4ce5b draft

fix
author gongo@gendarme.cr.ie.u-ryukyu.ac.jp
date Tue, 06 Jan 2009 15:39:48 +0900
parents 8e9ada0c1ed0
children 06cdf8baa989
comparison
equal deleted inserted replaced
182:8e9ada0c1ed0 184:a19d3ed4ce5b
1 #include <stdlib.h> 1 #include <stdlib.h>
2 #include <string.h> 2 #include <string.h>
3 #include "DrawSpan.h" 3 #include "DrawSpan.h"
4 #include "polygon_pack.h" 4 #include "polygon_pack.h"
5 #include "SpanPack.h"
6 #include "texture.h" 5 #include "texture.h"
7 #include "viewer_types.h" 6 #include "viewer_types.h"
8 #include "TileHash.h" 7 #include "Func.h"
9 8
10 #define SPAN_PACK_LOAD 0 9 #define SPAN_PACK_LOAD 0
11 #define TEX_LOAD 1 10 #define TEX_LOAD 1
12 11
13 SchedDefineTask(DrawSpan); 12 SchedDefineTask(DrawSpan);
14
15 static TileHashPtr hash;
16 static TileListPtr tileList;
17 13
18 /** 14 /**
19 * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する 15 * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
20 * 16 *
21 * +---+---+---+---+---+---+ 17 * +---+---+---+---+---+---+
43 * @param[in] tx X coordinates of texture 39 * @param[in] tx X coordinates of texture
44 * @param[in] tx Y coordinates of texture 40 * @param[in] tx Y coordinates of texture
45 * @param[in] twidth Width of texture 41 * @param[in] twidth Width of texture
46 * @return block ID 42 * @return block ID
47 */ 43 */
48 static inline int 44 int
49 get_tex_block(int tx, int ty, int twidth) 45 DrawSpan::getTexBlock(int tx, int ty, int twidth)
50 { 46 {
51 int blockX, blockY; 47 int blockX, blockY;
52 48
53 blockX = tx / TEXTURE_SPLIT_PIXEL; 49 blockX = tx / TEXTURE_SPLIT_PIXEL;
54 blockY = ty / TEXTURE_SPLIT_PIXEL; 50 blockY = ty / TEXTURE_SPLIT_PIXEL;
64 * @param[in] tx Y coordinates of texture 60 * @param[in] tx Y coordinates of texture
65 * @param[in] tw Width of texture 61 * @param[in] tw Width of texture
66 * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address 62 * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
67 * @return block ID 63 * @return block ID
68 */ 64 */
69 static inline uint32* 65 uint32*
70 getTile(int tx, int ty, int tw, uint32 *tex_addr_top) 66 DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
71 { 67 {
72 int block = get_tex_block(tx, ty, tw); 68 int block = getTexBlock(tx, ty, tw);
73 return tex_addr_top + block*TEXTURE_BLOCK_SIZE; 69 return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
74 } 70 }
75 71
76 void 72 void
77 DrawSpan::linebuf_init(int *buf, int x, int rgb) 73 DrawSpan::linebuf_init(int *buf, int x, int rgb)
79 for (int i = 0; i < x; i++) { 75 for (int i = 0; i < x; i++) {
80 buf[i] = rgb; 76 buf[i] = rgb;
81 } 77 }
82 } 78 }
83 79
84 Uint32 80 /**
85 DrawSpan::get_rgb(int tx, int ty, uint32 *addr) 81 * Span が使う Texture Tile があるか
82 *
83 * @retval != NULL 存在する
84 * @retval NULL 存在しない
85 */
86 TilePtr
87 DrawSpan::isAvailableTile(uint32 *addr)
88 {
89 return hash->get(addr);
90 }
91
92 void
93 DrawSpan::set_rgb(uint32 *addr)
86 { 94 {
87 TilePtr tile; 95 TilePtr tile;
88 96
89 tile = hash->get(addr); 97 if (!isAvailableTile(addr)) {
90 if (tile == NULL) {
91 tile = tileList->nextTile(); 98 tile = tileList->nextTile();
92
93 /** 99 /**
94 * FIFO なので、もし前のが残っていれば削除 100 * FIFO なので、もし前のが残っていれば削除
95 */ 101 */
96 hash->remove(tile->texture_addr); 102 hash->remove(tile->texture_addr);
97 103
98 tile->texture_addr = addr; 104 tile->texture_addr = addr;
99 105
106 hash->put(tile->texture_addr, tile);
107
100 smanager->dma_load(tile->pixel, (uint32)addr, 108 smanager->dma_load(tile->pixel, (uint32)addr,
101 sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD); 109 sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD);
102 110
103 int index = hash->put(tile->texture_addr, tile);
104
105 /**
106 * TODO:
107 * 入らなかったやつは
108 * 今までのやつを描画してから続きをするとか
109 */
110 if (index < 0) {
111 printf("[%p] Can't entry\n", tile);
112 return 0xff0000;
113 }
114
115 smanager->dma_wait(TEX_LOAD); 111 smanager->dma_wait(TEX_LOAD);
116 } 112 }
117 113 }
114
115 void
116 DrawSpan::set_rgbs(uint32 *addr, uint32 *max_addr)
117 {
118 uint32 start = (uint32)addr;
119 uint32 end = (uint32)max_addr;
120 uint32 length = end-start;
121 uint32 diff = sizeof(uint32)*TEXTURE_BLOCK_SIZE;
122 uint32 max_tile = 8;
123
124 for (uint32 i = 0, j = 0; i <= length && j < max_tile; i += diff, j++) {
125 set_rgb((uint32*)(start + i));
126 }
127 }
128
129 Uint32
130 DrawSpan::get_rgb(int tx, int ty, uint32 *addr)
131 {
132 TilePtr tile;
133
134 tile = hash->get(addr);
118 return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx]; 135 return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx];
119 } 136 }
120 137
121 138 /**
139 * DrawSpan の再起動 (DrawSpanRenew 生成)
140 *
141 * @param[in] spack 現在処理している SpanPack
142 * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
143 * どこまで進んでいるか
144 */
145 void
146 DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
147 {
148 TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
149 int rangey = smanager->get_param(2);
150
151 /**
152 * 共通の outData, param はそのまま渡す
153 */
154 for (int i = 0; i < rangey; i++) {
155 renew_task->add_outData(smanager->get_outputAddr(i),
156 smanager->get_outputSize(i));
157 }
158
159 // rangex_start, rangex_end, rangey
160 renew_task->add_param(smanager->get_param(0));
161 renew_task->add_param(smanager->get_param(1));
162 renew_task->add_param(smanager->get_param(2));
163
164 /**
165 * SpanPack は続きから開始するので、
166 * 現在の状態をコピーしておく。
167 * spack は rbuf から取得してる可能性があり
168 * rbuf はシステムが自動的に free() するため
169 * アドレスだけ渡すのはNG
170 */
171 SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
172 memcpy(curr, spack, sizeof(SpanPack));
173 renew_task->add_param((int)curr);
174
175 renew_task->add_param(cur_span_x);
176
177 /**
178 * 再起動したタスクを待つ
179 */
180 smanager->wait_task(renew_task);
181
182 // next_spack は free() するので wait する
183 smanager->dma_wait(SPAN_PACK_LOAD);
184 }
122 185
123 int 186 int
124 DrawSpan::run(void *rbuf, void *wbuf) 187 DrawSpan::run(void *rbuf, void *wbuf)
125 { 188 {
126 SpanPack *spack = (SpanPack*)smanager->get_input(0);
127 SpanPack *next_spack =
128 (SpanPack*)smanager->allocate(sizeof(SpanPack));
129 SpanPack *free_spack = next_spack; // next_spack の free() 用
130 Span *span;
131
132 hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH); 189 hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
133 tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); 190 tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
134 191
135 int rangex_start = smanager->get_param(0); 192 int rangex_start = smanager->get_param(0);
136 int rangex_end = smanager->get_param(1); 193 int rangex_end = smanager->get_param(1);
139 int rangex = rangex_end - rangex_start + 1; 196 int rangex = rangex_end - rangex_start + 1;
140 197
141 // y の範囲 (render_y + rangey - 1) 198 // y の範囲 (render_y + rangey - 1)
142 int rangey = smanager->get_param(2); 199 int rangey = smanager->get_param(2);
143 200
144 float *zRow = (float*)smanager->get_input(1); 201 float *zRow = (float*)smanager->allocate(sizeof(float)*rangex*rangey);
202
203 for (int i = 0; i < rangex*rangey; i++) {
204 zRow[i] = 65535.0f;
205 }
206
145 int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey); 207 int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey);
146 208
147 for (int i = 0; i < rangey; i++) { 209 for (int i = 0; i < rangey; i++) {
148 linebuf[i] = (int*)smanager->get_output(i); 210 linebuf[i] = (int*)smanager->get_output(i);
149 linebuf_init(linebuf[i], rangex, 0xffffffff); 211 linebuf_init(linebuf[i], rangex, 0xffffffff);
150 } 212 }
213
214 SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
215 SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
216 SpanPackPtr free_spack = next_spack; // next_spack の free() 用
217 Span *span;
151 218
152 do { 219 do {
153 /** 220 /**
154 * SpanPack->next が存在する場合、 221 * SpanPack->next が存在する場合、
155 * 現在の SpanPack を処理してる間に 222 * 現在の SpanPack を処理してる間に
208 tex_addr = getTile(tex_xpos, tex_ypos, 275 tex_addr = getTile(tex_xpos, tex_ypos,
209 span->tex_width, span->tex_addr); 276 span->tex_width, span->tex_addr);
210 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; 277 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
211 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; 278 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
212 279
280 /**
281 * Tile が無い場合、一旦タスクはここで中断し、
282 * Tile をロードするタスクを走らせた後に再起動する
283 */
284 if (!isAvailableTile(tex_addr)) {
285 spack->info.start = t;
286 //set_rgb(tex_addr);
287 set_rgbs(tex_addr,
288 getTile(span->tex_width-1, tex_ypos,
289 span->tex_width, span->tex_addr));
290 reboot(spack, 0);
291 goto FINISH;
292 }
293
213 rgb = get_rgb(tex_localx, tex_localy, tex_addr); 294 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
214 295
215 zRow[localx + (rangex * localy)] = zpos; 296 zRow[localx + (rangex * localy)] = zpos;
216 linebuf[localy][localx] = rgb; 297 linebuf[localy][localx] = rgb;
217 } 298 }
237 if (tex_z < zRow[localx + (rangex*localy)]) { 318 if (tex_z < zRow[localx + (rangex*localy)]) {
238 tex_addr = getTile(tex_xpos, tex_ypos, 319 tex_addr = getTile(tex_xpos, tex_ypos,
239 span->tex_width, span->tex_addr); 320 span->tex_width, span->tex_addr);
240 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; 321 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
241 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; 322 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
323
324 if (!isAvailableTile(tex_addr)) {
325 spack->info.start = t;
326 //set_rgb(tex_addr);
327 set_rgbs(tex_addr,
328 getTile(span->tex_width-1, tex_ypos,
329 span->tex_width, span->tex_addr));
330 reboot(spack, j);
331 goto FINISH;
332 }
242 333
243 rgb = get_rgb(tex_localx, tex_localy, tex_addr); 334 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
244 335
245 zRow[localx + (rangex*localy)] = tex_z; 336 zRow[localx + (rangex*localy)] = tex_z;
246 linebuf[localy][localx] = rgb; 337 linebuf[localy][localx] = rgb;
249 } 340 }
250 } 341 }
251 342
252 smanager->dma_wait(SPAN_PACK_LOAD); 343 smanager->dma_wait(SPAN_PACK_LOAD);
253 344
254 SpanPack *tmp_spack = spack; 345 SpanPackPtr tmp_spack = spack;
255 spack = next_spack; 346 spack = next_spack;
256 next_spack = tmp_spack; 347 next_spack = tmp_spack;
257 } while (spack); 348 } while (spack);
258 349
350
351 FINISH:
259 free(free_spack); 352 free(free_spack);
260 free(linebuf); 353 free(linebuf);
261 354
262 return 0; 355 return 0;
263 } 356 }