/*------------------------------------------------------------------------*/ GRAPH* build_graph_u(VINDEX vertex_size, EINDEX edge_size, MEM_POOL* m) { GRAPH *g; int i; GR_ASSERT(vertex_size >= 0, "build_graph_u vertex_size < 0\n"); GR_ASSERT(edge_size >= 0, "build_graph_u edge_size < 0\n"); g = (GRAPH*) MEM_POOL_Alloc(m, sizeof(GRAPH)); GR_ASSERT (g != 0, "build_graph_u g == 0\n"); memset(g, 0, sizeof(GRAPH)); if (vertex_size != 0) /* build the vertices */ { GRAPH_v(g) = (VERTEX*) MEM_POOL_Alloc(m, sizeof(VERTEX)*vertex_size); GR_ASSERT (GRAPH_v(g) != 0, "build_graph_u graph_v(g) == 0\n"); memset(GRAPH_v(g), 0, sizeof(VERTEX)*vertex_size); } if (edge_size != 0) /* build the edges */ { GRAPH_e(g) = (EDGE*) MEM_POOL_Alloc(m, sizeof(EDGE)*edge_size); GR_ASSERT (GRAPH_e(g) != 0, "build_graph_u graph_e(g) == 0\n"); memset(GRAPH_e(g), 0, sizeof(EDGE)*edge_size); } /*----------------------------set up the vertices-------------------------*/ GRAPH_vcnt(g) = 0; /* used vertices */ for (i = 0; i<vertex_size; ++i) { VERTEX_from(&GRAPH_v_i(g,i)) = i+1; /* set the linked list of free vertices */ VERTEX_fcnt(&GRAPH_v_i(g,i)) = -1; /* node is not being used */ } /* last free vertex points to no entry */ VERTEX_from(&GRAPH_v_i(g,vertex_size-1)) = INVALID_VINDEX; GRAPH_vfree(g) = 0; /* free vertices = total added vertices */ GRAPH_vmax(g) = vertex_size; /* max vertices = new maximum */ /*----------------------------set up the edges----------------------------*/ GRAPH_ecnt(g) = 0; /* used edges */ for (i = 0; i<edge_size; ++i) { EDGE_nfrom(&GRAPH_e_i(g,i)) = i+1; /* set the linked list of free edges */ EDGE_from(&GRAPH_e_i(g,i)) = INVALID_VINDEX; /* edge is not being used */ } /* last free edge points to no entry */ EDGE_nfrom(&GRAPH_e_i(g, edge_size-1)) = -1; GRAPH_efree(g) = 0; /* free edges */ GRAPH_emax(g) = edge_size; /* total edges */ GRAPH_root(g) = INVALID_VINDEX; /* no root */ GRAPH_m(g) = m; return g; }
/*----------------------------------------------------------------------*/ EINDEX add_edge(GRAPH *g, VINDEX from, VINDEX to, void *user) { EINDEX new_edge, e2; MEM_POOL *m = GRAPH_m(g); GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, from\n"); GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, to\n"); /* are there any free edges? */ if(GRAPH_efree(g) == -1) /* grow the edge list if no free edges */ grow_edge(g); /* get a free edge */ new_edge = GRAPH_efree(g); /* reset the free edge pointer */ GRAPH_efree(g)= EDGE_nfrom(&GRAPH_e_i(g,new_edge)); /* store the user information */ EDGE_user(&GRAPH_e_i(g,new_edge)) = user; /* from vertex is = from */ EDGE_from(&GRAPH_e_i(g,new_edge)) = from; /* to vertex is = to */ EDGE_to(&GRAPH_e_i(g,new_edge)) = to; /* incr. from count for from vertex */ VERTEX_fcnt(&GRAPH_v_i(g,from))++; /* incr. to count for to vertex */ VERTEX_tcnt(&GRAPH_v_i(g,to))++; /* incr. total used edge count */ GRAPH_ecnt(g)++; /* set up the list of from edges for the from vertex */ e2 = VERTEX_from(&GRAPH_v_i(g,from)); EDGE_nfrom(&GRAPH_e_i(g,new_edge)) = e2; VERTEX_from(&GRAPH_v_i(g,from)) = new_edge; /* set up the list of to edges for the to vertex */ e2 = VERTEX_to(&GRAPH_v_i(g,to)); EDGE_nto(&GRAPH_e_i(g,new_edge)) = e2; VERTEX_to(&GRAPH_v_i(g,to)) = new_edge; /* set the recursive edge field to be zero */ EDGE_etype(&GRAPH_e_i(g,new_edge)) = 0; return new_edge; }
/*---------------------------------------------------------------*/ void* get_edge_u(GRAPH *g, EINDEX e) { GR_ASSERT(is_edge(g, e), "get_edge_u is_edge\n"); return EDGE_user(&GRAPH_e_i(g,e)); }
/*---------------------------------------------------------------------*/ void* delete_vertex(GRAPH *g, VINDEX vertex) { void *user; EINDEX from, nfrom, to, nto; GR_ASSERT(is_vertex(g, vertex), "delete vertex is_vertex\n"); user = VERTEX_user(&GRAPH_v_i(g,vertex)); /* delete the from edges */ from = VERTEX_from(&GRAPH_v_i(g,vertex)); while (from != INVALID_EINDEX) { nfrom = EDGE_nfrom(&GRAPH_e_i(g,from)); delete_edge(g, from); from = nfrom; } /* delete the to edges */ to = VERTEX_to(&GRAPH_v_i(g,vertex)); while (to != INVALID_EINDEX) { nto = EDGE_nto(&GRAPH_e_i(g,to)); delete_edge(g, to); to = nto; } VERTEX_fcnt(&GRAPH_v_i(g,vertex)) = -1; VERTEX_from(&GRAPH_v_i(g,vertex)) = GRAPH_vfree(g); GRAPH_vfree(g) = vertex; GRAPH_vcnt(g)--; return user; }
/*------------------------------------------------------------------------*/ static void grow_edge(GRAPH *g) { EINDEX max, i, diff; MEM_POOL *m = GRAPH_m(g); if (GRAPH_emax(g) < 8) max = 16; else max = GRAPH_emax(g)*2; /* set max to double current size */ GR_ASSERT(max > GRAPH_emax(g), "grow_edge graph_emax >= max\n"); GRAPH_e(g) = (EDGE*) MEM_POOL_Realloc(m,GRAPH_e(g), sizeof(EDGE)*GRAPH_emax(g), sizeof(EDGE)*max); /* diff = max - GRAPH_emax(g); */ /* memset(&GRAPH_e_i(g,GRAPH_emax(g)), 0, sizeof(EDGE)*(diff)); */ for (i = GRAPH_emax(g); i<max; ++i) { EDGE_nfrom(&GRAPH_e_i(g,i)) = i+1; /* set the linked list of free edges */ EDGE_from(&GRAPH_e_i(g,i)) = INVALID_EINDEX; /* edge is not being used */ } /* last free vertex points to no entry */ EDGE_nfrom(&GRAPH_e_i(g, max-1)) = INVALID_EINDEX; GRAPH_efree(g) = GRAPH_emax(g); /* free edges = total added edges */ GRAPH_emax(g) = max; /* max edges = new maximum */ }
/*------------------------------------------------------------------------*/ static void grow_vertex(GRAPH *g) { VINDEX max, i; MEM_POOL *m = GRAPH_m(g); if (GRAPH_vmax(g) < 8) max = 16; else max = GRAPH_vmax(g)*2; /* set max to double current size */ GR_ASSERT(max > GRAPH_vmax(g), "grow_vertex max <= GRAPH_vmax(g)\n"); GRAPH_v(g) = (VERTEX*) MEM_POOL_Realloc(m,GRAPH_v(g),sizeof(VERTEX)*GRAPH_vmax(g), sizeof(VERTEX)*max); for (i = GRAPH_vmax(g); i<max; ++i) { VERTEX_from(&GRAPH_v_i(g,i)) = i+1; /* set the linked list of free vertices */ VERTEX_fcnt(&GRAPH_v_i(g,i)) = -1; /* node is not being used */ } /* last free vertex points to no entry */ VERTEX_from(&GRAPH_v_i(g,max-1)) = INVALID_VINDEX; GRAPH_vfree(g) = GRAPH_vmax(g); /* free vertices = total added vertices */ GRAPH_vmax(g) = max; /* max vertices = new maximum */ }
/*---------------------------------------------------------------*/ void* get_edge(GRAPH *g, VINDEX from, VINDEX to) { EINDEX e; GR_ASSERT(is_vertex(g, from), "get_edge is_vertex from\n"); GR_ASSERT(is_vertex(g, to), "get_edge is_vertex to\n"); e = VERTEX_from(&GRAPH_v_i(g, from)); while ( e != INVALID_EINDEX ) { if(EDGE_to(&GRAPH_e_i(g,e)) == to) break; e = (EDGE_nfrom(&GRAPH_e_i(g,e))); } return EDGE_user(&GRAPH_e_i(g,e)); }
/*---------------------------------------------------------------*/ int edge_count(GRAPH* g, VINDEX from, VINDEX to) { int count= 0; EINDEX e; GR_ASSERT(is_vertex(g, from), "edge_count is_vertex from\n"); GR_ASSERT(is_vertex(g, to), "edge_count is_vertex to\n"); e = VERTEX_from(&GRAPH_v_i(g, from)); while ( e != INVALID_EINDEX ) { if(EDGE_to(&GRAPH_e_i(g,e)) == to) ++count; e = (EDGE_nfrom(&GRAPH_e_i(g,e))); } return count; }
DFN * Depth_First_Ordering ( GRAPH *g, MEM_POOL* m ) { VINDEX vertex_count = GRAPH_vcnt(g); EINDEX edge_count = GRAPH_ecnt(g); int vertex_max = GRAPH_vmax(g); DFN *d; BOOL *visit; /* Validate and trace: */ GR_ASSERT ( GRAPH_root(g) != INVALID_VINDEX, "Invalid root g for graph\n"); printf ("Depth_First_Ordering: vertex count = %d \n", vertex_count ); /* Allocate the DFN struct: */ d = (DFN*) MEM_POOL_Alloc ( m, sizeof(DFN) ); GR_ASSERT(d != NULL, "Depth_First_Ordering: d" ); DFN_v_list(d) = (VINDEX *) MEM_POOL_Alloc ( m, sizeof(VINDEX) * vertex_count ); GR_ASSERT(DFN_v_list(d) != NULL, "Depth_First_Ordering: list" ); DFN_user(d) = (void *) MEM_POOL_Alloc ( m, sizeof(void *) * vertex_count ); GR_ASSERT(DFN_user(d) != NULL, "Depth_First_Ordering: user" ); /* Allocate work array to keep track of visited vertices: */ visit = (BOOL *) MEM_POOL_Alloc ( m, sizeof(BOOL)*vertex_max ); GR_ASSERT ( visit != NULL, "Depth_First_Ordering: visit" ); memset ( visit, 0, sizeof(BOOL)*vertex_max ); /* Initialize the DFN struct -- set end and first to point beyond * the first element: */ DFN_first(d) = DFN_end(d) = vertex_count; /* Go do the depth-first walk from the root: */ Search ( g, GRAPH_root(g), d, visit, INVALID_EINDEX ); /* Free work array: */ MEM_POOL_FREE(m, visit); return(d); }
/*-----------------------------------------------------------------------*/ VINDEX next_vertex(GRAPH *g, VINDEX vertex) { GR_ASSERT(is_vertex(g, vertex), "next_vertex is_vertex(g,vertex)\n"); while (1) { if (is_vertex(g, ++vertex)) return vertex; else if (vertex >= GRAPH_vmax(g)) return INVALID_VINDEX; } }
/*------------------------------------------------------------------------*/ GRAPH* build_graph(MEM_POOL* m) { GRAPH *g; g = (GRAPH*) MEM_POOL_Alloc(m, sizeof(GRAPH)); memset(g, 0, sizeof(GRAPH)); GR_ASSERT (g != 0, "build_graph g == 0\n"); GRAPH_vcnt(g) = 0; /* total vertices */ GRAPH_ecnt(g) = 0; /* total edges */ GRAPH_vfree(g) = -1; /* free vertices */ GRAPH_efree(g) = -1; /* free edges */ GRAPH_root(g) = INVALID_VINDEX; /* no root */ GRAPH_m(g) = m; return g; }
void Print_Pred(GRAPH *g, VINDEX v, void (*prn)()) { V_ITER *vi; VINDEX vtx; void * dummy = 0; int *u, total = 0; vi = create_vertex_iter(g, v, dummy); printf(" ["); for (vtx = first_v_preds(vi); vtx != INVALID_VINDEX; vtx = next_v_preds(vi)) { (*prn)(vtx); u = (int *)get_edge_u(g, V_ITER_c_e(vi)); GR_ASSERT(u, "user field in pred NULL"); printf("/%d ", *u); total += *u; } printf(" - total %d]", total); }
void _grDebugGroupWriteHeader(FxU32 header, FxU32 address) { #define FN_NAME "_grDebugGroupWriteHeader" GR_DCL_GC; FxU32 offset, /* laddress, * chipField, */ lheader = header; int index, nBits = 0; GR_ASSERT(address & GWH_ENABLE_BIT); GDBG_INFO((128, "New Group Write Packet ======================\n")); GDBG_INFO((128, "Address: 0x%x\n", address)); GDBG_INFO((128, "Header: 0x%x\n", header)); GDBG_INFO((128, "PCI Address: 0x%x\n", (address & 0xfffff) << 2)); GDBG_INFO((128, "Chip Field: 0x%x\n", (address >> 14) & 0xf)); offset = (address & ~(0xf << 14)) & 0xfffff; index = offset; if (offset < 0x100 ) { /* It's state or triangle */ GDBG_INFO((128, "Start: 0x%s (0x%x)\n", regNames[index], index)); GDBG_INFO((128, "Mask: 0x%x\n", header)); while (lheader) { if (lheader & 0x1) { nBits++; GDBG_INFO((128, "Includes:\t%s (0x%x)\n", regNames[index], index)); } lheader >>= 1; index++; } } else if (offset >= 0x10000) { /* It's texture */
/*---------------------------------------------------------------*/ int num_succs(GRAPH *g, VINDEX vertex) { GR_ASSERT(is_vertex(g,vertex), "num_succs is_vertex\n"); return (VERTEX_fcnt(&GRAPH_v_i(g,vertex))); }
/*---------------------------------------------------------------*/ void* get_vertex(GRAPH *g, VINDEX vertex) { GR_ASSERT(is_vertex(g,vertex), "get_vertex\n"); return (VERTEX_user(&GRAPH_v_i(g,vertex))); }
/*---------------------------------------------------------------------*/ void delete_edge(GRAPH *g, EINDEX edge) { VINDEX from_vertex, to_vertex; EINDEX next_edge, head_edge; GR_ASSERT(is_edge(g, edge), "delete_edge is_edge\n"); /* update the information for the from vertex */ /* get the from vertex */ from_vertex = EDGE_from(&GRAPH_e_i(g,edge)); /* decrement from count */ VERTEX_fcnt(&GRAPH_v_i(g,from_vertex))--; /* get the next edge in linked list */ next_edge = EDGE_nfrom(&GRAPH_e_i(g,edge)); /* get the first edge in linked list */ head_edge = VERTEX_from(&GRAPH_v_i(g,from_vertex)); /* if the head is set to edge */ if (head_edge == edge) /* set it to next from edge */ VERTEX_from(&GRAPH_v_i(g,from_vertex)) = next_edge; /* else walk the list of edges */ else { /* unlink the edge from listofedges */ while (EDGE_nfrom(&GRAPH_e_i(g,head_edge)) != edge) head_edge = EDGE_nfrom(&GRAPH_e_i(g,head_edge)); EDGE_nfrom(&GRAPH_e_i(g,head_edge)) = next_edge; } /*---- update the information for the to vertex ----*/ /* get the to vertex */ to_vertex = EDGE_to(&GRAPH_e_i(g,edge)); /* decrement to count */ VERTEX_tcnt(&GRAPH_v_i(g,to_vertex))--; /* get the next edge in linked list */ next_edge = EDGE_nto(&GRAPH_e_i(g,edge)); /* get the first edge in linked list */ head_edge = VERTEX_to(&GRAPH_v_i(g,to_vertex)); /* if head is set to edge */ if (head_edge == edge) /* set it to next to edge */ VERTEX_to(&GRAPH_v_i(g,to_vertex)) = next_edge; else /* else walk the list of edges */ { /* unlink the edge from the list of to edges */ while (g->e[head_edge].nto != edge) head_edge = EDGE_nto(&GRAPH_e_i(g,head_edge)); EDGE_nto(&GRAPH_e_i(g,head_edge)) = next_edge; } /* add the free edge to the linked list of free edges */ EDGE_nfrom(&GRAPH_e_i(g,edge)) = GRAPH_efree(g); EDGE_from(&GRAPH_e_i(g,edge)) = INVALID_VINDEX; GRAPH_efree(g) = edge; GRAPH_ecnt(g)--; /* decrement edge count */ }