/* * Copyright (C) 1997-2005, R3vis Corporation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA, or visit http://www.gnu.org/copyleft/lgpl.html. * * Original Contributor: * Wes Bethel, R3vis Corporation, Marin County, California * Additional Contributor(s): * * The OpenRM project is located at http://openrm.sourceforge.net/. */ /* * $Id: rmcr.c,v 1.12 2005/06/06 02:04:29 wes Exp $ * Version: $Name: OpenRM-1-6-0-RC5 $ * $Revision: 1.12 $ * $Log: rmcr.c,v $ * Revision 1.12 2005/06/06 02:04:29 wes * Lots of small additions to clean up compiler warnings. * * Revision 1.11 2005/05/16 01:00:51 wes * Minor code rearrangement to better accommodate RM_X and RM_CR compile * definitions (both might be used at once). * * Revision 1.10 2005/02/19 16:22:50 wes * Distro sync and consolidation. * * Revision 1.9 2005/01/23 17:00:22 wes * Copyright updated to 2005. * * Revision 1.8 2004/01/16 17:18:34 wes * Updated copyright line. Added more error testing to the Chromium-specific * RMpipe initialization sequence to help diagnose Chromium configuration * problems (there were a lot of questions related to CR config during * early field tests). * * Revision 1.7 2003/08/14 13:47:22 wes * Enclosed some debugging printf's inside conditional compilation directives. * * Revision 1.6 2003/07/27 15:37:37 wes * Fixed minor problems with in-line documentation. * * Revision 1.5 2003/04/05 13:58:52 wes * Remove dead code. * * Revision 1.4 2003/03/16 21:56:16 wes * Documentation updates. * * Revision 1.3 2003/02/18 15:40:40 wes * Added RMpipe wrapper functions for CR barrier creation and execution. * * Revision 1.2 2003/02/14 00:16:39 wes * Use of new CR-specific struct in the RMpipe, rather than a static struct. * * Revision 1.1.1.1 2003/01/28 02:15:23 wes * Manual rebuild of rm150 repository. * * Revision 1.7 2003/01/27 05:04:42 wes * Changes to RMpipe API and initialization sequence to unify GLX, WGL and CR * platforms w/o too much disruption to existing apps. * * Revision 1.6 2003/01/20 05:39:49 wes * Rewrote texture state handling code. * * Revision 1.5 2003/01/16 22:21:17 wes * Updated all source files to reflect new organization of header files: * all header files formerly located in include/rmaux, include/rmi, include/rmv * are now located in include/rm. * * Revision 1.4 2003/01/15 16:11:24 wes * Migrate setting of parms asking for shared display lists and texture objects * into the CR .conf files, rather than setting during RMpipe intialization. This * policy may change in the future. * * Revision 1.3 2003/01/14 05:28:57 wes * Added calls to CR extensions that enable shared display lists, * and texture object IDs. * * Revision 1.2 2003/01/09 16:58:59 wes * Removed c++'isms that lingered from a previous c++ version. These c++'isms * work OK in C sources in gcc 3.2, but not in earlier versions. * * Revision 1.1 2002/12/31 00:51:51 wes * Initial entry. * */ #include #include "rmprivat.h" #ifdef RM_CR #include #define CR_REASONABLE_MURALSIZE(a) (((a) > 0) && ((a) < 32768)) #endif /* * ---------------------------------------------------- * @Name rmPipeBarrierCreateCR @pstart RMenum rmPipeBarrierCreateCR (RMpipe *toModify, int barrierNumber) @pend @astart RMpipe *toModify - a handle to an RMpipe to be modified. int barrierNumber - an integer value specifying a barrier number. @aend @dstart (For use with Chromium only) Use this routine to create a named barrier. The barrier is executed by calling rmPipeBarrierExecCR(). Chromium barriers are intended to be used to synchronize execution of OpenGL streams on crservers. Chromium barriers, when created, require an integer value indicating the number of streams that will be participating in the barrier. This integer value is provided automatically by this routine. Use the routine rmPipeSetCommSize(), prior to calling rmPipeCreateBarrierCR(), to set the number of crservers that will be participating in execution of the barrier. Chromium barriers, when executed, synchronize execution of OpenGL code in the crservers. They do not block the application code. This routine returns RM_CHILL upon success. This routine will return RM_WHACKED if the input RMpipe is NULL, or if the size of the communication collective is zero (use rmPipeSetCommSize to set the size of the collective). This routine does not check for creation of duplicate barriers. @dend * ---------------------------------------------------- */ RMenum rmPipeBarrierCreateCR (RMpipe *toModify, int barrierNumber) { if (RM_ASSERT(toModify, "rmPipeBarrierCreateCR() error: the input RMpipe is NULL") == RM_WHACKED) return(RM_WHACKED); if (toModify->globalNPE == 0) { rmError("rmPipeBarrierCreateCR() error - the size of the communination collective is zero. Use rmPipeSetCommSize() to set a non-zero collective size prior to calling rmPipeBarrierCreateCR."); return RM_WHACKED; } #ifdef RM_CR toModify->crStuff->glBarrierCreateCR(barrierNumber, toModify->globalNPE); #else { barrierNumber++; /* foil compiler warning */ rmWarning("rmPipeBarrierCreateCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); } #endif return RM_CHILL; } /* * ---------------------------------------------------- * @Name rmPipeBarrierExecCR @pstart RMenum rmPipeBarrierExecCR (RMpipe *toUse, int barrierNumber) @pend @astart RMpipe *toUse - a handle to an RMpipe to be used. int barrierNumber - an integer value specifying a barrier number. @aend @dstart (For use with Chromium only) Use this routine to issue a "barrier execute" command to Chromium. Chromium barriers are intended to be used to synchronize execution of OpenGL streams on crservers. Chromium barriers, when created, require an integer value indicating the number of streams that will be participating in the barrier. This integer value is provided automatically by this routine. Use the routine rmPipeSetCommSize(), prior to calling rmPipeBarrierCreateCR(), to set the number of crservers that will be participating in execution of the barrier. Chromium barriers, when executed, synchronize execution of OpenGL code in the crservers. They do not block the application code. This routine returns RM_CHILL upon success, or RM_WHACKED if the input RMpipe is NULL. This routine does not check for creation of duplicate barriers. @dend * ---------------------------------------------------- */ RMenum rmPipeBarrierExecCR (RMpipe *toUse, int barrierNumber) { if (RM_ASSERT(toUse, "rmPipeBarrierExecCR() error: the input RMpipe is NULL") == RM_WHACKED) return(RM_WHACKED); #ifdef RM_CR toUse->crStuff->glBarrierExecCR(barrierNumber); #else barrierNumber++; /* foil compiler warning */ rmWarning("rmPipeBarrierExecCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif return RM_CHILL; } RMenum rmPipeSwapBuffersCR(const RMpipe *p) { #ifdef RM_CR int ival = (p->myRank == 0); /* only PE 0 does "real" swapbuffers */ #if (DEBUG_LEVEL & DEBUG_TRACE) fprintf(stderr," PE %d entering rmPipeSwapBuffersCR \n", p->myRank); fflush(stderr); #endif p->crStuff->glBarrierExecCR( RM_CR_PRE_SWAPBUFFERS_BARRIER ); if (ival == 1) p->crStuff->glSwapBuffersCR( 0, 0); else p->crStuff->glSwapBuffersCR( 0, CR_SUPPRESS_SWAP_BIT); p->crStuff->glBarrierExecCR( RM_CR_POST_SWAPBUFFERS_BARRIER ); #else p = NULL; /* foil compiler warnings */ rmWarning("rmPipeSwapBuffersCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif #if (DEBUG_LEVEL & DEBUG_TRACE) fprintf(stderr," PE %d leaving rmPipeSwapBuffersCR \n", p->myRank); fflush(stderr); #endif return RM_CHILL; } RMenum rmPipeCreateContextCR(RMpipe *pipe) { #ifdef RM_CR int ivisual = CR_RGB_BIT | CR_DEPTH_BIT | CR_DOUBLE_BIT ; int ictx; ictx = pipe->crStuff->glCreateContextCR(getenv("DISPLAY"), ivisual); if (ictx < 0) { rmError("rmPipeInitCR(), glCreateContextCR() call failed!\n"); return RM_WHACKED; } pipe->contextCR = ictx; #else pipe = NULL; /* foil compiler warning */ rmWarning("rmPipeCreateContextCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif return RM_CHILL; } RMenum rmPipeMakeCurrentCR(RMpipe *pipe) { RMenum stat = RM_TRUE; /* 5/1/05 - we note there really is no error checking in this routine */ #ifdef RM_CR int muralSize[2]; char buf[1024]; #if (DEBUG_LEVEL & DEBUG_TRACE) fprintf(stderr, "rmPipeMakeCurrentCR() - need to add code to honor stereo vs. not before context creation. get rid of viewport setting? \n"); fflush(stderr); #endif sprintf(buf,"CR_APPLICATION_ID_NUMBER=%d",pipe->myRank); putenv(buf); pipe->crStuff->glMakeCurrentCR(0, pipe->contextCR); pipe->crStuff->glGetChromiumParametervCR(GL_MURAL_SIZE_CR, 0, GL_INT, 2, muralSize ); /* deal with the case when there's no mothership */ if (muralSize[0] == 0 || muralSize[1] == 0) muralSize[0] = muralSize[1] = 256; fprintf(stderr,"rmPipeInitCR(): PE %d thinks the mural size is %d,%d \n", pipe->myRank, muralSize[0], muralSize[1]); fflush(stderr); if (CR_REASONABLE_MURALSIZE(muralSize[0]) && CR_REASONABLE_MURALSIZE(muralSize[1])) rmPipeSetWindowSize(pipe, muralSize[0], muralSize[1]); else { char buf[512]; sprintf(buf,"rmPipeInitCR(): PE %d: since the mural size is not reasonable, I'm setting the mural size to (256,256) because those are the values used by CR for a render spu with no mothership. \n", pipe->myRank); rmWarning(buf); rmPipeSetWindowSize(pipe, 256, 256); } { float vp[4] = {0., 0., 1., 1.}; rmNodeSetSceneViewport(rmRootNode(), vp); } /* Chromium-specific stuff: 1. create a barrier that will be called by all PEs prior to swapbuff. 2. create a barrier to sync up fbclears */ pipe->myRank = pipe->myRank; pipe->globalNPE = pipe->globalNPE; pipe->crStuff->glBarrierCreateCR(RM_CR_PRE_SWAPBUFFERS_BARRIER, pipe->globalNPE); pipe->crStuff->glBarrierCreateCR(RM_CR_POST_SWAPBUFFERS_BARRIER, pipe->globalNPE); pipe->crStuff->glBarrierCreateCR(RM_CR_POST_FBCLEAR_BARRIER, pipe->globalNPE); pipe->postFBClearBarrierFunc = private_rmPipePostFBClearBarrierCR; #else pipe = NULL; /* foil compiler warning */ rmWarning("rmPipeMakeCurrentCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif return(stat); } /* private */ void private_rmPipePostFBClearBarrierCR(const RMpipe *p) { #ifdef RM_CR p->crStuff->glBarrierExecCR(RM_CR_POST_FBCLEAR_BARRIER); #else p = NULL; /* foil compiler warnings */ rmWarning("private_rmPipePostFBClearBarrierCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif } /* private */ void private_rmPipeInitCR(RMpipe *p) { #ifdef RM_CR RMpipeCRvariables *lCR=NULL; lCR = (RMpipeCRvariables *)malloc(sizeof(RMpipeCRvariables)); p->crStuff = (void *)lCR; rmPipeSetSwapBuffersFunc(p, rmPipeSwapBuffersCR); lCR->glCreateContextCR = (crCreateContextProc)crGetProcAddress("crCreateContext"); lCR->glMakeCurrentCR = (crMakeCurrentProc)crGetProcAddress("crMakeCurrent"); lCR->glSwapBuffersCR = (crSwapBuffersProc)crGetProcAddress("crSwapBuffers"); lCR->glChromiumParametervCR = (glChromiumParametervCRProc)GET_PROC("glChromiumParametervCR"); lCR->glGetChromiumParametervCR = (glGetChromiumParametervCRProc) GET_PROC("glGetChromiumParametervCR"); lCR->glBarrierCreateCR = (glBarrierCreateCRProc)GET_PROC("glBarrierCreateCR"); lCR->glBarrierExecCR = (glBarrierExecCRProc)GET_PROC("glBarrierExecCR"); lCR->glChromiumParametervCR = (glChromiumParametervCRProc) GET_PROC("glChromiumParametervCR"); lCR->glChromiumParameteriCR = (glChromiumParameteriCRProc) GET_PROC("glChromiumParameteriCR"); /* * check to see if all the GET_PROC's succeeded. We cannot continue if * any of them failed. */ if ((lCR->glCreateContextCR == NULL) || (lCR->glMakeCurrentCR == NULL) || (lCR->glSwapBuffersCR == NULL) || (lCR->glChromiumParametervCR == NULL) || (lCR->glGetChromiumParametervCR == NULL) || (lCR->glBarrierCreateCR == NULL) || (lCR->glBarrierExecCR == NULL) || (lCR->glChromiumParametervCR == NULL) || (lCR->glChromiumParameteriCR == NULL)) { rmError("\n\n \ \tDuring intialization of a Chromium-enabled RMpipe, we encountered \n\ \tfatal error - some of the Chromium-specific routines loaded with \n\ \t'GET_PROC' could not be found. This condition most often happens \n\ \twhen you forget to have the symlinks in /usr/local/cr/lib/Linux \n\ \tthat point from libGL.so and libGL.so.1 to libcrfaker.so. The \n\ \tapplication fatally cripped, and will segfault in a short time. \n\n"); } #else p = NULL; /* foil compiler warning */ rmWarning("private_rmPipeInitCR() is effectively disabled. Build OpenRM/RM using the -DRM_CR compile flag to fully enable Chromium constructs."); #endif } /* private */ void private_rmPipeCloseContextCR (RMpipe *p) { p = NULL; /* foil compiler warning */ rmWarning("rmcr.c:private_rmPipeCloseContextCR() - need to write CR-specific context-closing routines. "); } /* EOF */