Mercurial > hg > Game > Cerium
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 } |