Imported various math functions.
authorethereal <ethereal@ethv.net>
Sun, 14 Jun 2015 18:09:27 +0000 (18:09 +0000)
committerethereal <ethereal@ethv.net>
Sun, 14 Jun 2015 18:09:27 +0000 (18:09 +0000)
src/CMakeLists.txt
src/ecore/ecore.c
src/ecore/lmath.c [new file with mode: 0644]
src/ecore/lmath.h [new file with mode: 0644]
src/ecore/math.c
src/ecore/math.h
src/ecore/render.c
src/ecore/rreq.c
src/ewrap/main.c

index 553a246..821aab7 100644 (file)
@@ -8,11 +8,12 @@ if(${build_ecore})
 
     add_custom_command(OUTPUT ecore.o DEPENDS ${base}/ecore.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/ecore.c -c -o ecore.o -ffreestanding -nostdlib)
     add_custom_command(OUTPUT rreq.o DEPENDS ${base}/rreq.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/rreq.c -c -o rreq.o -ffreestanding -nostdlib)
-    add_custom_command(OUTPUT render.o DEPENDS ${base}/render.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/render.c -c -o render.o -ffreestanding -nostdlib)
-    add_custom_command(OUTPUT math.o DEPENDS ${base}/math.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/math.c -c -o math.o -ffreestanding -nostdlib)
+    add_custom_command(OUTPUT render.o DEPENDS ${base}/render.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/render.c -c -o render.o -ffreestanding -nostdlib -Os)
+    add_custom_command(OUTPUT math.o DEPENDS ${base}/math.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/math.c -c -o math.o -ffreestanding -nostdlib -Os)
+    add_custom_command(OUTPUT lmath.o DEPENDS ${base}/lmath.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/lmath.c -c -o lmath.o -ffreestanding -nostdlib -Os)
     add_custom_command(OUTPUT support.o DEPENDS ${base}/support.S COMMAND e-as ${base}/support.S -o support.o)
 
-    add_custom_command(OUTPUT ecore.elf DEPENDS ecore.o rreq.o render.o math.o support.o COMMAND e-ld ecore.o rreq.o render.o math.o support.o -o ecore.elf -le-lib -lgcc -T$ENV{EPIPHANY_HOME}/bsps/current/internal.ldf -L$ENV{EPIPHANY_HOME}/tools/e-gnu/epiphany-elf/lib/ -L$ENV{EPIPHANY_HOME}/tools/e-gnu/lib/gcc/epiphany-elf/4.8.2/)
+    add_custom_command(OUTPUT ecore.elf DEPENDS ecore.o rreq.o render.o math.o lmath.o support.o COMMAND e-ld ecore.o rreq.o render.o math.o lmath.o support.o -o ecore.elf -le-lib -lgcc -T$ENV{EPIPHANY_HOME}/bsps/current/internal.ldf -L$ENV{EPIPHANY_HOME}/tools/e-gnu/epiphany-elf/lib/ -L$ENV{EPIPHANY_HOME}/tools/e-gnu/lib/gcc/epiphany-elf/4.8.2/)
     add_custom_command(OUTPUT ecore.srec DEPENDS ecore.elf COMMAND e-objcopy --srec-forceS3 --output-target srec ecore.elf ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ecore.srec)
     add_custom_target(ecore ALL DEPENDS ecore.srec)
 endif(${build_ecore})
index c6cd117..051c16a 100644 (file)
@@ -18,11 +18,6 @@ void *memcpy(void *dst, const void *src, size_t n) {
     return dst;
 }
 
