2017-04-26 17:20:15 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
2017-04-26 17:20:15 +02:00
|
|
|
#include "rt.h"
|
|
|
|
|
|
|
|
#define PAGE_SIZE 4096
|
|
|
|
|
|
|
|
struct r_struct {
|
|
|
|
INT pad1[PAGE_SIZE]; /* This pad is inserted to avoid
|
2017-04-26 18:03:02 +02:00
|
|
|
false-sharing due to artifacts
|
|
|
|
of not having a private space
|
|
|
|
in the sproc model */
|
2017-04-26 17:20:15 +02:00
|
|
|
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
|
2017-04-26 18:03:02 +02:00
|
|
|
false-sharing due to artifacts
|
|
|
|
of not having a private space
|
|
|
|
in the sproc model */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
} 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(RAY *rdst, RAY *rsrc)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
rdst->id = rsrc->id;
|
|
|
|
rdst->x = rsrc->x;
|
|
|
|
rdst->y = rsrc->y;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
VecCopy(rdst->P, rsrc->P);
|
|
|
|
VecCopy(rdst->D, rsrc->D);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
rdst->level = rsrc->level;
|
|
|
|
rdst->weight = rsrc->weight;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Other fields are initialized with InitRay. */
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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(INT TreeDepth, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
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. */
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
unsigned long powint(long i, long j)
|
|
|
|
{
|
|
|
|
long k;
|
|
|
|
long 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(RAY *rmsg, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
raystruct[pid].StackTop++;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (raystruct[pid].StackTop == raystruct[pid].StackSize)
|
|
|
|
{
|
|
|
|
fprintf(stderr,"%s: Ray tree stack overflow.\n", ProgName);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
CopyRayMsg(&(raystruct[pid].Stack[raystruct[pid].StackTop]), rmsg);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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(RAY *rmsg, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
if (raystruct[pid].StackTop < 0)
|
|
|
|
return (RTS_EMPTY);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
CopyRayMsg(rmsg, &(raystruct[pid].Stack[raystruct[pid].StackTop]));
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
raystruct[pid].StackTop--;
|
|
|
|
return (RTS_VALID);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|