Now with the actual patch attached...

On Thu, Jun 4, 2015 at 5:03 PM, Vasco Alexandre da Silva Costa <
vasco.co...@gmail.com> wrote:

> Simplified code for:
> - ray generation
> - writing the color output to the frame buffer
>
> On Tue, Jun 2, 2015 at 11:55 PM, Vasco Alexandre da Silva Costa <
> vasco.co...@gmail.com> wrote:
>
>> Hello,
>> I've been trying to make a really simple bare bones rendering loop in C
>> without branches, recursion, etc that we can try to parallelize later.
>>
>> For now I managed to do this for the ray generation part (patch
>> attached). Still need to work on the ray traversal and color computation
>> proper.
>>
>> Regards,
>>
>> --
>> Vasco Alexandre da Silva Costa
>> PhD Student at Department of Information Systems and Computer Science
>> Instituto Superior Técnico/University of Lisbon, Portugal
>>
>
>
>
> --
> Vasco Alexandre da Silva Costa
> PhD Student at Department of Information Systems and Computer Science
> Instituto Superior Técnico/University of Lisbon, Portugal
>



-- 
Vasco Alexandre da Silva Costa
PhD Student at Department of Information Systems and Computer Science
Instituto Superior Técnico/University of Lisbon, Portugal
Index: src/rt/do.c
===================================================================
--- src/rt/do.c	(revision 65176)
+++ src/rt/do.c	(working copy)
@@ -50,7 +50,9 @@
 #include "./rtuif.h"
 #include "./ext.h"
 
+#include "scanline.h"
 
+
 /***** Variables shared with viewing model *** */
 extern FILE *outfp;			/* optional pixel output file */
 extern mat_t view2model;
@@ -541,8 +543,158 @@
     }
 }
 
