Ignore:
Timestamp:
Aug 3, 2015, 7:07:02 PM (9 years ago)
Author:
guerin
Message:

raycast: initial distributed implementation

The main task runs on processor (0,0,0). It manages game logic and
initialization, and participates in the rendering process.
The render task runs on all other processors. It tries to render a frame
slice when available, which is raycasting + pixel drawing for a pixel
column of the frame.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/applications/raycast/disp.c

    r679 r683  
    66#include <math.h>
    77#include <hard_config.h>
     8#include <user_sqt_lock.h>
    89
    910#define FIELD_OF_VIEW   (70.f * M_PI / 180.f)   // Camera field of view
     
    1415// Globals
    1516
    16 static unsigned char* buf[2];
    17 static void *         sts[2];
    18 static unsigned int   cur_buf;
     17static unsigned char*           buf[2];         // framebuffer
     18static void *                   sts[2];         // for fbf_cma
     19static unsigned int             cur_buf;        // current framebuffer
     20static volatile unsigned int    slice_x;        // slice index (shared)
     21static sqt_lock_t               slice_x_lock;   // slice index lock
     22static volatile unsigned int    slice_cnt;      // slice count (shared)
    1923
    2024// Textures indexed by block number
     
    168172}
    169173
    170 static unsigned char *loadTexture(char *path)
     174static unsigned char *dispLoadTexture(char *path)
    171175{
    172176    int fd;
     
    191195void dispInit()
    192196{
    193     // allocate framebuffer
     197    unsigned int w, h, p;
     198
     199    // Initialize lock
     200    giet_procs_number(&w, &h, &p);
     201    sqt_lock_init(&slice_x_lock, w, h, p);
     202
     203    // Allocate framebuffer
    194204    buf[0] = almalloc(64, FBUF_X_SIZE * FBUF_Y_SIZE);
    195205    buf[1] = almalloc(64, FBUF_X_SIZE * FBUF_Y_SIZE);
     
    197207    sts[1] = almalloc(64, 64);
    198208
    199     // initialize framebuffer
     209    // Initialize framebuffer
    200210    giet_fbf_cma_alloc();
    201211    giet_fbf_cma_init_buf(buf[0], buf[1], sts[0], sts[1]);
    202212    giet_fbf_cma_start(FBUF_X_SIZE * FBUF_Y_SIZE);
    203213
    204     // load textures
    205     g_tex[1] = loadTexture("misc/rock_32.raw");
    206     g_tex[2] = loadTexture("misc/door_32.raw");
    207     g_tex[3] = loadTexture("misc/handle_32.raw");
    208     g_tex[4] = loadTexture("misc/wood_32.raw");
     214    // Load textures
     215    g_tex[1] = dispLoadTexture("misc/rock_32.raw");
     216    g_tex[2] = dispLoadTexture("misc/door_32.raw");
     217    g_tex[3] = dispLoadTexture("misc/handle_32.raw");
     218    g_tex[4] = dispLoadTexture("misc/wood_32.raw");
    209219
    210220    cur_buf = 0;
     221    slice_cnt = 0;
     222    slice_x = FBUF_X_SIZE;
     223}
     224
     225int dispRenderSlice(Game *game)
     226{
     227    unsigned int x;
     228    int type;
     229    float angle, dist, tx;
     230
     231    sqt_lock_acquire(&slice_x_lock);
     232
     233    if (slice_x == FBUF_X_SIZE) {
     234        // No more work to do for this frame
     235        sqt_lock_release(&slice_x_lock);
     236        return 0;
     237    }
     238    else {
     239        // Keep slice coordinate
     240        x = slice_x++;
     241    }
     242
     243    sqt_lock_release(&slice_x_lock);
     244
     245    angle = game->player.dir - FIELD_OF_VIEW / 2.f +
     246            x * FIELD_OF_VIEW / FBUF_X_SIZE;
     247
     248    // Cast a ray to get wall distance
     249    dist = dispRaycast(game, &type, &tx, angle);
     250
     251    // Perspective correction
     252    dist *= cos(game->player.dir - angle);
     253
     254    // Draw ceiling, wall and floor
     255    dispDrawSlice(game, x, FBUF_Y_SIZE / dist, type, tx);
     256
     257    // Signal this slice is done
     258    atomic_increment((unsigned int*)&slice_cnt, 1);
     259
     260    return 1;
    211261}
    212262
     
    214264{
    215265    int start = giet_proctime();
    216     float angle = game->player.dir - FIELD_OF_VIEW / 2.f;
    217 
    218     // Cast a ray for each pixel column and draw a colored wall slice
    219     for (int i = 0; i < FBUF_X_SIZE; i++)
    220     {
    221         float dist;
    222         int type;
    223         float tx;
    224 
    225         // Cast a ray to get wall distance
    226         dist = dispRaycast(game, &type, &tx, angle);
    227 
    228         // Perspective correction
    229         dist *= cos(game->player.dir - angle);
    230 
    231         // Draw ceiling, wall and floor
    232         dispDrawSlice(game, i, FBUF_Y_SIZE / dist, type, tx);
    233 
    234         angle += FIELD_OF_VIEW / FBUF_X_SIZE;
    235     }
    236 
     266
     267    // Start rendering
     268    slice_cnt = 0;
     269    slice_x = 0;
     270
     271    // Render slices
     272    while (dispRenderSlice(game));
     273
     274    // Wait for completion
     275    while (slice_cnt != FBUF_X_SIZE);
     276
     277    // Flip framebuffer
    237278    giet_fbf_cma_display(cur_buf);
    238279    cur_buf = !cur_buf;
    239280    giet_tty_printf("[RAYCAST] flip (took %d cycles)\n", giet_proctime() - start);
    240281}
     282
Note: See TracChangeset for help on using the changeset viewer.