Mercurial > hg > Game > Cerium
annotate TaskManager/Test/test_render/spe/DrawSpanRenew.cpp @ 210:e75f9eb97180 draft
fix DrawSpan
author | gongo@localhost.localdomain |
---|---|
date | Fri, 30 Jan 2009 14:55:04 +0900 |
parents | 1ff24ca2f016 |
children | c4918a1fb6c9 f7638e58b733 |
rev | line source |
---|---|
185 | 1 #include <stdlib.h> |
2 #include <string.h> | |
192 | 3 #include <spu_mfcio.h> |
185 | 4 #include "DrawSpanRenew.h" |
5 #include "polygon_pack.h" | |
6 #include "SpanPack.h" | |
7 #include "texture.h" | |
8 #include "viewer_types.h" | |
9 #include "Func.h" | |
10 | |
11 #define SPAN_PACK_LOAD 0 | |
12 #define TEX_LOAD 1 | |
193 | 13 #define FB_STORE 2 |
185 | 14 |
15 SchedDefineTask(DrawSpanRenew); | |
16 | |
193 | 17 void |
18 DrawSpanRenew::reboot(SpanPackPtr spack, int cur_span_x) | |
19 { | |
20 TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2); | |
21 | |
22 renew_task->add_param((int)args); | |
23 | |
24 SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); | |
25 memcpy(curr, spack, sizeof(SpanPack)); | |
26 renew_task->add_param((int)curr); | |
27 renew_task->add_param(cur_span_x); | |
28 | |
29 // linebuf と zRow も引き継がせる | |
30 renew_task->add_param((int)linebuf); | |
31 renew_task->add_param((int)zRow); | |
32 | |
33 //fprintf(stderr, "[%p] start %u\n", curr, spu_readch(SPU_RdDec)); | |
34 | |
35 /** | |
36 * 再起動したタスクを待つ | |
37 */ | |
38 smanager->wait_task(renew_task); | |
39 | |
40 // next_spack は free() するので wait する | |
41 smanager->dma_wait(SPAN_PACK_LOAD); | |
42 } | |
43 | |
185 | 44 int |
45 DrawSpanRenew::run(void *rbuf, void *wbuf) | |
46 { | |
193 | 47 SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1); |
185 | 48 SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack)); |
188
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
49 SpanPackPtr free_spack1 = spack; |
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
50 SpanPackPtr free_spack2 = next_spack; |
185 | 51 Span *span; |
193 | 52 |
53 args = (DrawSpanArgPtr)smanager->get_param(0); | |
54 uint32 display = args->display; | |
55 int screen_width = args->screen_width; | |
56 int rangex_start = args->rangex_start; | |
57 int rangex_end = args->rangex_end; | |
58 | |
59 // このタスクが担当する x の範囲 | |
60 int rangex = rangex_end - rangex_start + 1; | |
61 | |
62 // y の範囲 (render_y + rangey - 1) | |
63 int rangey = args->rangey; | |
185 | 64 |
193 | 65 hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH); |
66 tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST); | |
67 | |
68 linebuf = (int*)smanager->get_param(3); | |
69 zRow = (float*)smanager->get_param(4); | |
70 | |
71 doneWrite = 0; | |
72 | |
73 // span->length_x の処理での再起動位置 | |
74 int js_cont = smanager->get_param(2); | |
75 | |
76 //fprintf(stderr, "[%p] end %u\n", spack, spu_readch(SPU_RdDec)); | |
77 | |
188
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
78 smanager->dma_wait(TEX_LOAD); |
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
79 |
185 | 80 do { |
81 /** | |
82 * SpanPack->next が存在する場合、 | |
83 * 現在の SpanPack を処理してる間に | |
84 * 次の SpanPack の DMA 転送を行う | |
85 */ | |
86 if (spack->next != NULL) { | |
87 smanager->dma_load(next_spack, (uint32)spack->next, | |
88 sizeof(SpanPack), SPAN_PACK_LOAD); | |
89 } else { | |
90 next_spack = NULL; | |
91 } | |
92 | |
93 for (int t = spack->info.start; t < spack->info.size; t++) { | |
94 span = &spack->span[t]; | |
95 | |
193 | 96 uint32 rgb = 0x00ff0000; |
185 | 97 float tex1 = span->tex_x1; |
98 float tex2 = span->tex_x2; | |
99 float tey1 = span->tex_y1; | |
100 float tey2 = span->tex_y2; | |
101 | |
102 /** | |
103 * Span が持つ 1 pixel 毎の | |
104 * テクスチャの座標 | |
105 */ | |
106 int tex_xpos; | |
107 int tex_ypos; | |
108 | |
109 /** | |
110 * (tex_xpos, tex_ypos) の、ブロック内(上の図参照)での座標と | |
111 * そのブロックのアドレス(MainMemory) | |
112 */ | |
113 int tex_localx; | |
114 int tex_localy; | |
115 uint32 *tex_addr; | |
116 | |
117 int x = span->x; | |
118 int y = span->y; | |
119 int x_len = span->length_x; | |
120 float z = span->start_z; | |
121 float zpos = span->end_z; | |
122 | |
123 // 座標が [0 .. split_screen_w-1] に入るように x,y を -1 | |
124 int localx = getLocalX(x-1); | |
125 int localy = getLocalY(y-1); | |
126 | |
127 if (x_len == 1) { | |
128 if (x < rangex_start || rangex_end < x) { | |
129 continue; | |
130 } | |
131 | |
132 tex_xpos = (int)((span->tex_width-1) * tex1); | |
133 tex_ypos = (int)((span->tex_height-1) * tey1); | |
134 | |
135 if (zpos < zRow[localx + (rangex * localy)]) { | |
136 tex_addr = getTile(tex_xpos, tex_ypos, | |
137 span->tex_width, span->tex_addr); | |
138 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; | |
139 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; | |
140 | |
141 if (!isAvailableTile(tex_addr)) { | |
210 | 142 set_rgb(tex_addr, 0); |
143 smanager->dma_wait(0); | |
185 | 144 } |
145 | |
146 rgb = get_rgb(tex_localx, tex_localy, tex_addr); | |
147 | |
193 | 148 zRow[localx + (rangex*localy)] = zpos; |
149 linebuf[localx + (rangex*localy)] = rgb; | |
185 | 150 } |
151 } else { | |
152 int js = (x < rangex_start) ? rangex_start - x : 0; | |
153 int je = (x + x_len > rangex_end) ? rangex_end - x : x_len; | |
154 float tex_x, tex_y, tex_z; | |
155 | |
156 /** | |
157 * 一回比較すれば、以後再起動するまでは | |
158 * js_cont は使わないから 0 にしてるわけだけど、 | |
159 * 最初の一回のためだけにこれはめんどくさいのー。 | |
160 */ | |
161 js = (js < js_cont) ? js_cont : js; | |
162 js_cont = 0; | |
163 | |
164 for (int j = js; j <= je; j++) { | |
165 localx = getLocalX(x-1+j); | |
166 | |
167 tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1); | |
168 | |
169 tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1); | |
170 tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1); | |
171 if (tex_x > 1) tex_x = 1; | |
172 if (tex_x < 0) tex_x = 0; | |
173 if (tex_y > 1) tex_y = 1; | |
174 if (tex_y < 0) tex_y = 0; | |
175 tex_xpos = (int)((span->tex_width-1) * tex_x); | |
176 tex_ypos = (int)((span->tex_height-1) * tex_y); | |
177 | |
178 if (tex_z < zRow[localx + (rangex*localy)]) { | |
179 tex_addr = getTile(tex_xpos, tex_ypos, | |
180 span->tex_width, span->tex_addr); | |
181 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; | |
182 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; | |
193 | 183 |
185 | 184 if (!isAvailableTile(tex_addr)) { |
185 spack->info.start = t; | |
193 | 186 #if 0 |
187 set_rgbs(tex_addr, | |
188 getTile(span->tex_width-1, tex_ypos, | |
189 span->tex_width, span->tex_addr)); | |
190 reboot(spack, j); | |
191 goto FINISH; | |
192 #else | |
210 | 193 set_rgb(tex_addr, TEX_LOAD); |
193 | 194 smanager->dma_wait(TEX_LOAD); |
195 #endif | |
185 | 196 } |
197 | |
198 rgb = get_rgb(tex_localx, tex_localy, tex_addr); | |
199 | |
200 zRow[localx + (rangex*localy)] = tex_z; | |
193 | 201 linebuf[localx + (rangex*localy)] = rgb; |
185 | 202 } |
203 } | |
204 } | |
205 } | |
206 | |
207 smanager->dma_wait(SPAN_PACK_LOAD); | |
208 | |
209 SpanPackPtr tmp_spack = spack; | |
210 spack = next_spack; | |
211 next_spack = tmp_spack; | |
212 } while (spack); | |
213 | |
193 | 214 writebuffer(display, rangex, rangey, screen_width); |
215 | |
216 free(zRow); | |
217 free(args); | |
185 | 218 |
219 FINISH: | |
193 | 220 /** |
221 * linebuf, zRow, args は RenewTask が引き継ぐ | |
222 */ | |
188
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
223 free(free_spack1); |
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
224 free(free_spack2); |
fe854a6ee9e2
<≪若膊肴:TaskManager/Test/test_render/ChangeLog
gongo@localhost.localdomain
parents:
187
diff
changeset
|
225 |
185 | 226 return 0; |
227 } |