+static int ibackground[3] = {0, 0, 50};         /* integer 0..255 version */
+static int inonbackground[3] = {0, 0, 51};	/* integer non-background */
+static size_t pwidth = 3;                       /* Width of each pixel (in bytes) */
+extern fb *fbp;                                 /* Framebuffer handle */
+static struct scanline scanline;
 
 /**
+ * Arrange to have the pixel output.  a_uptr has region pointer, for
+ * reference.
+ */
+void
+my_view_pixel(struct application *ap)
+{
+    int r, g, b;
+    unsigned char *pixelp;
+    struct scanline *slp;
+
+    if (ap->a_user == 0) {
+	/* Shot missed the model, don't dither */
+	r = ibackground[0];
+	g = ibackground[1];
+	b = ibackground[2];
+	VSETALL(ap->a_color, -1e-20);	/* background flag */
+    } else {
+        r = ap->a_color[0]*255;
+        g = ap->a_color[1]*255;
+        b = ap->a_color[2]*255;
+	if (r > 255) r = 255;
+	else if (r < 0) r = 0;
+	if (g > 255) g = 255;
+	else if (g < 0) g = 0;
+	if (b > 255) b = 255;
+	else if (b < 0) b = 0;
+	if (r == ibackground[0] && g == ibackground[1] &&  b == ibackground[2]) {
+	    r = inonbackground[0];
+	    g = inonbackground[1];
+	    b = inonbackground[2];
+	}
+
+	/* Make sure it's never perfect black */
+	if (r==0 && g==0 && b==0)
+	    b = 1;
+    }
+
+    slp = &scanline;
+    if (slp->sl_buf == (unsigned char *)0) {
+        slp->sl_buf = (unsigned char *)bu_calloc(width, pwidth, "sl_buf scanline buffer");
+        slp->sl_left = width;
+    }
+    pixelp = slp->sl_buf+(ap->a_x*pwidth);
+    *pixelp++ = r;
+    *pixelp++ = g;
+    *pixelp++ = b;
+    if (--(slp->sl_left) <= 0) {
+        /* do_eol */
+        if (fbp != FB_NULL) {
+            size_t npix;
+            bu_semaphore_acquire(BU_SEM_SYSCALL);
+            npix = fb_write(fbp, 0, ap->a_y, (unsigned char *)slp->sl_buf, width);
+            bu_semaphore_release(BU_SEM_SYSCALL);
+            if (npix < width)
+                bu_exit(EXIT_FAILURE, "scanline fb_write error");
+        }
+        bu_free(slp->sl_buf, "sl_buf scanline buffer");
+        slp->sl_buf = (unsigned char *)0;
+    }
+}
+
+void
+my_pixel(int cpu, int pixelnum)
+{
+    struct application a;
+    vect_t point;		/* Ref point on eye or view plane */
+    vect_t colorsum = {(fastf_t)0.0, (fastf_t)0.0, (fastf_t)0.0};
+
+
+    /* Obtain fresh copy of global application struct */
+    a = APP;				/* struct copy */
+    a.a_resource = &resource[cpu];
+
+    a.a_y = (int)(pixelnum/width);
+    a.a_x = (int)(pixelnum - (a.a_y * width));
+
+    /* our starting point, used for non-jitter */
+    VJOIN2 (point, viewbase_model, a.a_x, dx_model, a.a_y, dy_model);
+
+    /* not tracing the corners of a prism by default */
+    a.a_pixelext=(struct pixel_ext *)NULL;
+
+    /* LOOP BELOW IS UNROLLED ONE SAMPLE SINCE THAT'S THE COMMON CASE.
+     *
+     * XXX - If you edit the unrolled or non-unrolled section, be sure
+     * to edit the other section.
+     */
+    /* not hypersampling, so just do it */
+
+    VMOVE(a.a_ray.r_pt, point);
+    VMOVE(a.a_ray.r_dir, APP.a_ray.r_dir);
+    
+    a.a_level = 0;		/* recursion level */
+    a.a_purpose = "main ray";
+    (void)rt_shootray(&a);
+    VADD2(colorsum, colorsum, a.a_color);
+
+    my_view_pixel(&a);
+    return;
+}
+
+void
+my_run(int a, int b)
+{
+    size_t cpu = 0;
+    int per_processor_chunk = 0;	/* how many pixels to do at once */
+
+    int cur_pixel;			/* current pixel number, 0..last_pixel */
+    int last_pixel;			/* last pixel number */
+
+    int pixelnum;
+
+    cur_pixel = a;
+    last_pixel = b;
+
+    /*
+     * SERIAL case -- one CPU does all the work.
+     */
+    npsw = 1;
+
+    /* The more CPUs at work, the bigger the bites we take */
+    if (per_processor_chunk <= 0) per_processor_chunk = npsw;
+
+    RT_CK_RESOURCE(&resource[cpu]);
+
+    bu_semaphore_acquire(RT_SEM_WORKER);
+
+    for (pixelnum = cur_pixel; pixelnum <= last_pixel; pixelnum++) {
+        my_pixel(cpu, pixelnum);
+    }
+
+    bu_semaphore_release(RT_SEM_WORKER);
+
+    /* Tally up the statistics */
+    for (cpu=0; cpu < npsw; cpu++) {
+	if (resource[cpu].re_magic != RESOURCE_MAGIC) {
+	    bu_log("ERROR: CPU %d resources corrupted, statistics bad\n", cpu);
+	    continue;
+	}
+	rt_add_res_stats(APP.a_rt_i, &resource[cpu]);
+    }
+    return;
+}
+
+/**
  * Do all the actual work to run a frame.
  *
  * Returns -1 on error, 0 if OK.
@@ -810,7 +962,7 @@
      * It may prove desirable to do this in chunks
      */
     rt_prep_timer();
-
+#if 0
     if (incr_mode) {
 	for (incr_level = 1; incr_level <= incr_nlevel; incr_level++) {
 	    if (incr_level > 1)
@@ -835,6 +987,15 @@
 	pix_start = 0;
 	pix_end = (int)(height*width - 1);
     }
+#endif
+    printf("pix_start: %d, pix_end: %d\n", pix_start, pix_end);
+    my_run(pix_start, pix_end);
+
+    /* Reset values to full size, for next frame (if any) */
+    pix_start = 0;
+    pix_end = (int)(height*width - 1);
+    /**/
+    
     utime = rt_get_timer(&times, &wallclock);
 
     /*
------------------------------------------------------------------------------
_______________________________________________
BRL-CAD Developer mailing list
brlcad-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-devel

Reply via email to