comparison Renderer/test_render/spe/DrawSpanRenew.cpp @ 283:55ea4465b1a2

fix test_render
author e065746@localhost.localdomain
date Fri, 05 Jun 2009 16:49:12 +0900
parents
children 58fd16298954
comparison
equal deleted inserted replaced
282:ef061be0baff 283:55ea4465b1a2
1 #include <stdlib.h>
2 #include <string.h>
3 #include <spu_mfcio.h>
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
13 #define FB_STORE 2
14
15 SchedDefineTask(DrawSpanRenew);
16
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
44 int
45 DrawSpanRenew::run(void *rbuf, void *wbuf)
46 {
47 SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1);
48 SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
49 SpanPackPtr free_spack1 = spack;
50 SpanPackPtr free_spack2 = next_spack;
51 Span *span;
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;
64
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
78 smanager->dma_wait(TEX_LOAD);
79
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
96 uint32 rgb = 0x00ff0000;
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)) {
142 set_rgb(tex_addr, 0);
143 smanager->dma_wait(0);
144 }
145
146 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
147
148 zRow[localx + (rangex*localy)] = zpos;
149 linebuf[localx + (rangex*localy)] = rgb;
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;
183
184 if (!isAvailableTile(tex_addr)) {
185 spack->info.start = t;
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
193 set_rgb(tex_addr, TEX_LOAD);
194 smanager->dma_wait(TEX_LOAD);
195 #endif
196 }
197
198 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
199
200 zRow[localx + (rangex*localy)] = tex_z;
201 linebuf[localx + (rangex*localy)] = rgb;
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
214 writebuffer(display, rangex, rangey, screen_width);
215
216 free(zRow);
217 free(args);
218
219 /**
220 * linebuf, zRow, args は RenewTask が引き継ぐ
221 */
222 free(free_spack1);
223 free(free_spack2);
224
225 return 0;
226 }