-// stupidity
-float tanf(float x) { return x; }
-float sqrtf(float x) { return x; }
-float powf(float x, float y) { return x; }
-
 int main() {
     e_shm_attach(&shared_mem, "raytrace_shm");
 
@@ -39,7 +34,6 @@ int main() {
     e_irq_mask(E_MESSAGE_INT, E_FALSE);
 
     int id = y*e_group_config.group_rows + x;
-    int ind = 0;
     while(1) {
         request_new_range(id);
 
@@ -53,7 +47,7 @@ int main() {
 
         //shm_region->msg[id] = ++ind;
 
-        //render_range();
+        render_range();
     }
 
     return 0;
diff --git a/src/ecore/lmath.c b/src/ecore/lmath.c
new file mode 100644 (file)
index 0000000..67e773d
--- /dev/null
@@ -0,0 +1,347 @@
+#include "lmath.h"
+
+static const float HALF_PI = 1.570796326;
+static const float ONE_OVER_PI = 0.318309886;
+static const float r[] = { -0.1666665668,
+                            0.8333025139e-02,
+                           -0.1980741872e-03,
+                            0.2601903036e-5 };
+
+float fabsf(float x) {
+    if(x<0) return -x;
+    return x;
+}
+
+static float sinef(float x, int cosine) {
+    int sgn, N;
+    float y, XN, g, R, res;
+
+    /* Use sin and cos properties to ease computations. */
+    if (cosine)
+    {
+        sgn = 1;
+        y = fabsf (x) + HALF_PI;
+    }
+    else
+    {
+        if (x < 0.0)
+        {
+            sgn = -1;
+            y = -x;
+        }
+        else
+        {
+            sgn = 1;
+            y = x;
+        }
+    }
+
+    /* Calculate the exponent. */
+    if (y < 0.0)
+        N = (int) (y * ONE_OVER_PI - 0.5);
+    else
+        N = (int) (y * ONE_OVER_PI + 0.5);
+    XN = (float) N;
+
+    if (N & 1)
+        sgn = -sgn;
+
+    if (cosine)
+        XN -= 0.5;
+
+    y = fabsf (x) - XN * M_PI;
+
+    if (-1e-5 < y && y < 1e-5)
+        res = y;
+
+    else
+    {
+        g = y * y;
+
+        /* Calculate the Taylor series. */
+        R = (((r[3] * g + r[2]) * g + r[1]) * g + r[0]) * g;
+
+        /* Finally, compute the result. */
+        res = y + y * R;
+    }
+
+    res *= sgn;
+
+    return (res);
+}
+
+float sinf(float x) {
+    return sinef(x, 0);
+}
+
+float cosf(float x) {
+    return sinef(x, 1);
+}
+
+float frexpf (float d, int *exp)
+{
+    float f;
+    __int32_t wf, wd;
+
+    /* Check for special values. */
+    if(d == 0) {
+        *exp = 0;
+        return d;
+    }
+
+    wd = *(__int32_t*)(&d);
+
+    /* Get the exponent. */
+    *exp = ((wd & 0x7f800000) >> 23) - 126;
+
+    /* Get the mantissa. */ 
+    wf = wd & 0x7fffff;  
+    wf |= 0x3f000000;
+
+    f = *(float*)(&wf);
+
+    return (f);
+}
+
+
+#define FLOAT_EXP_OFFS 127
+
+float ldexpf(float d, int e) {
+    int exp;
+    __int32_t wd;
+
+    wd = *(__int32_t*)&d;
+
+    if(wd == 0) return d;
+
+    exp = (wd & 0x7f800000) >> 23;
+    exp += e;
+
+    wd &= 0x807fffff;
+    wd |= exp << 23;
+    d = *(float*)(&wd);
+
+    return (d);
+}
+
+float sqrtf(float x) {
+    float f, y;
+    int exp, i, odd;
+
+    /* Initial checks are performed here. */
+    if (x == 0.0)
+        return (0.0);
+    if (x < 0)
+    {
+        return -1.0;
+    }
+
+    /* Find the exponent and mantissa for the form x = f * 2^exp. */
+    f = frexpf (x, &exp);
+    odd = exp & 1;
+
+    /* Get the initial approximation. */
+    y = 0.41731 + 0.59016 * f;
+
+    f *= 0.5;
+    /* Calculate the remaining iterations. */
+    for (i = 0; i < 2; ++i)
+        y = y * 0.5 + f / y;
+
+    /* Calculate the final value. */
+    if (odd)
+    {
+        y *= __SQRT_HALF;
+        exp++;
+    }
+    exp >>= 1;
+    y = ldexpf (y, exp);
+
+    return (y);
+}
+
+static const float one = 1.0;
+
+float modff(float x, float *iptr)
+{
+    __int32_t i0,j0;
+    __uint32_t i;
+    i0 = *(__int32_t*)(&x);
+    j0 = ((i0>>23)&0xff)-0x7f;  /* exponent of x */
+    if(j0<23) {         /* integer part in x */
+        if(j0<0) {          /* |x|<1 */
+            i0 &= 0x80000000;
+            *iptr = *(float*)(&i0);
+            return x;
+        } else {
+            i = (0x007fffff)>>j0;
+            if((i0&i)==0) {         /* x is integral */
+                __uint32_t ix;
+                *iptr = x;
+                ix = *(__int32_t*)(&x);
+                ix &= 0x80000000;
+                x = *(float*)(&ix);
+                return x;
+            } else {
+                i0 &= ~i;
+                *iptr = *(float*)(&i0);
+                return x - *iptr;
+            }
+        }
+    } else {            /* no fraction part */
+        __uint32_t ix;
+        *iptr = x*one;
+        ix = *(__int32_t*)(&x);
+        ix &= 0x80000000;
+        x = *(float*)(ix);
+        return x;
+    }
+}
+
+
+float powf (float x, float y)
+{
+    float d, k, t, r = 1.0;
+    int n, sign, exponent_is_even_int = 0;
+    __int32_t px;
+
+    px = *(__int32_t*)(&x);
+
+    k = modff (y, &d);
+
+    if (k == 0.0) 
+    {
+        /* Exponent y is an integer. */
+        if (modff (ldexpf (y, -1), &t))
+        {
+            /* y is odd. */
+            exponent_is_even_int = 0;
+        }
+        else
+        {
+            /* y is even. */
+            exponent_is_even_int = 1;
+        }
+    }
+
+    if ( !k && fabsf (d) <= 32767 ) 
+    {
+        n = (int) d;
+
+        if ((sign = (n < 0)))
+            n = -n;
+
+        while ( n > 0 ) 
+        {
+            if ((unsigned int) n % 2) 
+                r *= x;
+            x *= x;
+            n = (unsigned int) n / 2;
+        }
+
+        if (sign)
+            r = 1.0 / r;
+
+        return r;
+    }
+    else 
+    {
+        if ( px & 0x80000000 ) 
+        {
+            /* x is negative. */
+            if (k) 
+            {
+                /* y is not an integer. */
+                return 0.0;
+            }
+        }
+
+        x = expf (t);
+
+        if (!exponent_is_even_int) 
+        { 
+            if (px & 0x80000000)
+            {
+                /* y is an odd integer, and x is negative,
+                   so the result is negative. */
+                px = *(__int32_t*)(&x);
+                px |= 0x80000000;
+                x = *(float*)(&px);
+            }
+        }
+    }
+
+    return x;
+}
+
+static const float INV_LN2 = 1.442695040;
+static const float LN2 = 0.693147180;
+static const float p[] = { 0.249999999950, 0.00416028863 };
+static const float q[] = { 0.5, 0.04998717878 };
+
+float expf(float x)
+{
+    int N;
+    float g, z, R, P, Q;
+
+    if(x == 0) return 1.0;
+
+    /* Calculate the exponent. */
+    if (x < 0.0)
+        N = (int) (x * INV_LN2 - 0.5);
+    else
+        N = (int) (x * INV_LN2 + 0.5);
+
+    /* Construct the mantissa. */
+    g = x - N * LN2;
+    z = g * g;
+    P = g * (p[1] * z + p[0]);
+    Q = q[1] * z + q[0];
+    R = 0.5 + P / (Q - P);
+
+    /* Return the floating point value. */
+    N++;
+    return (ldexpf (R, N));
+}
+
+static const float TWO_OVER_PI = 0.6366197723;
+static const float tan_p[] = { -0.958017723e-1 };
+static const float tan_q[] = { -0.429135777,
+    0.971685835e-2 };
+
+float tanf(float x) {
+    float y, f, g, XN, xnum, xden, res;
+    int N;
+
+    y = fabsf (x);
+
+    if (x < 0.0)
+        N = (int) (x * TWO_OVER_PI - 0.5);
+    else
+        N = (int) (x * TWO_OVER_PI + 0.5);
+
+    XN = (float) N;
+
+    f = x - N * __PI_OVER_TWO;
+
+    /* Calculate the polynomial. */ 
+    { 
+        g = f * f;
+
+        xnum = f * (p[0] * g) + f;
+        xden = (q[1] * g + q[0]) * g + 1.0;
+    }
+
+    /* Check for odd or even values. */
+    if (N & 1)
+    {
+        xnum = -xnum;
+        res = xden / xnum;
+    } 
+    else
+    {
+        res = xnum / xden;
+    }
+
+    return (res);
+}
diff --git a/src/ecore/lmath.h b/src/ecore/lmath.h
new file mode 100644 (file)
index 0000000..b86e039
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef LMATH_H
+#define LMATH_H
+
+#include <math.h>
+
+#define M_PI 3.14159265358979323846
+#define __SQRT_HALF 0.70710678118654752440
+#define __PI_OVER_TWO 1.57079632679489661923132
+
+#endif
index e7a95d3..259c61d 100644 (file)
@@ -108,81 +108,3 @@ void rotate_vector(vector_t *q, vector_t *v, vector_t *result) {
 
     /* And we end up with result = q*v*q^{conjugate}. */
 }
-
-static const float HALF_PI = 1.570796326;
-static const float ONE_OVER_PI = 0.318309886;
-static const float r[] = { -0.1666665668,
-                            0.8333025139e-02,
-                           -0.1980741872e-03,
-                            0.2601903036e-5 };
-
-float fabsf(float x) {
-    if(x<0) return -x;
-    return x;
-}
-
-static float sinef(float x, int cosine) {
-    int sgn, N;
-    float y, XN, g, R, res;
-
-    /* Use sin and cos properties to ease computations. */
-    if (cosine)
-    {
-        sgn = 1;
-        y = fabsf (x) + HALF_PI;
-    }
-    else
-    {
-        if (x < 0.0)
-        {
-            sgn = -1;
-            y = -x;
-        }
-        else
-        {
-            sgn = 1;
-            y = x;
-        }
-    }
-
-    /* Calculate the exponent. */
-    if (y < 0.0)
-        N = (int) (y * ONE_OVER_PI - 0.5);
-    else
-        N = (int) (y * ONE_OVER_PI + 0.5);
-    XN = (float) N;
-
-    if (N & 1)
-        sgn = -sgn;
-
-    if (cosine)
-        XN -= 0.5;
-
-    y = fabsf (x) - XN * M_PI;
-
-    if (-1e-5 < y && y < 1e-5)
-        res = y;
-
-    else
-    {
-        g = y * y;
-
-        /* Calculate the Taylor series. */
-        R = (((r[3] * g + r[2]) * g + r[1]) * g + r[0]) * g;
-
-        /* Finally, compute the result. */
-        res = y + y * R;
-    }
-
-    res *= sgn;
-
-    return (res);
-}
-
-float sinf(float x) {
-    return sinef(x, 0);
-}
-
-float cosf(float x) {
-    return sinef(x, 1);
-}
index fdb8454..c169e57 100644 (file)
@@ -2,8 +2,7 @@
 #define MATH_H
 
 #include <math.h>
-
-#define M_PI 3.14159265358979323846
+#include "lmath.h"
 
 /* Four-dimensional affine vector/point. */
 typedef struct vector_t vector_t;
index b08b666..36899d7 100644 (file)
@@ -66,7 +66,7 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
 
     if(!find_closest(ray, dir, &min_i, &min_ind)) {
         vector_t ret;
-        ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0.1;
+        ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0.0;
         return ret;
     }
 
@@ -98,7 +98,6 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
     }
 
     /* Do lighting calculations for each light. */
-
     for(int i = 0; i < buf_region->light_count; i ++) {
         vector_t ldir;
         ldir.c[0] = lights[i].x - intersection.c[0];
@@ -111,34 +110,37 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
         ret.c[1] += lights[i].a * mat->a * mat->g * lights[i].g;
         ret.c[2] += lights[i].a * mat->a * mat->b * lights[i].b;
 
-        if(!find_closest(&intersection, &ldir, &min_i, &min_ind)) {
-            /* apply diffuse */
-            float diffuse = dot_vectors(&ldir, &normal);
-            if(diffuse < 0) diffuse = -diffuse;
-
-            diffuse *= lights[i].d * mat->d;
-            ret.c[0] += diffuse * mat->r * lights[i].r;
-            ret.c[1] += diffuse * mat->g * lights[i].g;
-            ret.c[2] += diffuse * mat->b * lights[i].b;
-            
-            /* apply specular */
-
-            vector_t r;
-            mul_vector(&normal, -2 * dot_vectors(&normal, &ldir), &r);
-            add_vectors(&r, &ldir, &r);
-
-            float specular = powf(dot_vectors(&r, dir), mat->shininess);
-            specular *= lights[i].s * mat->s;
-
-            ret.c[0] += specular * mat->sr * lights[i].r;
-            ret.c[1] += specular * mat->sg * lights[i].g;
-            ret.c[2] += specular * mat->sb * lights[i].b;
-        }
+        if(find_closest(&intersection, &ldir, &min_i, &min_ind)) continue;
+
+        /* apply diffuse */
+        float diffuse = dot_vectors(&ldir, &normal);
+        if(diffuse < 0) diffuse = -diffuse;
+
+        diffuse *= lights[i].d * mat->d;
+        ret.c[0] += diffuse * mat->r * lights[i].r;
+        ret.c[1] += diffuse * mat->g * lights[i].g;
+        ret.c[2] += diffuse * mat->b * lights[i].b;
+        
+        /* apply specular */
+
+        vector_t r;
+        mul_vector(&normal, -2 * dot_vectors(&normal, &ldir), &r);
+        add_vectors(&r, &ldir, &r);
+
+        float specular = powf(dot_vectors(&r, dir), mat->shininess);
+        specular *= lights[i].s * mat->s;
+
+        ret.c[0] += specular * mat->sr * lights[i].r;
+        ret.c[1] += specular * mat->sg * lights[i].g;
+        ret.c[2] += specular * mat->sb * lights[i].b;
     }
 
     if(ret.c[0] > 1) ret.c[0] = 1;
     if(ret.c[1] > 1) ret.c[1] = 1;
     if(ret.c[2] > 1) ret.c[2] = 1;
+    ret.c[0] = 1;
+    ret.c[1] = 1;
+    ret.c[2] = 1;
 
     return ret;
 }
@@ -171,7 +173,6 @@ void render_range() {
     rotate_vector(&cam_rot, &cam_basisy, &cam_basisy);
 
     while(render_start != render_end) {
-#if 0
         float x = (render_start % buf_region->width)
             / (float)buf_region->width - 0.5;
         float y = (render_start / buf_region->width)
@@ -193,9 +194,7 @@ void render_range() {
         result |= (int)(col.c[1] * 255) << 8;
         result |= (int)(col.c[2] * 255) << 16;
 
-        write_render_result(result + 1<<24);
-#endif
-        write_render_result(1<<24);
+        write_render_result(result);
         /* Done, next pixel! */
         render_start ++;
     }
index 4f1e264..af72615 100644 (file)
@@ -53,11 +53,12 @@ void handle_range_request(int id) {
         tdesc->inner_stride = (4 << 16) | 4;
         tdesc->count = (1 << 16) | (shm_region->data_end>>2);
         tdesc->outer_stride = 0;
-        tdesc->src_addr = (void*)shm_region;
+        tdesc->src_addr = (void *)shm_region;
         tdesc->dst_addr = e_get_global_address(target_r, target_c, in_buffer_ptr);
         // initiate DMA
         uint32_t value = E_DMA_STARTUP | ((uint32_t)&dma_desc << 16);
-        *(uint32_t *)e_get_global_address(target_r, target_c, (void *)E_REG_DMA1CONFIG) = value;
+        *(uint32_t *)e_get_global_address(target_r, target_c,
+            (void *)E_REG_DMA1CONFIG) = value;
     }
     else {
         // render data already present, so just send a message IRQ
@@ -95,7 +96,6 @@ void __attribute((interrupt)) range_request_handler(
 
 void __attribute((interrupt)) message_handler() {
     message_intr = 1;
-    shm_region->sph_count = ((uint32_t *)in_buffer_ptr)[0];
 }
 
 void setup_range_request() {
index 2ed7760..e85bfd3 100644 (file)
@@ -1,5 +1,7 @@
+#define _GNU_SOURCE
 #include <stdint.h>
 #include <stdio.h>
+#include <math.h>
 
 #include "e-hal.h"
 #include "e-loader.h"
@@ -64,9 +66,27 @@ int main() {
 
     shm_region->data_end = 0x100;
 
+    shm_region->cam.fov = M_PI/3;
+    shm_region->cam.dw = 1.0;
+
     shm_region->finished = 0;
     shm_region->generation = 1;
 
+    shm_mat_t *material = (void*)((uint8_t*)shm_region + sizeof(*shm_region));
+    material->r = material->g = material->b = 1.0;
+    material->shininess = 1.0;
+    material->sr = material->sg = material->sb = 1.0;
+    material->a = material->s = material->d = 1.0;
+
+    shm_sph_t *sphere = (void *)((uint8_t*)shm_region + sizeof(*shm_region) + sizeof(*material));
+    sphere->x = 0.0;
+    sphere->y = 0.0;
+    sphere->z = 0.0;
+    sphere->r = 10.0;
+    sphere->mat = 0;
+
+    shm_region->data_end = (sizeof(*shm_region) + sizeof(*material) + sizeof(*sphere));
+    /*
     const uint32_t in_buffer_address = 0x52e0;
     for(int i = 0; i < 100; i ++) {
         printf("in buffer content:");
@@ -76,9 +96,9 @@ int main() {
         printf("\n");
         usleep(1000);
     }
+    */
 
     printf("Waiting for rendering to finish...\n");
-    printf("Sphere count (i.e. width): %lx\n", shm_region->sph_count);
     while(shm_region->finished != 1) {}
     printf("Finished rendering!\n");
 
@@ -88,11 +108,13 @@ int main() {
     }
     printf("\n");
 
+    /*
     printf("in buffer content:");
     uint32_t in_buffer[32];
     e_read(&dev, 2, 2, in_buffer_address, in_buffer, 32*4);
     for(int i = 0; i < 32; i ++) printf(" %lx", in_buffer[i]);
     printf("\n");
+    */
 
     e_close(&dev);
     e_shm_release("raytrace_shm");