17 #define TACHYON_INTERNAL 1    34   if (primary->depth > 0) {
    36     return primary->scene->shader(primary);
    40   return primary->scene->bgtexfunc(primary);
    45 int node_row_sendrecv(
int my_tid, 
thr_parms * t, scenedef *scene, 
    46                       int *sentrows, 
int y) {
    49   if (scene->nodes > 1) {
    56 #if defined(USEATOMICBARRIERS)    68     if (rowbarcnt == t->
nthr) {
    87       for (row=(*sentrows); row<rowsdone; row++) { 
   126 int node_finish_row_sendrecvs(
int my_tid, 
thr_parms * t, scenedef *scene, 
int *sentrows) {
   128   if (scene->nodes > 1) {
   133 #if defined(USEATOMICBARRIERS)   141       int rowsdone, totalrows;
   160       for (row=(*sentrows); row<rowsdone; row++) { 
   183   int R = (int) (col.r * 255.0f); 
   184   int G = (int) (col.g * 255.0f); 
   185   int B = (int) (col.b * 255.0f); 
   187   if (R > 255) R = 255;      
   191   if (G > 255) G = 255;      
   195   if (B > 255) B = 255;      
   203 #pragma omp parallel default( none ) firstprivate(t)   206   unsigned long * local_mbox = NULL;
   210   int x, y, do_ui, hskip;
   211   int startx, stopx, xinc, starty, stopy, yinc, hsize, vres;
   213 #if defined(RT_ACCUMULATE_ON)   214   float accum_norm = 1.0f;
   222   int my_tid = omp_get_thread_num(); 
   223   unsigned long my_serialno = 1; 
   226   unsigned long my_serialno = t->
serialno;
   242   hsize  = scene->hres*3;
   245   do_ui = (scene->mynode == 0 && my_tid == 0);
   247 #if !defined(DISABLEMBOX)   250   local_mbox = (
unsigned long *)calloc(
sizeof(
unsigned long)*scene->objgroup.numobjects, 1);
   253     local_mbox = (
unsigned long *)calloc(
sizeof(
unsigned long)*scene->objgroup.numobjects, 1);
   261 #if defined(RT_ACCUMULATE_ON)   263   if (scene->accum_count > 0) 
   264     accum_norm = 1.0f / scene->accum_count;
   274   if (
sizeof(
unsigned long) < 8) {
   284     if (local_mbox != NULL) {
   286       if (my_serialno > (((
unsigned long) 1) << ((
sizeof(
unsigned long) * 8) - 3))) {
   287         memset(local_mbox, 0, 
sizeof(
unsigned long)*scene->objgroup.numobjects);
   295      unsigned int rngseed = 
tea4(my_tid, scene->mynode);
   296 #if defined(RT_ACCUMULATE_ON)   297      rngseed = 
tea4(scene->accum_count, rngseed);
   298      camray_init(scene, &primary, my_serialno, local_mbox, rngseed,
   299                  tea4(scene->accum_count, scene->accum_count));
   302      camray_init(scene, &primary, my_serialno, local_mbox, rngseed, rngseed);
   308   cachefrng = primary.frng;
   313   if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) {
   315     unsigned char *img = (
unsigned char *) scene->img;
   317 #
if defined(THR) && !defined(MPI)
   319     if (t->sched_dynamic) {
   321       int end = scene->hres * scene->vres - 1;
   327         int myend=pixel+tilesz-1;
   330         for (tpxl=mystart; tpxl<=myend; tpxl++) {
   331           int y = tpxl / scene->hres;
   332           int x = tpxl - (y*scene->hres);
   333           unsigned int idx = y*scene->hres + x;  
   334 #if defined(RT_ACCUMULATE_ON)   335           if (scene->accum_count) {
   336             primary.randval =  
tea4(idx, scene->accum_count);
   340           int addr = hsize * y + (3 * (startx - 1 + x));  
   343           primary.frng = cachefrng; 
   344           col=scene->camera.cam_ray(&primary, x, y);   
   346 #if defined(RT_ACCUMULATE_ON)   348           if (scene->accum_buf != NULL) {
   349             scene->accum_buf[addr    ] += col.r;
   350             col.r = scene->accum_buf[addr    ] * accum_norm;
   351             scene->accum_buf[addr + 1] += col.g;
   352             col.g = scene->accum_buf[addr + 1] * accum_norm;
   353             scene->accum_buf[addr + 2] += col.b;
   354             col.b = scene->accum_buf[addr + 2] * accum_norm;
   361         if (do_ui && !(mystart % (16*scene->hres))) {
   369 #pragma omp for schedule(runtime)   371     for (y=starty; y<=stopy; y+=yinc) {
   372       int addr = hsize * (y - 1) + (3 * (startx - 1));  
   373       for (x=startx; x<=stopx; x+=xinc,addr+=hskip) {
   374         unsigned int idx = y*scene->hres + x;  
   375 #if defined(RT_ACCUMULATE_ON)   376         if (scene->accum_count) {
   377           primary.randval =  
tea4(idx, scene->accum_count);
   382         primary.frng = cachefrng; 
   383         col=scene->camera.cam_ray(&primary, x, y);   
   385 #if defined(RT_ACCUMULATE_ON)   387         if (scene->accum_buf != NULL) {
   388           scene->accum_buf[addr    ] += col.r;
   389           col.r = scene->accum_buf[addr    ] * accum_norm;
   390           scene->accum_buf[addr + 1] += col.g;
   391           col.g = scene->accum_buf[addr + 1] * accum_norm;
   392           scene->accum_buf[addr + 2] += col.b;
   393           col.b = scene->accum_buf[addr + 2] * accum_norm;
   400       if (do_ui && !((y-1) % 16)) {
   406       node_row_sendrecv(my_tid, t, scene, &sentrows, y);
   410 #if defined(THR) && !defined(MPI)   417     float *img = (
float *) scene->img;
   419 #
if defined(THR) && !defined(MPI)
   421     if (t->sched_dynamic) {
   423       int end = scene->hres * scene->vres - 1;
   429         int myend=pixel+tilesz-1;
   432         for (tpxl=mystart; tpxl<=myend; tpxl++) {
   433           int y = tpxl / scene->hres;
   434           int x = tpxl - (y*scene->hres);
   435           unsigned int idx = y*scene->hres + x;  
   437           addr = hsize * y + (3 * (startx - 1 + x));    
   439 #if defined(RT_ACCUMULATE_ON)   440           if (scene->accum_count) {
   441             primary.randval =  
tea4(idx, scene->accum_count);
   446           primary.frng = cachefrng; 
   447           col=scene->camera.cam_ray(&primary, x, y);    
   449 #if defined(RT_ACCUMULATE_ON)   451           if (scene->accum_buf != NULL) {
   452             scene->accum_buf[addr    ] += col.r;
   453             col.r = scene->accum_buf[addr    ] * accum_norm;
   454             scene->accum_buf[addr + 1] += col.g;
   455             col.g = scene->accum_buf[addr + 1] * accum_norm;
   456             scene->accum_buf[addr + 2] += col.b;
   457             col.b = scene->accum_buf[addr + 2] * accum_norm;
   462           img[addr + 1] = col.g;   
   463           img[addr + 2] = col.b;   
   466         if (do_ui && !(mystart % (16*scene->hres))) {
   474 #pragma omp for schedule(runtime)   476     for (y=starty; y<=stopy; y+=yinc) {
   477       addr = hsize * (y - 1) + (3 * (startx - 1));    
   478       for (x=startx; x<=stopx; x+=xinc,addr+=hskip) {
   479         unsigned int idx = y*scene->hres + x;  
   480 #if defined(RT_ACCUMULATE_ON)   481         if (scene->accum_count) {
   482           primary.randval =  
tea4(idx, scene->accum_count);
   487         primary.frng = cachefrng; 
   488         col=scene->camera.cam_ray(&primary, x, y);     
   490 #if defined(RT_ACCUMULATE_ON)   492         if (scene->accum_buf != NULL) {
   493           scene->accum_buf[addr    ] += col.r;
   494           col.r = scene->accum_buf[addr    ] * accum_norm;
   495           scene->accum_buf[addr + 1] += col.g;
   496           col.g = scene->accum_buf[addr + 1] * accum_norm;
   497           scene->accum_buf[addr + 2] += col.b;
   498           col.b = scene->accum_buf[addr + 2] * accum_norm;
   503         img[addr + 1] = col.g;   
   504         img[addr + 2] = col.b;   
   507       if (do_ui && !((y-1) % 16)) {
   513       node_row_sendrecv(my_tid, t, scene, &sentrows, y);
   517 #if defined(THR) && !defined(MPI)   527   my_serialno = primary.serial + 1;
   536   if (
sizeof(
unsigned long) < 8) {
   537     memset(local_mbox, 0, 
sizeof(
unsigned long)*scene->objgroup.numobjects);
   540   if (local_mbox != NULL)
   546     if (local_mbox != NULL)
   552   if (scene->nodes == 1)
   556     node_finish_row_sendrecvs(my_tid, t, scene, &sentrows);
 int stopx
ending X pixel index 
void convert_rgb96f_rgb24u(color col, unsigned char *img)
int rt_atomic_int_get(rt_atomic_int_t *atomp)
get an atomic int variable 
int rt_thread_barrier(rt_barrier_t *barrier, int increment)
synchronize on counting barrier primitive 
int nthr
total number of worker threads 
scenedef * scene
scene handle 
rt_barrier_t * runbar
sleeping thread pool barrier 
int starty
starting Y pixel index 
Tachyon cross-platform thread creation and management, atomic operations, and CPU feature query APIs...
int startx
starting X pixel index 
int rt_atomic_int_fetch_and_add(rt_atomic_int_t *atomp, int inc)
fetch an atomic int and add inc to it, returning original value 
int rt_par_sendrecvscanline_get_totalrows(rt_parhandle voidparhandle, rt_parbuf voidhandle)
void * thread_trace(thr_parms *t)
unsigned long * local_mbox
grid acceleration mailbox structure 
color trace(ray *primary)
Tachyon cross-platform timers, special math function wrappers, and RNGs. 
unsigned long serialno
ray mailbox test serial number 
void rt_par_sendrecvscanline(rt_parhandle voidparhandle, rt_parbuf voidhandle)
int rt_atomic_int_set(rt_atomic_int_t *atomp, int val)
set an atomic int variable 
unsigned int tea4(unsigned int v0, unsigned int v1)
void camray_init(scenedef *scene, ray *primary, unsigned long serial, unsigned long *mbox, unsigned int aarandval, unsigned int aorandval)
void rt_ui_progress(int percent)
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
int rt_atomic_int_add_and_fetch(rt_atomic_int_t *atomp, int inc)
fetch an atomic int and add inc to it, returning new value 
int tid
worker thread index 
int stopy
ending Y pixel index 
void intersect_objects(ray *ry)