Sanchayan Maity
2fcc51c2c1
While at it also add the libpthread static library amd m5op_x86 for matrix multiplication test code as well. Note that the splash2 benchmark code does not comply with gem5 coding guidelines. Academic guys never seem to follow 80 columns and no whitespace guideline :(.
316 lines
12 KiB
C
316 lines
12 KiB
C
/*************************************************************************/
|
|
/* */
|
|
/* 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. */
|
|
/* */
|
|
/*************************************************************************/
|
|
|
|
|
|
#ifndef _PATCH_H
|
|
#define _PATCH_H
|
|
|
|
#include "structs.H"
|
|
|
|
/************************************************************************
|
|
*
|
|
* Constants
|
|
*
|
|
*************************************************************************/
|
|
|
|
#define F_COPLANAR (5.0e-2) /* H(P) < F_COPLANAR then P is on the plane */
|
|
#define N_VISIBILITY_TEST_RAYS (10) /* number of "random", "magic" rays fired
|
|
between patches to test visibility */
|
|
|
|
#define FF_GEOMETRY_ERROR (1.0) /* FF relative error due to Fdf approx
|
|
and cosine approx of angle */
|
|
#define FF_GEOMETRY_VARIANCE (1.0) /* FF relative varance with in elem */
|
|
#define FF_VISIBILITY_ERROR (1.0 / N_VISIBILITY_TEST_RAYS)
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Intersection code
|
|
*
|
|
*************************************************************************/
|
|
|
|
#define POINT_POSITIVE_SIDE (1)
|
|
#define POINT_NEGATIVE_SIDE (2)
|
|
#define POINT_ON_PLANE (0)
|
|
|
|
#define P1_POSITIVE (1)
|
|
#define P1_NEGATIVE (2)
|
|
#define P2_POSITIVE (4)
|
|
#define P2_NEGATIVE (8)
|
|
#define P3_POSITIVE (16)
|
|
#define P3_NEGATIVE (32)
|
|
#define ANY_POSITIVE (P1_POSITIVE | P2_POSITIVE | P3_POSITIVE)
|
|
#define ANY_NEGATIVE (P1_NEGATIVE | P2_NEGATIVE | P3_NEGATIVE)
|
|
#define POSITIVE_SIDE(code) (((code) & ANY_NEGATIVE) == 0)
|
|
#define NEGATIVE_SIDE(code) (((code) & ANY_POSITIVE) == 0)
|
|
#define INTERSECTING(code) ( ((code) & ANY_NEGATIVE) \
|
|
&& ((code) & ANY_POSITIVE) )
|
|
#define P1_CODE(code) (code & 3)
|
|
#define P2_CODE(code) ((code >> 2) & 3)
|
|
#define P3_CODE(code) ((code >> 4) & 3)
|
|
|
|
/************************************************************************
|
|
*
|
|
* Visibility Testing
|
|
*
|
|
*************************************************************************/
|
|
|
|
#define VISIBILITY_UNDEF ((float)-1.0)
|
|
#define PATCH_CACHE_SIZE (2) /* The first two cache entries
|
|
covers about 95% of the total cache hits, so using
|
|
more doesn't help too much. */
|
|
|
|
/************************************************************************
|
|
*
|
|
* Refinement Advice
|
|
*
|
|
*************************************************************************/
|
|
|
|
#define _NO_INTERACTION (1)
|
|
#define _NO_REFINEMENT_NECESSARY (2)
|
|
#define _REFINE_PATCH_1 (4)
|
|
#define _REFINE_PATCH_2 (8)
|
|
#define _NO_VISIBILITY_NECESSARY (16)
|
|
|
|
#define NO_INTERACTION(c) ((c) & _NO_INTERACTION)
|
|
#define NO_REFINEMENT_NECESSARY(c) ((c) & _NO_REFINEMENT_NECESSARY)
|
|
#define REFINE_PATCH_1(c) ((c) & _REFINE_PATCH_1)
|
|
#define REFINE_PATCH_2(c) ((c) & _REFINE_PATCH_2)
|
|
#define NO_VISIBILITY_NECESSARY(c) ((c) & _NO_VISIBILITY_NECESSARY)
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Element Vertex
|
|
*
|
|
* ElementVertex represents a vertex of an element. A vertex structure
|
|
* is shared by those elements which contain the vertex as part of their
|
|
* vertex list.
|
|
*
|
|
*************************************************************************/
|
|
|
|
typedef struct _elemvertex {
|
|
Vertex p ; /* Coordinate of the vertex */
|
|
Rgb col ; /* Color of the vertex */
|
|
float weight ; /* weight */
|
|
Shared_Lock *ev_lock ;
|
|
} ElemVertex ;
|
|
|
|
|
|
#define N_ELEMVERTEX_ALLOCATE (16)
|
|
|
|
/************************************************************************
|
|
*
|
|
* Edge
|
|
*
|
|
* Edge represents each edge of the element. Two adjacent elements
|
|
* share the same edge. As an element is subdivided, the edge is also
|
|
* subdivided. The edges form a binary tree, which can be viewed as a
|
|
* projection of the element subdivision along an edge of the element.
|
|
* In other words, the edge structure binds elements at the same height.
|
|
* Note that the vertices may appear in reverse order in the edge structure
|
|
* with respect to the order in the patch/element definition.
|
|
*
|
|
*************************************************************************/
|
|
|
|
typedef struct _edge {
|
|
ElemVertex *pa, *pb ;
|
|
struct _edge *ea, *eb ; /* Edge (A-center) and (center-B) */
|
|
Shared_Lock *edge_lock ; /* Use segment0 */
|
|
} Edge ;
|
|
|
|
|
|
#define N_EDGE_ALLOCATE (16)
|
|
|
|
#define _LEAF_EDGE(e) ((e)->ea == 0)
|
|
#define EDGE_REVERSE(e,a,b) ((e)->pa == (b))
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Planar equation
|
|
*
|
|
* Plane equation (in implicit form) of the triangle patch.
|
|
* A point P on the plane satisfies
|
|
* (N.P) + C = 0
|
|
* where N is the normal vector of the patch, C is a constant which
|
|
* is the distance of the plane from the origin scaled by -|N|.
|
|
*
|
|
*************************************************************************/
|
|
|
|
typedef struct {
|
|
Vertex n ; /* Normal vector (normalized) */
|
|
float c ; /* Constant */
|
|
/* Nx*x + Ny*y + Nz*z + C = 0 */
|
|
} PlaneEqu ;
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Patch (also a node of the BSP tree)
|
|
*
|
|
* The Patch represents a triangular patch (input polygon) of the given
|
|
* geometric model (i.e., room scene). The Patch contains 'per-patch'
|
|
* information such as the plane equation, area, and color. The Patch also
|
|
* serves as a node of the BSP tree which is used to test patch-patch
|
|
* visibility. The Patch points to the root level of the element quad-tree.
|
|
* Geometrically speaking, the Patch and the root represent the same
|
|
* triangle.
|
|
* Although coordinates of the vertices are given by the Edge structure,
|
|
* copies are stored in the Patch to allow fast access to the coordinates
|
|
* during the visibility test.
|
|
* For cost based task distribution another structure, Patch_Cost, is
|
|
* also used. This structure is made separate from the Patch structure
|
|
* since gathering cost statistics is a frequently read/write operation.
|
|
* If it were in the Patch structure, updating a cost would result in
|
|
* invalidation of the Patch structure and cause cache misses during
|
|
* BSP traversal.
|
|
*
|
|
*************************************************************************/
|
|
|
|
struct _element ;
|
|
|
|
typedef struct _patch {
|
|
ElemVertex *ev1, *ev2, *ev3 ; /* ElemVertecies of the patch */
|
|
Edge *e12, *e23, *e31 ; /* Edges of the patch */
|
|
Vertex p1, p2, p3 ; /* Vertices of the patch */
|
|
PlaneEqu plane_equ ; /* Plane equation H(x,y,z) */
|
|
float area ; /* Area of the patch */
|
|
Rgb color ; /* Diffuse color of the patch */
|
|
/* (reflectance) */
|
|
Rgb emittance ; /* Radiant emmitence */
|
|
|
|
struct _patch *bsp_positive ; /* BSP tree H(x,y,z) >= 0 */
|
|
struct _patch *bsp_negative ; /* H(x,y,z) < 0 */
|
|
struct _patch *bsp_parent ; /* BSP backpointer to the parent*/
|
|
|
|
struct _element *el_root ; /* Root of the element tree */
|
|
long seq_no ; /* Patch sequence number */
|
|
} Patch ;
|
|
|
|
|
|
typedef struct {
|
|
Patch *patch ;
|
|
Shared_Lock *cost_lock ; /* Cost variable lock */
|
|
long n_bsp_node ; /* Number of BSP nodes visited */
|
|
long n_total_inter ; /* Total number of interactions */
|
|
long cost_estimate ; /* Cost estimate */
|
|
long cost_history[11] ; /* Cost history */
|
|
} Patch_Cost ;
|
|
|
|
/* Patch cost:
|
|
Visiting a node in BSP tree: 150 cyc (overall)
|
|
Gathering ray per interaction: 50 cyc (overall avg) */
|
|
|
|
#define PATCH_COST(p) ((p)->n_bsp_node * 3 + (p)->n_total_inter)
|
|
#define PATCH_COST_ESTIMATE(p) ((p)->cost_history[0] \
|
|
+ ((p)->cost_history[1] >> 1)\
|
|
+ ((p)->cost_history[2] >> 2) )
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Element
|
|
*
|
|
* The Element represents each node of the quad-tree generated by the
|
|
* hierarchical subdivision. The Element structure consists of:
|
|
* - pointers to maintain the tree structure
|
|
* - a linear list of interacting elements
|
|
* - radiosity value of the element
|
|
* - pointer to the vertex and edge data structures
|
|
*
|
|
* To allow smooth radiosity interpolation across elements, an element
|
|
* shares edges and vertices with adjacent elements.
|
|
*
|
|
*************************************************************************/
|
|
|
|
struct _interact ;
|
|
|
|
typedef struct _element {
|
|
Shared_Lock *elem_lock ; /* Element lock variable (seg 1) */
|
|
Patch *patch ; /* Original patch of the element */
|
|
|
|
struct _element *parent ; /* Quad tree (parent) */
|
|
struct _element *center ; /* (center triangle) */
|
|
struct _element *top ; /* (top) */
|
|
struct _element *left ; /* (left) */
|
|
struct _element *right ; /* (right) */
|
|
|
|
struct _interact *interactions ; /* Top of light interaction list */
|
|
long n_interactions ; /* Total # of interactions */
|
|
struct _interact *vis_undef_inter ; /* Top of visibility undef list */
|
|
long n_vis_undef_inter ; /* # of interactions whose visibility
|
|
is not yet calculated */
|
|
Rgb rad ; /* Radiosity of this element
|
|
(new guess of B) */
|
|
Rgb rad_in ; /* Sum of anscestor's radiosity */
|
|
Rgb rad_subtree ; /* Area weighted sum of subtree's
|
|
radiosity (includes this elem) */
|
|
long join_counter ; /* # of unfinished subprocesses */
|
|
|
|
ElemVertex *ev1, *ev2, *ev3 ; /* Vertices of the element */
|
|
Edge *e12, *e23, *e31 ; /* Edges of the element */
|
|
float area ; /* Area of the element */
|
|
} Element ;
|
|
|
|
|
|
#define _LEAF_ELEMENT(e) ((e)->center == 0)
|
|
|
|
#if MEM_CONSISTENCY_PROCESSOR
|
|
#define LEAF_ELEMENT(e) _LEAF_ELEMENT((e))
|
|
#endif
|
|
|
|
#if (MEM_CONSISTENCY_RELEASE || MEM_CONSISTENCY_WEAK)
|
|
extern long leaf_element() ;
|
|
#define LEAF_ELEMENT(e) (leaf_element((e)))
|
|
#endif
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* Interaction
|
|
*
|
|
*************************************************************************/
|
|
|
|
typedef struct _interact {
|
|
struct _interact *next ; /* Next entry of the list */
|
|
Element *destination ; /* Partner of the interaction */
|
|
float formfactor_out ; /* Form factor from this patch */
|
|
float formfactor_err ; /* Error of FF */
|
|
float area_ratio ; /* Area(this) / Area(dest) */
|
|
float visibility ; /* Visibility (0 - 1.0) */
|
|
} Interaction ;
|
|
|
|
|
|
void foreach_patch_in_bsp(void (*func)(), long arg1, long process_id);
|
|
void foreach_depth_sorted_patch(Vertex *sort_vec, void (*func)(), long arg1, long process_id);
|
|
void define_patch(Patch *patch, Patch *root, long process_id);
|
|
void split_patch(Patch *patch, Patch *node, long xing_code, long process_id);
|
|
void attach_element(Patch *patch, long process_id);
|
|
void refine_newpatch(Patch *patch, long newpatch, long process_id);
|
|
Patch *get_patch(long process_id);
|
|
void init_patchlist(long process_id);
|
|
void print_patch(Patch *patch, long process_id);
|
|
void print_bsp_tree(long process_id);
|
|
void _pr_patch(Patch *patch, long dummy, long process_id);
|
|
float plane_equ(PlaneEqu *plane, Vertex *point, long process_id);
|
|
float comp_plane_equ(PlaneEqu *pln, Vertex *p1, Vertex *p2, Vertex *p3, long process_id);
|
|
long point_intersection(PlaneEqu *plane, Vertex *point, long process_id);
|
|
long patch_intersection(PlaneEqu *plane, Vertex *p1, Vertex *p2, Vertex *p3, long process_id);
|
|
void print_plane_equ(PlaneEqu *peq, long process_id);
|
|
|
|
#endif
|