| /*************************************************************************/ |
| /* */ |
| /* Copyright (c) 1994 Stanford University */ |
| /* */ |
| /* All rights reserved. */ |
| /* */ |
| /* Permission is given to use, copy, and modify this software for any */ |
| /* non-commercial purpose as long as this copyright notice is not */ |
| /* removed. All other uses, including redistribution in whole or in */ |
| /* part, are forbidden without prior written permission. */ |
| /* */ |
| /* This software is provided with absolutely no warranty and no */ |
| /* support. */ |
| /* */ |
| /*************************************************************************/ |
| |
| |
| /* |
| * NAME |
| * raystack.c |
| * |
| * DESCRIPTION |
| * This file contains the private data and code for managing the ray tree |
| * stack of ray messages. |
| * |
| * A stack is used to eliminate recursion when processing a ray tree. |
| * |
| * The ray tree stack contains ray messages for secondary reflection and |
| * refraction rays for pixel. Shadow rays are not put on the stack; they |
| * are processed sequentially after a ray tree node hit. |
| * |
| * The storage for the stack is allocated initially before processing any |
| * rays. The size is dependent on max_ray_tree_step. Each copy of this |
| * code needs to have its own private stack. |
| */ |
| |
| |
| #include <stdio.h> |
| #include <math.h> |
| #include "rt.h" |
| |
| #define PAGE_SIZE 4096 |
| |
| struct r_struct { |
| INT pad1[PAGE_SIZE]; /* This pad is inserted to avoid |
| false-sharing due to artifacts |
| of not having a private space |
| in the sproc model */ |
| RAY *Stack; /* Ptr to ray tree stack. */ |
| INT StackTop; /* Top of ray tree stack. */ |
| INT StackSize; /* Maximum size of ray tree stack. */ |
| INT pad2[PAGE_SIZE]; /* This pad is inserted to avoid |
| false-sharing due to artifacts |
| of not having a private space |
| in the sproc model */ |
| |
| } raystruct[MAX_PROCS]; |
| |
| |
| /* |
| * NAME |
| * CopyRayMsg - copy a ray structure from a source to a destination |
| * |
| * SYNOPSIS |
| * VOID CopyRayMsg(rdst, rsrc) |
| * RAY *rdst; // Destination ray message. |
| * RAY *rsrc; // Source ray message. |
| * |
| * RETURNS |
| * Nothing. |
| */ |
| |
| VOID CopyRayMsg(rdst, rsrc) |
| RAY *rdst; |
| RAY *rsrc; |
| { |
| rdst->id = rsrc->id; |
| rdst->x = rsrc->x; |
| rdst->y = rsrc->y; |
| |
| VecCopy(rdst->P, rsrc->P); |
| VecCopy(rdst->D, rsrc->D); |
| |
| rdst->level = rsrc->level; |
| rdst->weight = rsrc->weight; |
| |
| /* Other fields are initialized with InitRay. */ |
| } |
| |
| |
| |
| /* |
| * NAME |
| * InitRayTreeStack - initialize the ray tree stack |
| * |
| * SYNOPSIS |
| * VOID InitRayTreeStack(TreeDepth,pid) |
| * INT TreeDepth. // Max depth of a ray tree. |
| * INT pid. |
| * |
| * DESCRIPTION |
| * Initialize the ray tree stack by setting the stack pointer to 0 and |
| * allocating memory for the stack. |
| * |
| * RETURNS |
| * Nothing. |
| */ |
| |
| VOID InitRayTreeStack(TreeDepth, pid) |
| INT TreeDepth; |
| INT pid; |
| { |
| unsigned int powint(); |
| |
| raystruct[pid].StackSize = powint(2, TreeDepth) - 1; |
| raystruct[pid].StackSize += NumSubRays; |
| raystruct[pid].Stack = LocalMalloc(raystruct[pid].StackSize*sizeof(RAY), "raystack.c"); |
| raystruct[pid].StackTop = -1; /* Empty condition. */ |
| } |
| |
| |
| unsigned int powint(i,j) |
| int i,j; |
| { |
| int k; |
| int temp = 1; |
| |
| for (k = 0; k < j; k++) |
| temp = temp*i; |
| return temp; |
| } |
| |
| |
| /* |
| * NAME |
| * PushRayTreeStack - push a ray message onto the ray tree stack |
| * |
| * SYNOPSIS |
| * VOID PushRayTreeStack(rmsg,pid) |
| * RAY *rmsg; // Ray message. |
| * INT pid. |
| * |
| * RETURNS |
| * Nothing. |
| */ |
| |
| VOID PushRayTreeStack(rmsg, pid) |
| RAY *rmsg; |
| INT pid; |
| { |
| raystruct[pid].StackTop++; |
| |
| if (raystruct[pid].StackTop == raystruct[pid].StackSize) |
| { |
| fprintf(stderr,"%s: Ray tree stack overflow.\n", ProgName); |
| exit(-1); |
| } |
| |
| CopyRayMsg(&(raystruct[pid].Stack[raystruct[pid].StackTop]), rmsg); |
| } |
| |
| |
| |
| /* |
| * NAME |
| * PopRayTreeStack - pop a ray message from the ray tree stack |
| * |
| * SYNOPSIS |
| * INT PopRayTreeStack(rmsg) |
| * RAY *rmsg; // Will receive popped ray message. |
| * INT pid; |
| * |
| * RETURNS |
| * Either empty or popped status code. |
| */ |
| |
| INT PopRayTreeStack(rmsg, pid) |
| RAY *rmsg; |
| INT pid; |
| { |
| if (raystruct[pid].StackTop < 0) |
| return (RTS_EMPTY); |
| |
| CopyRayMsg(rmsg, &(raystruct[pid].Stack[raystruct[pid].StackTop])); |
| |
| raystruct[pid].StackTop--; |
| return (RTS_VALID); |
| } |
| |