|
RwCameraVertex typedef for a structure describing a camera-space 3D vertex. |
|
RwImVertexIndex Typedef for a RenderWare Graphics Immediate Mode Vertex |
|
|
RxConfigMsgHandlerFn is the callback to be called, for the owning pipeline node, whenever a message is sent to it by the RxPipelineNodeConfigFn of another pipeline node in the same pipeline. See RxPipelineNodeSendConfigMsg.
|
|
RxLockedPipe typedef for a reference to a locked pipeline |
|
RxNodeBodyFn is the callback to be called during pipeline execution -- and, typically, process RxPacket's -- for the owning pipeline node.
|
|
RxNodeInitFn is the callback to be called, for the owning node definition, the first time an RxPipeline referencing that node definition is unlocked.
|
|
RxNodeInput typedef for a reference to the input of a pipeline node |
|
RxNodeOutput typedef for a reference to an output of a pipeline node |
|
RxNodeTermFn is the callback to be called, for the owning node definition, the last time an RxPipeline referencing that node definition is destroyed or locked.
|
|
RxObjSpace3DLitVertex Typedef for an RxObjSpace3DLitVertex structure |
|
RxObjSpace3DVertex Typedef for an RxObjSpace3DVertex structure |
|
RxPipelineNodeConfigFn is the callback to be called, for the owning pipeline node, whenever a RxPipeline containing that that pipeline node is unlocked, *after* all RxPipelineNodeInitFn's have been called for the pipeline in question. This func is to be used as described in RxPipelineNodeSendConfigMsg.
|
|
RxPipelineNodeInitFn is the callback to be called, for the owning pipeline node, whenever a RxPipeline containing that that pipeline node is unlocked.
|
|
RxPipelineNodeOutputCallBack is the callback function supplied to RxPipelineNodeForAllConnectedOutputs. The callback will be passed a pointer to the RxPipelineNode whose outputs are being traversed and a pointer to the current output RxPipelineNode, as well as a pointer to an optional user-defined data structure (callbackdata). If no such structure was specified, this will be NULL.
|
|
RxPipelineNodeTermFn is the callback to be called, for the owning pipeline node, whenever a RxPipeline containing that that pipeline node is locked or destroyed.
|
|
RxScrSpace2DVertex Typedef for an RxScrSpace2DVertex structure |
|
RxVertexIndex Typedef for a RenderWare Graphics PowerPipe Immediate Mode Vertex |
|
RwClipFlag Flags specifying the clipping status of a vertex
|
|
RxClusterForcePresent Flags specifying whether an RxCluster should be forced to be present in an RxPipelineNode |
|
RxClusterValid Flags specifying the state requirements for a RxCluster on exit from a node |
|
RxClusterValidityReq Flags specifying the state requirements for a RxCluster on entry to a node
|
|
RxGeometryFlag Flags describing geometry properties
|
|
RxNodeDefEditable Flags specifying whether an RxNodeDefinition is editable or not (RxPipelineNodeCloneDefinition, RxPipelineNodeReplaceCluster and RxPipelineNodeRequestCluster create editable copies of node definitions as the originals may be static definitions). |
|
RxRenderStateFlag Flags used in the RxRenderStateVector structure
|
|
RxClusterDecCursor decreases the cluster's data array cursor by the array's stride.
|
|
RxClusterDecCursorByStride decrements the cluster's data array cursor by "stride" bytes.
|
|
RxClusterDestroyData destroys a cluster's data array. In the same manner as the run-time library free() call, RxClusterDestroyData can be used to deallocate cluster data. A cluster should have some data to free on entering this function, naturally - if it is external data, it won't actually be freed, but the cluster's pointer to the data will be cleared, as will its flags.
|
|
RxClusterGetAttributes gets the attributes of a cluster. Each RxCluster in each RxPacket has an attributes field. RxClusterInitializeData initializes the attributes field to a creationAttributes value specific to the cluster and the pipeline in which creation occurs. Using RxClusterGetAttributes or RxClusterSetAttributes, this attributes value may be read and modified as the packet flows down the pipeline. Interpretation of the cluster attributes field is with reference to the cluster's attributeSet identifier. For example, PlayStation 2 specific pipelines tend to employ clusters with the attributeSet identifier "PS2"; given the attributeSet identifier "PS2", we know that the attribute values are constructed from the PlayStation 2 cluster attributes (CL_ATTRIB_OPAQUE, CL_V4_16, etc.). It is good practice for a node's pipelinenodeinit/pipelinenodeconfig methods to test a cluster's attributeSet identifier before reading or writing attribute values (e.g. RxPipelineClusterAssertAttributeSet(cl, RWSTRING("PS2"))).
|
|
RxClusterGetCursorData is a macro that returns a reference to the element of the cluster's data array pointed to by the data array cursor.
|
|
RxClusterGetFreeIndex returns an index one beyond the last used element in the cluster's data array. Additionally increments the numUsed member of the cluster. It is the responsibility of the user to test that the array is large enough to hold a new entry - i.e. that RxClusterGetFreeIndex(cl) is less than the cluster and greater than numAlloced - and to RxClusterResizeData as necessary.
|
|
RxClusterGetIndexedData returns a reference to the element of the cluster's data array specified by the given index.
|
|
RxClusterIncCursor increases the cluster's data array cursor by the array's stride.
|
|
RxClusterIncCursorByStride increments the cluster's data array cursor by "stride" bytes.
|
|
RxClusterInitializeData creates a cluster's data array. In the same manner as the run-time library alloc() call, RxClusterInitializeData can be used to allocate cluster data. However, it is probably best to think of this function's purpose as to "(re)initialize a cluster's data" - it sets the cluster's stride (values greater than zero are valid) and allocates data. If the cluster already has data then it will be freed. If you know that you do not need the old data then it is better to call this function rather than RxClusterResizeData, because the copy of the data that that function will do is entirely unnecessary and may be costly. Both the stride and number of elements specified must be greater than zero.
|
|
RxClusterLockRead locks a cluster for reading in an RxPacket. RxClusterLockRead will fail (indicated by a NULL return) if the packet does not contain the requested cluster. To ensure that this does not happen, the node's RxNodeDefinition should flag the cluster as required [rxCLREQ_REQUIRED or rxCLREQ_DONTWANT - the latter means that the cluster is required but any prior data it contains is not wanted]. Even if this is done, the cluster may not be present if no subsequent nodes in the pipeline require it and no prior nodes create it. The node can ensure that it definitely is there by specifying rxCLFORCEPRESENT for the forcePresent member of the cluster's RxClusterRef in the clustersOfInterest array in the RxNodeDefinition. This is important if the cluster is to be dispatched in the packet to another pipeline. It is possible for an rxCLREQ_REQUIRED cluster to be empty, and to guard against this nodes should test (cluster->numUsed > 0). rxCLREQ_OPTIONAL clusters may not be present and should always be tested for presence. Clusters locked for reading may not be resized, and modification of their data is not permitted. Note that this function is used for debug purposes only and, for efficiency, is available as a macro for final release versions of an application.
RwBool ProcessPacket(RxPacket *pk) { RxCluster *clObjVerts; // cluster we wish to LockRead() is identified by its index // within the node's RxNodeDefinition.io.clustersOfInterest array clObjVerts = RxClusterLockRead(pk, 3); if ( (clObjVerts != NULL ) && (clObjVerts->numUsed > 0)) { RwUInt32 n; for (n = 0; n < clObjVerts->numUsed; n++) // iterate over ObjVerts array { const RwObjSpace3DVertex *objVert = RxClusterGetCursorData(clObjVerts, const RwObjSpace3DVertex); ... // do something with objVert RxClusterIncCursor(clObjVerts); } RxClusterUnlock(clObjVerts); } }
|
|
RxClusterLockWrite locks a cluster for writing. Returns NULL if the packet does not contain the requested cluster. [The node's RxNodeDefinition record may list a cluster as rxCLVALID_VALID, but if dependency chasing identifies that no subsequent nodes have any interest in the cluster and no prior nodes create the cluster, it will be eliminated: packets will not make provision for the cluster, and it will not be possible to create it. To override this elimination behavior, set the RxClusterRef.forcePresent flag to rxCLFORCEPRESENT - see also RxClusterLockRead] Clusters locked for writing may have their data initialized, resized, destroyed or modified. This function sets the rxCLFLAGS_MODIFIED bit in the cluster's flags so that it can later be determined that the cluster's data has been edited. If RxClusterLockWrite is called on an external (by reference) cluster, "internalization" occurs - the cluster data is copied to permit modification, and the cluster becomes internal (dropping the reference altogether). It is this internal cluster that will subsequently be propagated. For a more detailed discussion of the internal/external distinction, see RxClusterSetExternalData or RxClusterSetData.
RwBool ProcessRenderState( RxPipelineNodeInstance *self, const RxPipelineNodeParam *params ) { RxPacket *packet; RxCluster *clRenderState; RxRenderStateVector *renderStateData; packet = (RxPacket *)RxPacketFetch( self ); RWASSERT( NULL != packet ); // cluster we wish to LockWrite() is identified by its index // within the node's RxNodeDefinition.io.clustersOfInterest array clRenderState = RxClusterLockWrite( packet, 1, self ); RWASSERT( clRenderState != NULL ); clRenderState = RxClusterInitializeData( clRenderState, 1, sizeof(RxRenderStateVector) ); RWASSERT( NULL != clRenderState ); renderStateData = RxClusterGetCursorData( clRenderState, RxRenderStateVector ); RWASSERT( NULL != renderStateData ); memset( renderStateData, 0, sizeof(RxRenderStateVector) ); // ... and any further changes to renderStateData RxClusterUnlock( clRenderState ); // ... }
|
|
RxClusterResetCursor resets the cluster's data array cursor, so that it points to the first element in the cluster's data array. A cursor reset is performed automatically by the API after RxClusterLockRead, RxClusterLockWrite, RxClusterInitializeData, RxClusterResizeData, RxClusterSetData and RxClusterSetExternalData.
|
|
RxClusterResizeData resizes a cluster's data array. In the same manner as the run-time library realloc() call, RxClusterResizeData can be used to reallocate cluster data. RxClusterDestroyData should be used to deallocate data, not this function. Equally, data should be initially allocated by RxClusterInitializeData, not this function. The number of elements specified must be greater than zero.
|
|
RxClusterSetAttributes sets the attributes of a cluster. Each RxCluster in each RxPacket has an attributes field. RxClusterInitializeData initializes the attributes field to a creationAttributes value specific to the cluster and the pipeline in which creation occurs. Using the RxClusterGetAttributes and RxClusterSetAttributes functions, this attributes value may be read and modified as the packet flows down the pipeline. Interpretation of the cluster attributes field is with reference to the cluster's attributeSet identifier. For example, PlayStation 2 specific pipelines tend to employ clusters with the attributeSet identifier "PS2"; given the attributeSet identifier "PS2", we know that the attribute values are constructed from the PlayStation 2 cluster attributes (CL_ATTRIB_OPAQUE, CL_V4_16, etc.). It is good practice for a node's pipelinenodeinit/pipelinenodeconfig methods to test a cluster's attributeSet identifier before reading or writing attribute values (e.g. RxPipelineClusterAssertAttributeSet(cl, RWSTRING("PS2"))).
|
|
RxClusterSetData sets a cluster's data to an existing data block. Clusters are the means by which packets convey data. A packet will usually contain a number of clusters, e.g. { RenderState, ObjVerts, Indices }. Clusters are classified as internal or external (to pipeline execution). Nodes treat internal or external clusters in exactly the same fashion; indeed, as a rule, nodes need not know whether a given cluster is internal or external. This function sets the data to INTERNAL. INTERNAL clusters: A cluster created by RxClusterInitializeData is internal - the cluster data is allocated from the pipeline execution heap, and the cluster may be resized and its data modified as the packet flows down the pipeline. When the containing packet is destroyed, or the cluster is terminated - because subsequent nodes have no interest in it, as identified by dependency chasing during RxLockedPipeUnlock - the cluster data is freed. EXTERNAL clusters: These are used to convey a reference to data external to the pipeline execution heap. Should a node attempt to modify (i.e. call RxClusterLockWrite) or resize (RxClusterResizeData) an external cluster, then the cluster will be transparently "internalized" (the referenced data will be copied into the pipeline execution heap, and the cluster will become internal). In the event of internalization, it is the copied data that is subsequently propagated. Note that this scheme makes it essential that you use RxClusterLockWrite for a cluster instead of RxClusterLockRead, if you are subsequently to edit the cluster's data. Non-array data is treated as a single element array; it is still necessary to correctly set the stride for non-array data.
|
|
RxClusterSetExternalData initializes a cluster as referencing external data. Clusters are the means by which packets convey data. A packet will usually contain a number of clusters, e.g. { RenderState, ObjVerts, Triangles }. Clusters are classified as internal or external (to pipeline execution). Nodes treat internal or external clusters in exactly the same fashion; indeed, as a rule, nodes need not know whether a given cluster is internal or external. This function sets the data to EXTERNAL. INTERNAL clusters: A cluster created by RxClusterInitializeData is internal - the cluster data is allocated from the pipeline execution heap, and the cluster may be resized and its data modified as the packet flows down the pipeline. When the containing packet is destroyed, or the cluster is terminated - because subsequent nodes have no interest in it, as identified by dependency chasing during RxLockedPipeUnlock - the cluster data is freed. EXTERNAL clusters: These are used to convey a reference to data external to the pipeline execution heap. Should a node attempt to modify (i.e. call RxClusterLockWrite) or resize (RxClusterResizeData) an external cluster, then the cluster will be transparently "internalized" (the referenced data will be copied into the pipeline execution heap, and the cluster will become internal). In the event of internalization, it is the copied data that is subsequently propagated. Note that this scheme makes it essential that you use RxClusterLockWrite for a cluster instead of RxClusterLockRead, if you are subsequently to edit the cluster's data. Note that in some cases it may be useful to flag cluster data that is allocated from the pipeline execution heap as external. Doing so will protect the original data array from modification by any subsequent nodes in the pipeline, which might be useful if the same array is to be used in multiple packets that a node creates. Non-array data is treated as a single element array; it is still necessary to correctly set the stride for non-array data.
|
|
RxClusterSetStride sets a cluster's stride (the increment in bytes from one element of the data array to the next). This function only stores the stride value; it does not reorganize the data array, nor does it resize it. It is common practice to follow RxClusterSetStride with an RxClusterResizeData. When creating a cluster, it is more natural to use the RxClusterInitializeData call, which sets the stride of, and allocates memory for, the data array.
|
|
RxClusterUnlock unlocks a cluster. Counterpart to RxClusterLockRead and RxClusterLockWrite ; call when the RxCluster is no longer required - when reading, writing or resizing is complete.
|
|
RxHeapAlloc allocates a block of memory from an RxHeap.
|
|
RxHeapCreate creates an RxHeap for dynamic memory management optimized for use during the execution of PowerPipe pipelines. See RxHeapGetGlobalHeap and RxPipelineExecute for details of current usage within PowerPipe. This heap structure is optimized for the following kind of process: blocks of memory are allocated, a minority of these blocks are freed or resized and at the end of the process, the entire set of remaining allocations can be freed with one call (to RxHeapReset). The RxHeap provides very quick allocations but does not do anything clever to deal with fragmentation within the heap. It operates as its fastest if it does not have to resort to reusing freed memory (i.e. if you can allocate all your blocks without filling the heap, then do so without freeing any blocks and merely call RxHeapReset at the end of the process). If the heap is filled and cannot service an allocation, it will automatically grow by the size passed to RxHeapCreate or the size of the allocation (whichever is the larger).
|
|
RxHeapDestroy destroys an RxHeap previously created by RxHeapCreate, freeing any outstanding memory allocations from that heap.
|
|
RxHeapFree returns a previously allocated block of memory to an RxHeap for reuse.
|
|
RxHeapGetGlobalHeap returns the global PowerPipe heap. The pipeline execution code maintains an execution heap that is tightly bound to the current invocation of RxPipelineExecute . This heap is used to rapidly service allocations for "transient" memory; such allocations are not preserved between pipeline executions - the heap is cleared down on exit from RxPipelineExecute, with a call to RxHeapReset. RxClusterInitializeData and RxClusterResizeData, for example, use the execution heap to allocate cluster memory. The returned heap of type RxHeap can be used in calls to RxHeapAlloc, RxHeapRealloc and RxHeapFree. During the execution of the node body method of a RxPipelineNode, the current heap - we may have multiple heaps eventually to execute more than one pipe simultaneously on multiprocessor systems - may be obtained through RxPipelineNodeParamGetHeap. Use of execution heap: { RxHeap *heap; int *intArray; heap = RxHeapGetGlobalHeap(); intArray = (int *) RxHeapAlloc(heap, 200 * sizeof(int)); intArray[199] = 3; RxHeapFree(heap, intArray); }
|
|
RxHeapRealloc resizes a previously allocated block of memory within an RxHeap, possibly moving the block. The allowCopy parameter determines whether, if the current block cannot be resized in-place, it should be copied to a new location or whether this should be treated as failure (in some cases, the caller may prefer to do something else if realloc'ing requires an expensive copy).
|
|
RxHeapReset resets an RxHeap, (quickly) marking all memory allocations from that heap as free.
|
|
RxLockedPipeAddFragment adds a fragment to a locked pipeline. A fragment is a chain of nodes, interconnected on their first (default) outputs. Constructing a pipeline is typically a process of adding a number of fragments (describing linear sections of the pipeline graph), and then adding additional paths between fragments using RxLockedPipeAddPath.
|
|
RxLockedPipeAddPath adds a path in the specified locked pipeline, between the given RxNodeOutput and the given RxNodeInput.
|
|
RxLockedPipeDeleteNode deletes the specified node from a locked pipeline. Paths into and out of the node are deleted.
|
|
RxLockedPipeDeletePath deletes a path in the specified locked pipeline, between the given RxNodeOutput and the given RxNodeInput.
|
|
RxLockedPipeGetEntryPoint gets the locked pipeline's entry point - that is, the pipeline node that forms the head of the pipeline graph, where pipeline processing will commence. After RxLockedPipeUnlock, the specified node will be the first node in the flattened node array.
|
|
RxLockedPipeReplaceNode replaces an existing pipeline node with a new pipeline node instanced from a specified node definition. Paths into and out of the node are retained to the greatest extent possible. Pipeline nodes can be located within pipelines using RxPipelineFindNodeByName or RxPipelineFindNodeByIndex.
|
|
RxLockedPipeSetEntryPoint sets a locked pipeline's entry point - that is, the index of node that forms the head of the pipeline graph, where pipeline processing will commence. After RxLockedPipeUnlock, the specified node will be the first node in the flattened node array.
|
|
RxLockedPipeUnlock unlocks a pipeline (switches, in effect, pipeline state from EDITABLE to EXECUTABLE). Pipeline unlocking is computationally intensive (see RxPipelineExecute), and can fail if it is determined that the requirements of all nodes cannot be met by the nodes feeding them.
|
|
RxPacketCreate creates an empty packet. This function will fail if there is insufficient memory on the pipeline execution heap or if a packet is already in existence (owing to the nested pipeline executed model, only one packet exists at a time, see RxPacketFetch for details). Data for all clusters in the created packet will be flagged invalid !(RxCluster.flags & rxCLFLAGS_CLUSTERVALID). Use RxClusterLockWrite then RxClusterInitializeData, RxClusterSetExternalData or RxClusterSetData to initialize clusters as required. This function is for use within node body methods.
|
|
RxPacketDestroy destroys a packet. Data for all valid clusters is also freed, excepting "external" [by reference] clusters. RxPacketCreate must be called in order to do further RxPacket processing in the current node.
{ RxPacket *pk; pk = RxPacketFetch(self); RWASSERT (NULL != pk); ... // process packet RxPacketDestroy(pk, self); return(TRUE); }
|
|
RxPacketDispatch dispatches an RxPacketFetch -ed or RxPacketCreate -ed packet to an output of the current node. RxPacketDispatch dispatches packets to one of the outputs of the current node [RxPacketDispatchToPipeline is used to dispatch packets to another pipeline]. If a packet is dispatched to an unconnected output, it will be destroyed. NOTE, however, that this happens anyway from the point of view of the calling node due to the nested nature of pipeline execution - when RxPacketDispatch is called, the packet is sent down the rest of the pipeline within this call and will have been destroyed [as described in RxPacketFetch] by the time the dispatch function returns (you can no longer operate on this packet, you will need to RxPacketCreate another). If the current node has not RxPacketCreate -ed or RxPacketFetch -ed a packet then it is valid to pass NULL as the packet parameter to this function (if a packet exists and you simply haven't checked, it will be passed on anyway). As noted in the documentation for RxPacketFetch, you should not RxPacketCreate or RxPacketFetch a packet unless you subsequently RxPacketDispatch, RxPacketDispatchToPipeline or RxPacketDestroy it.
{ RxPacket *pk; pk = RxPacketFetch(self); RWASSERT (NULL != pk); ... // process packet // dispatch packet to output 0 (default) RxPacketDispatch(pk, 0, self); return(TRUE); }
|
|
RxPacketDispatchToPipeline dispatches a RxPacketFetch -ed or RxPacketCreate -ed packet to an output of the current node. RxPacketDispatchToPipeline dispatches packets to another pipeline [RxPacketDispatch is used to dispatch packets to one of the outputs of the current node]. When RxPacketDispatchToPipeline is called, the packet is sent down the subsequent pipeline immediately due to the nested nature of pipeline execution - when RxPacketDispatchToPipeline is called, the packet is sent down the destination pipeline within this call and will have been destroyed [as described in RxPacketFetch] by the time the dispatch function returns (you can no longer operate on this packet, you will need to RxPacketCreate another). If the current node has not RxPacketCreate -ed or RxPacketFetch -ed a packet then it is valid to pass NULL as the packet parameter to this function (if a packet exists and you simply haven't checked, it will be passed on anyway). As noted in the documentation for RxPacketFetch, it is an error to RxPacketCreate or RxPacketFetch a packet and not to subsequently RxPacketDispatch, RxPacketDispatchToPipeline or RxPacketDestroy it. Note that this function is used for debug purposes only and, for efficiency, is available as a macro for final release versions of an application.
{ RxPacket *pk; pk = RxPacketFetch(self); RWASSERT (NULL != pk); ... // process packet // dispatch packet to output 0 (default) RxPacketDispatchToPipeline(pk, fancyPipeline, self); return(TRUE); }
|
|
RxPacketFetch fetches the current packet if there is one, returning a pointer to an RxPacket or NULL if there is no packet currently. The RxPacketFetch -ed packet should be RxPacketDispatchToPipeline -ed, RxPacketDispatch -ed or RxPacketDestroy -ed. If a node fails to do so, the packet will automatically be freed on exit of the node. Pipeline execution proceeds in a nested manner such that inside a dispatch, the RxPacket in fact proceeds along the rest of the pipeline and is destroyed explicitly by a node or automatically on dispatch to an unconnected node output or on exit of the terminal node. Hence, a dispatch is equivalent to calling RxPacketDestroy from the point of view of the current node - the packet can no longer be used within this node and another must be created. The convention is to give terminal nodes an output to which they dispatch, while recognizing that this output will usually remain unconnected - dispatch to an unconnected output causes the packet to be destroyed. RxPacketFetch should only be called once within a node, given the nested pipeline execution structure described above. RxPacketDispatch and RxPacketDispatchToPipeline are the only mechanisms to progress along a pipeline and they pass along at most one RxPacket.
{ RxPacket *pk; pk = RxPacketFetch(self); RWASSERT (NULL != pk); ... // process packet // dispatch packet to output 0 (default) RxPacketDispatch(pk, 0, self); return(TRUE); }
|
|
RxPipelineClone deep-copies an unlocked pipeline; the resultant copy may then form the basis for subsequent edits. Cloning a pipeline is non-trivial. This is because the nodes within a pipeline that was created in external code will have been set up by unknown API calls. Initialization data (see RxPipelineNodeCreateInitData) is used to 'remember' the effects of pipeline node setup API functions, such that a pipeline node's RxPipelineNodeInitFn may use it to perform automatic initialization of the node in a clone pipeline. The use of this function is no longer recommended. It may be removed from the library in subsequent versions.
|
|
RxPipelineClusterAssertAttributeSet provides a convenient debugging test that can be made if one plans to manipulate a cluster's attributes. See RxPipelineClusterSetCreationAttributes for further information.
|
|
RxPipelineClusterGetCreationAttributes gets creation attributes from a pipeline cluster. Each pipeline maintains a collection of RxPipelineCluster records, one for each cluster used by the pipeline. An RxPipelineCluster record holds a creationAttributes value - when a cluster is created in the pipeline (RxClusterInitializeData), the cluster's attributes field is initialized from RxPipelineCluster.creationAttributes. Nodes may subsequently modify the cluster's attributes as the packet flows down the pipe. Interpretation of the cluster attributes field is with reference to the cluster's attributeSet identifier. For example, PlayStation 2 specific pipelines tend to employ clusters with the attributeSet identifier "PS2"; given the attributeSet identifier "PS2", we know that the attribute values are constructed from the PlayStation 2 cluster attributes (CL_ATTRIB_OPAQUE, CL_V4_16, etc.). It is good practice for a node's pipelinenodeinit/pipelinenodeconfig methods to test a cluster's attributeSet identifier before reading or writing attribute values (e.g. RxPipelineClusterAssertAttributeSet(cl, RWSTRING("PS2"))).
|
|
RxPipelineClusterSetCreationAttributes sets creation attributes. Each pipeline maintains a collection of RxPipelineCluster records, one for each cluster used by the pipeline. An RxPipelineCluster record holds a creationAttributes value - when a cluster is created in the pipeline (RxClusterInitializeData), the cluster's attributes field is initialized from RxPipelineCluster.creationAttributes. nodes may subsequently modify the cluster's attributes as the packet flows down the pipe. Interpretation of the cluster attributes field is with reference to the cluster's attributeSet identifier. For example, PlayStation 2 specific pipelines tend to employ clusters with the attributeSet identifier "PS2"; given the attributeSet identifier "PS2", we know that the attribute values are constructed from the PlayStation 2 cluster attributes (CL_ATTRIB_OPAQUE, CL_V4_16, etc.). It is good practice for a node's pipelinenodeinit/pipelinenodeconfig methods to test a cluster's attributeSet identifier before reading or writing attribute values (e.g. RxPipelineClusterAssertAttributeSet(cl, RWSTRING("PS2"))).
|
|
RxPipelineCreate creates an RxPipeline. RxPipelineCreate may return NULL if there is insufficient memory. The following code creates a worldsector object pipeline containing the three library nodes WorldSectorInstance.csl, WorldSectorEnumerateLights.csl and MaterialScatter.csl. RxPipeline * CreateWorldSectorPipeline(void) { RxPipeline *pipe; RxLockedPipe *lpipe; pipe = RxPipelineCreate(); if ( pipe != NULL ) { lpipe = RxPipelineLock(pipe); if ( lpipe != NULL ) { if ( RxLockedPipeAddFragment(lpipe, NULL, RxNodeGetNodeWorldSectorInstance(), RxNodeGetNodeWorldSectorEnumerateLights(), RxNodeGetNodeMaterialScatter(), NULL) ) { if ( RxLockedPipeUnlock(lpipe) ) { return (pipe); // success } } } // fall through to here for cleanup if pipeline was // Create()d okay, but one of the construction calls // [Lock(), AddFragment(), Unlock()] has failed _rxPipelineDestroy(pipe); } return NULL; // failure }
|
|
RxPipelineDestroy destroys a RxPipeline, freeing all associated resources. Counterpart to RxPipelineCreate.
|
|
RxPipelineExecute executes a pipeline. The RxPipeline object describes a directed acylic graph of nodes, which must be in an unlocked state for execution [RxPipelineLock and RxLockedPipeUnlock calls bracket edits of the DAG; inside the RxLockedPipeUnlock call, analysis is made of data flow through the pipeline, which is then used to optimize RxPipelineExecute performance]. Execution begins at the head node of the pipeline, proceeding downwards through the flattened ("topologically sorted") pipeline. Parameter "data" is passed into each node. Typically, a node near the top of the pipeline will process the object referenced by this data pointer to generate one or more RxPacket's, which are then directed down the graph for further processing. RxPipelineNode's may invoke other pipelines by dispatching RxPacket s with the inter-DAG RxPacketDispatchToPipeline function rather than the RxPacketDispatch intra-DAG function [which outputs the RxPacket to the node connected to output "outputIndex"]. Pipeline execution proceeds in a nested manner such that inside a dispatch, the RxPacket in fact proceeds along the rest of the pipeline and is destroyed explicitly by a node or automatically on dispatch to an unconnected node output or on exit of the terminal node. Hence, a dispatch is equivalent to calling RxPacketDestroy from the point of view of the calling node - the packet can no longer be used within that node and another must be created. RxPacketDispatchToPipeline and RxPacketDispatch are the only means of causing subsequent nodes to execute (i.e pipeline execution to continue). Nodes executing within a pipeline should use the RxHeap structure (as detailed in RxHeapGetGlobalHeap and RxHeapCreate) to allocate "transient" memory, where "transient" means that the memory can safely be lost as soon as the pipeline execution terminates or sooner (the heap is cleared with a call to RxHeapReset before execution begins, unless the heapReset parameter to RxPipelineExecute is FALSE, as used by RwIm3DTransform for example). Allocations of cluster memory, for instance (through RxClusterInitializeData and RxClusterResizeData), use the pipeline execution heap. The heap attached to the current pipeline execution is accessible via the RxPipelineNodeParam parameter of pipeline node RxNodeBodyFn's, with the aid of RxPipelineNodeParamGetHeap. While there is currently one global heap, the system may in the future be extended to use different heaps for each pipeline execution, such that many pipelines could be executed simultaneously on multiprocessor systems. Early termination: the nested execution model descibed above means that terminating pipeline execution is achieved merely by not dispatching to a subsequent node or pipeline. However, there is no guarantee that nodes above the current node will not create and dispatch further packets. So, if a node returns FALSE (signifying an error) then pipeline execution will terminate as soon as all nodes above it can exit and no further dispatches will be allowed. If the pipeline (or any invoked pipelines) terminates with an error, RxPipelineExecute will return NULL.
if ( !RxPipelineExecute(defaultAtomicPipeline, (void *) atomic, TRUE) ) { // pipeline execution incurred an error }
|
|
RxPipelineFindNodeByIndex returns the node in a pipeline at index "nodeindex". Indices increment from zero with the first fragment through each subsequent pipeline node added. Neither pipeline node indices nor pipeline node pointers are valid across an RxLockedPipeUnlock, as this function causes the pipeline nodes to be re-ordered.
|
|
RxPipelineFindNodeByName finds the first PipelineNode in a given pipeline which has a given name specified in its RxNodeDefinition. If a non-NULL reference to a RxPipelineNode within the pipeline is passed in, the search starts immediately after that pipeline node. If a non-NULL reference to a RwInt32 index is passed in, it will be filled, on success, with the index of the pipeline node. On failure it will be filled with -1. Pipeline node pointers are not valid across an RxLockedPipeUnlock, as this function causes the nodes to be re-ordered.
|
|
RxPipelineInsertDebugNode inserts a 'debug' pipeline node inbetween two specified pipeline nodes. For all clusters active in either of the two specified pipeline nodes, the added pipeline node will have rxCLREQ_REQUIRED specified for them on input and rxCLVALID_VALID on output. Debug nodes are constructed to monitor traffic by "packet sniffing".
|
|
RxPipelineLock locks a pipeline (switches, in effect, pipeline state from EXECUTABLE to EDITABLE).
|
|
RxPipelineNodeCloneDefinition creates a private copy of the RxNodeDefinition of a given an RxPipelineNode, so that the definition can be modified. It optionally adds a new cluster_of_interest. The same cluster may not appear twice in a node's clusters_of_interest array, so it is an error to add a cluster that is already present. This function is generally used by nodes to assist in the provision of construction-time "customization" APIs.
|
|
RxPipelineNodeCreateInitData creates space for initialization data for a pipeline node. Initialization data can be supplied before a pipeline is unlocked, so that the pipeline node initialization function has some data to work with when it is called at unlock time. This function creates space for initialization data in a node and returns a pointer to that space so that the application can fill it. It creates the space locally so that it can safely be freed when the node is destroyed. If this function is called subsequently, any prior data will be freed. Initialization data was introduced to support RxPipelineClone. It is used to 'remember' the effects of pipeline node setup API functions, such that a pipeline node's RxPipelineNodeInitFn may use it to perform automatic initialization of the node in a clone pipeline. This function should be called before the containing pipeline is unlocked.
|
|
RxPipelineNodeFindInput returns a handle to the node's input, suitable for use with RxLockedPipeAddPath, etc.
|
|
RxPipelineNodeFindOutputByIndex searches through the node's outputs, as defined in its RxNodeDefinition, returning a handle to the requested output (requested with an index into the node's array of outputs, in the order defined in the node's RxNodeDefinition). This handle can be used with RxLockedPipeAddPath, etc.
|
|
RxPipelineNodeFindOutputByName searches through the node's outputs, as defined in its struct RxNodeDefinition, returning a handle to the requested output - requested with a string in the RxNodeDefinition . This handle can be used with RxLockedPipeAddPath, etc.
|
|
RxPipelineNodeForAllConnectedOutputs enumerates over the connected outputs of a node. Enumeration function. The callback is executed on every connected output of the specified node. The callback may return NULL to terminate enumeration, or a non-NULL value to continue. Expected use is in pipelinenodeconfig methods. Callback prototype: typedef RxPipelineNode * (*RxPipelineNodeOutputCallBack)(RxPipelineNode *node, RxPipelineNode *outputnode, void *callbackdata);
|
|
RxPipelineNodeGetInitData gets the initialization data pointer of a pipeline node. Initialization data may be supplied before a pipeline is unlocked, so that the pipeline node initialization function has some data to work with when it is called. When the pipeline node is destroyed (this occurs when its containing pipeline is destroyed or the node removed from it) or the data is replaced (this occurs whenever RxPipelineNodeCreateInitData is called), the data is freed.
|
|
RxPipelineNodeGetPipelineCluster gets a pipeline cluster from a pipeline node. Each pipeline maintains a collection of RxPipelineCluster records, one for each cluster used by the pipeline. An RxPipelineCluster record holds a creationAttributes value - when a cluster is created in the pipeline (RxClusterInitializeData), the cluster's attributes field is initialized from RxPipelineCluster.creationAttributes. RxPipelineNodeGetPipelineCluster is most commonly used in a node's pipelinenodeinit method, as a precursor to modifying a cluster's creationAttributes.
|
|
RxPipelineNodeParamGetData gets the data pointer which was passed in to RxPipelineExecute for the current pipeline execution.
|
|
RxPipelineNodeParamGetHeap gets the RxHeap in use by the current pipeline execution
|
|
RxPipelineNodeReplaceCluster replaces a cluster in a pipeline node during pipeline definition. This can be used in multipass pipelines, which use the same node several times and want to pass in a different cluster to each instance (a different set of RxUVs or a different RxMeshStateVector, for instance). This function can also be used when the node designer has no means of knowing what a cluster will be called (e.g. a node which simply copies the contents of 'a cluster' into memory somewhere - it reads stride at run-time and can potentially work on any cluster); a place-holder cluster (&clusterPlaceHolder) is then used, which is invariably replaced during pipeline definition. This function must be called prior to unlocking the containing pipeline.
|
|
RxPipelineNodeRequestCluster causes a node to request a cluster. When pipelines are unlocked, a requirements/data flow analysis is performed within the pipeline, which is intended to validate the pipeline and eliminate redundant effort. This analysis can not, of itself, factor in the requirements of any pipelines to which this pipeline might dispatch (such dispatches are dependent on the execution-time behavior of node body methods). For this reason, it is important that terminal nodes which dispatch to other pipelines require (in their RxNodeDefinition's ) the clusters that the destination pipelines will require. Without this, it might be determined that certain clusters are no longer required, and they may be terminated before packets reach the dispatching node. RxPipelineNodeRequestCluster causes the node to request a cluster. A copy of the node's RxNodeDefinition is made, and this is edited, so other RxPipelineNodes instanced from the same RxNodeDefinition are not impacted. The cluster is always requested as rxCLREQ_OPTIONAL because it is more flexible than rxCLREQ_REQUIRED. If this function is used and the cluster is not present, rxCLREQ_REQUIRED would cause dependency chasing to fail, whereas with rxCLREQ_OPTIONAL no harm is done. This function must be called prior to unlocking the containing pipeline.
|
|
RxPipelineNodeSendConfigMsg requests information on node requirements. In the final stages of pipeline Unlock()-ing, (i) the pipelinenodeinit method of each node in the pipeline is called [in bottom to top (consumer -> producer) order]; (ii) the pipelinenodeconfig method of each node is called, again in bottom to top order. It is expected that nodes will use the pipelinenodeinit method to initialize their private data. Once the pipelinenodeinit phase is complete, it is assumed that all nodes are initialized as necessary. Nodes may then use the pipelinenodeconfig method as an opportunity to communicate with other nodes in the pipeline and further ascertain requirements. A typical node's pipelinenodeconfig method might use RxPipelineNodeForAllConnectedOutputs (perhaps recursively) to identify the nodes to which it outputs, and then use RxPipelineNodeSendConfigMsg to request information on their requirements. Nodes receive messages via their configmsghandler method. The return value of RxPipelineNodeSendConfigMsg is the node's response, or zero if the message is unserviced. No default msg values are currently defined. The use of this function (and the related callback types, RxPipelineNodeConfigFn and RxConfigMsgHandlerFn) is no longer recommended. It may be removed from the library in subsequent versions.
|
|
RxPipelineSetFreeListCreateParams allows the developer to specify how many RxPipeline s to preallocate space for. Call before RwEngineInit.
|
|
RxRenderStateVectorCreate returns a RxRenderStateVector set to the default or current state. The returned vector can be set to the current driver state or the default render state depending on the value of the 'current' parameter. This function should not be called before RwEngineStart() has been called.
|
|
RxRenderStateVectorDestroy destroys a RxRenderStateVector
|
|
RxRenderStateVectorGetDefaultRenderStateVector returns a CONST pointer to the global default RxRenderStateVector. This function should not be called before RwEngineStart() has been called.
|
|
RxRenderStateVectorLoadDriverState sets a RxRenderStateVector to the current driver render state. This function should not be called before RwEngineInit() has been called.
|
|
RxRenderStateVectorSetDefaultRenderStateVector sets a RxRenderStateVector to the default state. This function should not be called before RwEngineStart() has been called.
|
Converted from CHM to HTML with chm2web Pro 2.85 (unicode) |