diff Renderer/Engine/task/DrawSpanRenew.cc @ 507:735f76483bb2

Reorganization..
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 12 Oct 2009 09:39:35 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/task/DrawSpanRenew.cc	Mon Oct 12 09:39:35 2009 +0900
@@ -0,0 +1,223 @@
+#if 0
+#include <stdlib.h>
+#include <string.h>
+#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)
+{
+    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, (uint32)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;
+                    if (!(tile = isAvailableTile(tex_addr))) {
+                        tile = set_rgb(tex_addr, 0);
+                        smanager->dma_wait(0);
+                    }
+
+                    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;
+                        if (!(tile = isAvailableTile(tex_addr))) {
+                            spack->info.start = t;
+                            tile = set_rgb(tex_addr, TEX_LOAD);
+                            smanager->dma_wait(TEX_LOAD);
+                        }
+
+                        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);
+
+    //FINISH:
+    /**
+     * linebuf, zRow, args は RenewTask が引き継ぐ
+     */
+    free(free_spack1);
+    free(free_spack2);
+
+    return 0;
+}
+#endif