aboutsummaryrefslogtreecommitdiff
path: root/mp/src/utils/vrad/mpivrad.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/utils/vrad/mpivrad.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/utils/vrad/mpivrad.cpp')
-rw-r--r--mp/src/utils/vrad/mpivrad.cpp992
1 files changed, 496 insertions, 496 deletions
diff --git a/mp/src/utils/vrad/mpivrad.cpp b/mp/src/utils/vrad/mpivrad.cpp
index d54dfaeb..5b7bfc03 100644
--- a/mp/src/utils/vrad/mpivrad.cpp
+++ b/mp/src/utils/vrad/mpivrad.cpp
@@ -1,496 +1,496 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-//
-// mpivrad.cpp
-//
-
-#include <windows.h>
-#include <conio.h>
-#include "vrad.h"
-#include "physdll.h"
-#include "lightmap.h"
-#include "tier1/strtools.h"
-#include "radial.h"
-#include "utlbuffer.h"
-#include "pacifier.h"
-#include "messbuf.h"
-#include "bsplib.h"
-#include "consolewnd.h"
-#include "vismat.h"
-#include "vmpi_filesystem.h"
-#include "vmpi_dispatch.h"
-#include "utllinkedlist.h"
-#include "vmpi.h"
-#include "mpi_stats.h"
-#include "vmpi_distribute_work.h"
-#include "vmpi_tools_shared.h"
-
-
-
-
-CUtlVector<char> g_LightResultsFilename;
-
-
-extern int total_transfer;
-extern int max_transfer;
-
-extern void BuildVisLeafs(int);
-extern void BuildPatchLights( int facenum );
-
-
-// Handle VRAD packets.
-bool VRAD_DispatchFn( MessageBuffer *pBuf, int iSource, int iPacketID )
-{
- switch( pBuf->data[1] )
- {
- case VMPI_SUBPACKETID_PLIGHTDATA_RESULTS:
- {
- const char *pFilename = &pBuf->data[2];
- g_LightResultsFilename.CopyArray( pFilename, strlen( pFilename ) + 1 );
- return true;
- }
-
- default:
- return false;
- }
-}
-CDispatchReg g_VRADDispatchReg( VMPI_VRAD_PACKET_ID, VRAD_DispatchFn ); // register to handle the messages we want
-CDispatchReg g_DistributeWorkReg( VMPI_DISTRIBUTEWORK_PACKETID, DistributeWorkDispatch );
-
-
-
-void VRAD_SetupMPI( int &argc, char **&argv )
-{
- CmdLib_AtCleanup( VMPI_Stats_Term );
-
- //
- // Preliminary check -mpi flag
- //
- if ( !VMPI_FindArg( argc, argv, "-mpi", "" ) && !VMPI_FindArg( argc, argv, VMPI_GetParamString( mpi_Worker ), "" ) )
- return;
-
- // Force local mode?
- VMPIRunMode mode;
- if ( VMPI_FindArg( argc, argv, VMPI_GetParamString( mpi_Local ), "" ) )
- mode = VMPI_RUN_LOCAL;
- else
- mode = VMPI_RUN_NETWORKED;
-
- VMPI_Stats_InstallSpewHook();
-
- //
- // Extract mpi specific arguments
- //
- Msg( "Initializing VMPI...\n" );
- if ( !VMPI_Init(
- argc,
- argv,
- "dependency_info_vrad.txt",
- HandleMPIDisconnect,
- mode
- ) )
- {
- Error( "MPI_Init failed." );
- }
-
- StatsDB_InitStatsDatabase( argc, argv, "dbinfo_vrad.txt" );
-}
-
-
-//-----------------------------------------
-//
-// Run BuildFaceLights across all available processing nodes
-// and collect the results.
-//
-
-CCycleCount g_CPUTime;
-
-
-template<class T> void WriteValues( MessageBuffer *pmb, T const *pSrc, int nNumValues)
-{
- pmb->write(pSrc, sizeof( pSrc[0]) * nNumValues );
-}
-
-template<class T> int ReadValues( MessageBuffer *pmb, T *pDest, int nNumValues)
-{
- return pmb->read( pDest, sizeof( pDest[0]) * nNumValues );
-}
-
-
-//--------------------------------------------------
-// Serialize face data
-void SerializeFace( MessageBuffer * pmb, int facenum )
-{
- int i, n;
-
- dface_t * f = &g_pFaces[facenum];
- facelight_t * fl = &facelight[facenum];
-
- pmb->write(f, sizeof(dface_t));
- pmb->write(fl, sizeof(facelight_t));
-
- WriteValues( pmb, fl->sample, fl->numsamples);
-
- //
- // Write the light information
- //
- for (i=0; i<MAXLIGHTMAPS; ++i) {
- for (n=0; n<NUM_BUMP_VECTS+1; ++n) {
- if (fl->light[i][n])
- {
- WriteValues( pmb, fl->light[i][n], fl->numsamples);
- }
- }
- }
-
- if (fl->luxel)
- WriteValues( pmb, fl->luxel, fl->numluxels);
-
- if (fl->luxelNormals)
- WriteValues( pmb, fl->luxelNormals, fl->numluxels);
-}
-
-//--------------------------------------------------
-// UnSerialize face data
-//
-void UnSerializeFace( MessageBuffer * pmb, int facenum, int iSource )
-{
- int i, n;
-
- dface_t * f = &g_pFaces[facenum];
- facelight_t * fl = &facelight[facenum];
-
- if (pmb->read(f, sizeof(dface_t)) < 0)
- Error("UnSerializeFace - invalid dface_t from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
-
- if (pmb->read(fl, sizeof(facelight_t)) < 0)
- Error("UnSerializeFace - invalid facelight_t from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
-
- fl->sample = (sample_t *) calloc(fl->numsamples, sizeof(sample_t));
- if (pmb->read(fl->sample, sizeof(sample_t) * fl->numsamples) < 0)
- Error("UnSerializeFace - invalid sample_t from %s (mb len: %d, offset: %d, fl->numsamples: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset(), fl->numsamples );
-
- //
- // Read the light information
- //
- for (i=0; i<MAXLIGHTMAPS; ++i) {
- for (n=0; n<NUM_BUMP_VECTS+1; ++n) {
- if (fl->light[i][n])
- {
- fl->light[i][n] = (LightingValue_t *) calloc( fl->numsamples, sizeof(LightingValue_t ) );
- if ( ReadValues( pmb, fl->light[i][n], fl->numsamples) < 0)
- Error("UnSerializeFace - invalid fl->light from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
- }
- }
- }
-
- if (fl->luxel) {
- fl->luxel = (Vector *) calloc(fl->numluxels, sizeof(Vector));
- if (ReadValues( pmb, fl->luxel, fl->numluxels) < 0)
- Error("UnSerializeFace - invalid fl->luxel from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
- }
-
- if (fl->luxelNormals) {
- fl->luxelNormals = (Vector *) calloc(fl->numluxels, sizeof( Vector ));
- if ( ReadValues( pmb, fl->luxelNormals, fl->numluxels) < 0)
- Error("UnSerializeFace - invalid fl->luxelNormals from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
- }
-
-}
-
-
-void MPI_ReceiveFaceResults( uint64 iWorkUnit, MessageBuffer *pBuf, int iWorker )
-{
- UnSerializeFace( pBuf, iWorkUnit, iWorker );
-}
-
-
-void MPI_ProcessFaces( int iThread, uint64 iWorkUnit, MessageBuffer *pBuf )
-{
- // Do BuildFacelights on the face.
- CTimeAdder adder( &g_CPUTime );
-
- BuildFacelights( iThread, iWorkUnit );
-
- // Send the results.
- if ( pBuf )
- {
- SerializeFace( pBuf, iWorkUnit );
- }
-}
-
-
-void RunMPIBuildFacelights()
-{
- g_CPUTime.Init();
-
- Msg( "%-20s ", "BuildFaceLights:" );
- if ( g_bMPIMaster )
- {
- StartPacifier("");
- }
-
- VMPI_SetCurrentStage( "RunMPIBuildFaceLights" );
- double elapsed = DistributeWork(
- numfaces,
- VMPI_DISTRIBUTEWORK_PACKETID,
- MPI_ProcessFaces,
- MPI_ReceiveFaceResults );
-
- if ( g_bMPIMaster )
- {
- EndPacifier(false);
- Msg( " (%d)\n", (int)elapsed );
- }
-
- if ( g_bMPIMaster )
- {
- //
- // BuildPatchLights is normally called from BuildFacelights(),
- // but in MPI mode we have the master do the calculation
- // We might be able to speed this up by doing while the master
- // is idling in the above loop. Wouldn't want to slow down the
- // handing out of work - maybe another thread?
- //
- for ( int i=0; i < numfaces; ++i )
- {
- BuildPatchLights(i);
- }
- }
- else
- {
- if ( g_iVMPIVerboseLevel >= 1 )
- Msg( "\n\n%.1f%% CPU utilization during BuildFaceLights\n\n", ( g_CPUTime.GetSeconds() * 100 / elapsed ) );
- }
-}
-
-
-//-----------------------------------------
-//
-// Run BuildVisLeafs across all available processing nodes
-// and collect the results.
-//
-
-// This function is called when the master receives results back from a worker.
-void MPI_ReceiveVisLeafsResults( uint64 iWorkUnit, MessageBuffer *pBuf, int iWorker )
-{
- int patchesInCluster = 0;
-
- pBuf->read(&patchesInCluster, sizeof(patchesInCluster));
-
- for ( int k=0; k < patchesInCluster; ++k )
- {
- int patchnum = 0;
- pBuf->read(&patchnum, sizeof(patchnum));
-
- CPatch * patch = &g_Patches[patchnum];
- int numtransfers;
- pBuf->read( &numtransfers, sizeof(numtransfers) );
- patch->numtransfers = numtransfers;
- if (numtransfers)
- {
- patch->transfers = new transfer_t[numtransfers];
- pBuf->read(patch->transfers, numtransfers * sizeof(transfer_t));
- }
-
- total_transfer += numtransfers;
- if (max_transfer < numtransfers)
- max_transfer = numtransfers;
- }
-}
-
-
-// Temporary variables used during callbacks. If we're going to be threadsafe, these
-// should go in a structure and get passed around.
-class CVMPIVisLeafsData
-{
-public:
- MessageBuffer *m_pVisLeafsMB;
- int m_nPatchesInCluster;
- transfer_t *m_pBuildVisLeafsTransfers;
-};
-
-CVMPIVisLeafsData g_VMPIVisLeafsData[MAX_TOOL_THREADS+1];
-
-
-
-// This is called by BuildVisLeafs_Cluster every time it finishes a patch.
-// The results are appended to g_VisLeafsMB and sent back to the master when all clusters are done.
-void MPI_AddPatchData( int iThread, int patchnum, CPatch *patch )
-{
- CVMPIVisLeafsData *pData = &g_VMPIVisLeafsData[iThread];
- if ( pData->m_pVisLeafsMB )
- {
- // Add in results for this patch
- ++pData->m_nPatchesInCluster;
- pData->m_pVisLeafsMB->write(&patchnum, sizeof(patchnum));
- pData->m_pVisLeafsMB->write(&patch->numtransfers, sizeof(patch->numtransfers));
- pData->m_pVisLeafsMB->write( patch->transfers, patch->numtransfers * sizeof(transfer_t) );
- }
-}
-
-
-// This handles a work unit sent by the master. Each work unit here is a
-// list of clusters.
-void MPI_ProcessVisLeafs( int iThread, uint64 iWorkUnit, MessageBuffer *pBuf )
-{
- CTimeAdder adder( &g_CPUTime );
-
- CVMPIVisLeafsData *pData = &g_VMPIVisLeafsData[iThread];
- int iCluster = iWorkUnit;
-
- // Start this cluster.
- pData->m_nPatchesInCluster = 0;
- pData->m_pVisLeafsMB = pBuf;
-
- // Write a temp value in there. We overwrite it later.
- int iSavePos = 0;
- if ( pBuf )
- {
- iSavePos = pBuf->getLen();
- pBuf->write( &pData->m_nPatchesInCluster, sizeof(pData->m_nPatchesInCluster) );
- }
-
- // Collect the results in MPI_AddPatchData.
- BuildVisLeafs_Cluster( iThread, pData->m_pBuildVisLeafsTransfers, iCluster, MPI_AddPatchData );
-
- // Now send the results back..
- if ( pBuf )
- {
- pBuf->update( iSavePos, &pData->m_nPatchesInCluster, sizeof(pData->m_nPatchesInCluster) );
- pData->m_pVisLeafsMB = NULL;
- }
-}
-
-
-void RunMPIBuildVisLeafs()
-{
- g_CPUTime.Init();
-
- Msg( "%-20s ", "BuildVisLeafs :" );
- if ( g_bMPIMaster )
- {
- StartPacifier("");
- }
-
- memset( g_VMPIVisLeafsData, 0, sizeof( g_VMPIVisLeafsData ) );
- if ( !g_bMPIMaster || VMPI_GetActiveWorkUnitDistributor() == k_eWorkUnitDistributor_SDK )
- {
- // Allocate space for the transfers for each thread.
- for ( int i=0; i < numthreads; i++ )
- {
- g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers = BuildVisLeafs_Start();
- }
- }
-
- //
- // Slaves ask for work via GetMPIBuildVisLeafWork()
- // Results are returned in BuildVisRow()
- //
- VMPI_SetCurrentStage( "RunMPIBuildVisLeafs" );
-
- double elapsed = DistributeWork(
- dvis->numclusters,
- VMPI_DISTRIBUTEWORK_PACKETID,
- MPI_ProcessVisLeafs,
- MPI_ReceiveVisLeafsResults );
-
- // Free the transfers from each thread.
- for ( int i=0; i < numthreads; i++ )
- {
- if ( g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers )
- BuildVisLeafs_End( g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers );
- }
-
- if ( g_bMPIMaster )
- {
- EndPacifier(false);
- Msg( " (%d)\n", (int)elapsed );
- }
- else
- {
- if ( g_iVMPIVerboseLevel >= 1 )
- Msg( "%.1f%% CPU utilization during PortalFlow\n", (g_CPUTime.GetSeconds() * 100.0f / elapsed) / numthreads );
- }
-}
-
-void VMPI_DistributeLightData()
-{
- if ( !g_bUseMPI )
- return;
-
- if ( g_bMPIMaster )
- {
- const char *pVirtualFilename = "--plightdata--";
-
- CUtlBuffer lightFaceData;
-
- // write out the light data
- lightFaceData.EnsureCapacity( pdlightdata->Count() + (numfaces * (MAXLIGHTMAPS+sizeof(int))) );
- Q_memcpy( lightFaceData.PeekPut(), pdlightdata->Base(), pdlightdata->Count() );
- lightFaceData.SeekPut( CUtlBuffer::SEEK_HEAD, pdlightdata->Count() );
-
- // write out the relevant face info into the stream
- for ( int i = 0; i < numfaces; i++ )
- {
- for ( int j = 0; j < MAXLIGHTMAPS; j++ )
- {
- lightFaceData.PutChar(g_pFaces[i].styles[j]);
- }
- lightFaceData.PutInt(g_pFaces[i].lightofs);
- }
- VMPI_FileSystem_CreateVirtualFile( pVirtualFilename, lightFaceData.Base(), lightFaceData.TellMaxPut() );
-
- char cPacketID[2] = { VMPI_VRAD_PACKET_ID, VMPI_SUBPACKETID_PLIGHTDATA_RESULTS };
- VMPI_Send2Chunks( cPacketID, sizeof( cPacketID ), pVirtualFilename, strlen( pVirtualFilename ) + 1, VMPI_PERSISTENT );
- }
- else
- {
- VMPI_SetCurrentStage( "VMPI_DistributeLightData" );
-
- // Wait until we've received the filename from the master.
- while ( g_LightResultsFilename.Count() == 0 )
- {
- VMPI_DispatchNextMessage();
- }
-
- // Open
- FileHandle_t fp = g_pFileSystem->Open( g_LightResultsFilename.Base(), "rb", VMPI_VIRTUAL_FILES_PATH_ID );
- if ( !fp )
- Error( "Can't open '%s' to read lighting info.", g_LightResultsFilename.Base() );
-
- int size = g_pFileSystem->Size( fp );
- int faceSize = (numfaces*(MAXLIGHTMAPS+sizeof(int)));
-
- if ( size > faceSize )
- {
- int lightSize = size - faceSize;
- CUtlBuffer faceData;
- pdlightdata->EnsureCount( lightSize );
- faceData.EnsureCapacity( faceSize );
-
- g_pFileSystem->Read( pdlightdata->Base(), lightSize, fp );
- g_pFileSystem->Read( faceData.Base(), faceSize, fp );
- g_pFileSystem->Close( fp );
-
- faceData.SeekPut( CUtlBuffer::SEEK_HEAD, faceSize );
-
- // write out the face data
- for ( int i = 0; i < numfaces; i++ )
- {
- for ( int j = 0; j < MAXLIGHTMAPS; j++ )
- {
- g_pFaces[i].styles[j] = faceData.GetChar();
- }
- g_pFaces[i].lightofs = faceData.GetInt();
- }
- }
- }
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+//
+// mpivrad.cpp
+//
+
+#include <windows.h>
+#include <conio.h>
+#include "vrad.h"
+#include "physdll.h"
+#include "lightmap.h"
+#include "tier1/strtools.h"
+#include "radial.h"
+#include "utlbuffer.h"
+#include "pacifier.h"
+#include "messbuf.h"
+#include "bsplib.h"
+#include "consolewnd.h"
+#include "vismat.h"
+#include "vmpi_filesystem.h"
+#include "vmpi_dispatch.h"
+#include "utllinkedlist.h"
+#include "vmpi.h"
+#include "mpi_stats.h"
+#include "vmpi_distribute_work.h"
+#include "vmpi_tools_shared.h"
+
+
+
+
+CUtlVector<char> g_LightResultsFilename;
+
+
+extern int total_transfer;
+extern int max_transfer;
+
+extern void BuildVisLeafs(int);
+extern void BuildPatchLights( int facenum );
+
+
+// Handle VRAD packets.
+bool VRAD_DispatchFn( MessageBuffer *pBuf, int iSource, int iPacketID )
+{
+ switch( pBuf->data[1] )
+ {
+ case VMPI_SUBPACKETID_PLIGHTDATA_RESULTS:
+ {
+ const char *pFilename = &pBuf->data[2];
+ g_LightResultsFilename.CopyArray( pFilename, strlen( pFilename ) + 1 );
+ return true;
+ }
+
+ default:
+ return false;
+ }
+}
+CDispatchReg g_VRADDispatchReg( VMPI_VRAD_PACKET_ID, VRAD_DispatchFn ); // register to handle the messages we want
+CDispatchReg g_DistributeWorkReg( VMPI_DISTRIBUTEWORK_PACKETID, DistributeWorkDispatch );
+
+
+
+void VRAD_SetupMPI( int &argc, char **&argv )
+{
+ CmdLib_AtCleanup( VMPI_Stats_Term );
+
+ //
+ // Preliminary check -mpi flag
+ //
+ if ( !VMPI_FindArg( argc, argv, "-mpi", "" ) && !VMPI_FindArg( argc, argv, VMPI_GetParamString( mpi_Worker ), "" ) )
+ return;
+
+ // Force local mode?
+ VMPIRunMode mode;
+ if ( VMPI_FindArg( argc, argv, VMPI_GetParamString( mpi_Local ), "" ) )
+ mode = VMPI_RUN_LOCAL;
+ else
+ mode = VMPI_RUN_NETWORKED;
+
+ VMPI_Stats_InstallSpewHook();
+
+ //
+ // Extract mpi specific arguments
+ //
+ Msg( "Initializing VMPI...\n" );
+ if ( !VMPI_Init(
+ argc,
+ argv,
+ "dependency_info_vrad.txt",
+ HandleMPIDisconnect,
+ mode
+ ) )
+ {
+ Error( "MPI_Init failed." );
+ }
+
+ StatsDB_InitStatsDatabase( argc, argv, "dbinfo_vrad.txt" );
+}
+
+
+//-----------------------------------------
+//
+// Run BuildFaceLights across all available processing nodes
+// and collect the results.
+//
+
+CCycleCount g_CPUTime;
+
+
+template<class T> void WriteValues( MessageBuffer *pmb, T const *pSrc, int nNumValues)
+{
+ pmb->write(pSrc, sizeof( pSrc[0]) * nNumValues );
+}
+
+template<class T> int ReadValues( MessageBuffer *pmb, T *pDest, int nNumValues)
+{
+ return pmb->read( pDest, sizeof( pDest[0]) * nNumValues );
+}
+
+
+//--------------------------------------------------
+// Serialize face data
+void SerializeFace( MessageBuffer * pmb, int facenum )
+{
+ int i, n;
+
+ dface_t * f = &g_pFaces[facenum];
+ facelight_t * fl = &facelight[facenum];
+
+ pmb->write(f, sizeof(dface_t));
+ pmb->write(fl, sizeof(facelight_t));
+
+ WriteValues( pmb, fl->sample, fl->numsamples);
+
+ //
+ // Write the light information
+ //
+ for (i=0; i<MAXLIGHTMAPS; ++i) {
+ for (n=0; n<NUM_BUMP_VECTS+1; ++n) {
+ if (fl->light[i][n])
+ {
+ WriteValues( pmb, fl->light[i][n], fl->numsamples);
+ }
+ }
+ }
+
+ if (fl->luxel)
+ WriteValues( pmb, fl->luxel, fl->numluxels);
+
+ if (fl->luxelNormals)
+ WriteValues( pmb, fl->luxelNormals, fl->numluxels);
+}
+
+//--------------------------------------------------
+// UnSerialize face data
+//
+void UnSerializeFace( MessageBuffer * pmb, int facenum, int iSource )
+{
+ int i, n;
+
+ dface_t * f = &g_pFaces[facenum];
+ facelight_t * fl = &facelight[facenum];
+
+ if (pmb->read(f, sizeof(dface_t)) < 0)
+ Error("UnSerializeFace - invalid dface_t from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
+
+ if (pmb->read(fl, sizeof(facelight_t)) < 0)
+ Error("UnSerializeFace - invalid facelight_t from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
+
+ fl->sample = (sample_t *) calloc(fl->numsamples, sizeof(sample_t));
+ if (pmb->read(fl->sample, sizeof(sample_t) * fl->numsamples) < 0)
+ Error("UnSerializeFace - invalid sample_t from %s (mb len: %d, offset: %d, fl->numsamples: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset(), fl->numsamples );
+
+ //
+ // Read the light information
+ //
+ for (i=0; i<MAXLIGHTMAPS; ++i) {
+ for (n=0; n<NUM_BUMP_VECTS+1; ++n) {
+ if (fl->light[i][n])
+ {
+ fl->light[i][n] = (LightingValue_t *) calloc( fl->numsamples, sizeof(LightingValue_t ) );
+ if ( ReadValues( pmb, fl->light[i][n], fl->numsamples) < 0)
+ Error("UnSerializeFace - invalid fl->light from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
+ }
+ }
+ }
+
+ if (fl->luxel) {
+ fl->luxel = (Vector *) calloc(fl->numluxels, sizeof(Vector));
+ if (ReadValues( pmb, fl->luxel, fl->numluxels) < 0)
+ Error("UnSerializeFace - invalid fl->luxel from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
+ }
+
+ if (fl->luxelNormals) {
+ fl->luxelNormals = (Vector *) calloc(fl->numluxels, sizeof( Vector ));
+ if ( ReadValues( pmb, fl->luxelNormals, fl->numluxels) < 0)
+ Error("UnSerializeFace - invalid fl->luxelNormals from %s (mb len: %d, offset: %d)", VMPI_GetMachineName( iSource ), pmb->getLen(), pmb->getOffset() );
+ }
+
+}
+
+
+void MPI_ReceiveFaceResults( uint64 iWorkUnit, MessageBuffer *pBuf, int iWorker )
+{
+ UnSerializeFace( pBuf, iWorkUnit, iWorker );
+}
+
+
+void MPI_ProcessFaces( int iThread, uint64 iWorkUnit, MessageBuffer *pBuf )
+{
+ // Do BuildFacelights on the face.
+ CTimeAdder adder( &g_CPUTime );
+
+ BuildFacelights( iThread, iWorkUnit );
+
+ // Send the results.
+ if ( pBuf )
+ {
+ SerializeFace( pBuf, iWorkUnit );
+ }
+}
+
+
+void RunMPIBuildFacelights()
+{
+ g_CPUTime.Init();
+
+ Msg( "%-20s ", "BuildFaceLights:" );
+ if ( g_bMPIMaster )
+ {
+ StartPacifier("");
+ }
+
+ VMPI_SetCurrentStage( "RunMPIBuildFaceLights" );
+ double elapsed = DistributeWork(
+ numfaces,
+ VMPI_DISTRIBUTEWORK_PACKETID,
+ MPI_ProcessFaces,
+ MPI_ReceiveFaceResults );
+
+ if ( g_bMPIMaster )
+ {
+ EndPacifier(false);
+ Msg( " (%d)\n", (int)elapsed );
+ }
+
+ if ( g_bMPIMaster )
+ {
+ //
+ // BuildPatchLights is normally called from BuildFacelights(),
+ // but in MPI mode we have the master do the calculation
+ // We might be able to speed this up by doing while the master
+ // is idling in the above loop. Wouldn't want to slow down the
+ // handing out of work - maybe another thread?
+ //
+ for ( int i=0; i < numfaces; ++i )
+ {
+ BuildPatchLights(i);
+ }
+ }
+ else
+ {
+ if ( g_iVMPIVerboseLevel >= 1 )
+ Msg( "\n\n%.1f%% CPU utilization during BuildFaceLights\n\n", ( g_CPUTime.GetSeconds() * 100 / elapsed ) );
+ }
+}
+
+
+//-----------------------------------------
+//
+// Run BuildVisLeafs across all available processing nodes
+// and collect the results.
+//
+
+// This function is called when the master receives results back from a worker.
+void MPI_ReceiveVisLeafsResults( uint64 iWorkUnit, MessageBuffer *pBuf, int iWorker )
+{
+ int patchesInCluster = 0;
+
+ pBuf->read(&patchesInCluster, sizeof(patchesInCluster));
+
+ for ( int k=0; k < patchesInCluster; ++k )
+ {
+ int patchnum = 0;
+ pBuf->read(&patchnum, sizeof(patchnum));
+
+ CPatch * patch = &g_Patches[patchnum];
+ int numtransfers;
+ pBuf->read( &numtransfers, sizeof(numtransfers) );
+ patch->numtransfers = numtransfers;
+ if (numtransfers)
+ {
+ patch->transfers = new transfer_t[numtransfers];
+ pBuf->read(patch->transfers, numtransfers * sizeof(transfer_t));
+ }
+
+ total_transfer += numtransfers;
+ if (max_transfer < numtransfers)
+ max_transfer = numtransfers;
+ }
+}
+
+
+// Temporary variables used during callbacks. If we're going to be threadsafe, these
+// should go in a structure and get passed around.
+class CVMPIVisLeafsData
+{
+public:
+ MessageBuffer *m_pVisLeafsMB;
+ int m_nPatchesInCluster;
+ transfer_t *m_pBuildVisLeafsTransfers;
+};
+
+CVMPIVisLeafsData g_VMPIVisLeafsData[MAX_TOOL_THREADS+1];
+
+
+
+// This is called by BuildVisLeafs_Cluster every time it finishes a patch.
+// The results are appended to g_VisLeafsMB and sent back to the master when all clusters are done.
+void MPI_AddPatchData( int iThread, int patchnum, CPatch *patch )
+{
+ CVMPIVisLeafsData *pData = &g_VMPIVisLeafsData[iThread];
+ if ( pData->m_pVisLeafsMB )
+ {
+ // Add in results for this patch
+ ++pData->m_nPatchesInCluster;
+ pData->m_pVisLeafsMB->write(&patchnum, sizeof(patchnum));
+ pData->m_pVisLeafsMB->write(&patch->numtransfers, sizeof(patch->numtransfers));
+ pData->m_pVisLeafsMB->write( patch->transfers, patch->numtransfers * sizeof(transfer_t) );
+ }
+}
+
+
+// This handles a work unit sent by the master. Each work unit here is a
+// list of clusters.
+void MPI_ProcessVisLeafs( int iThread, uint64 iWorkUnit, MessageBuffer *pBuf )
+{
+ CTimeAdder adder( &g_CPUTime );
+
+ CVMPIVisLeafsData *pData = &g_VMPIVisLeafsData[iThread];
+ int iCluster = iWorkUnit;
+
+ // Start this cluster.
+ pData->m_nPatchesInCluster = 0;
+ pData->m_pVisLeafsMB = pBuf;
+
+ // Write a temp value in there. We overwrite it later.
+ int iSavePos = 0;
+ if ( pBuf )
+ {
+ iSavePos = pBuf->getLen();
+ pBuf->write( &pData->m_nPatchesInCluster, sizeof(pData->m_nPatchesInCluster) );
+ }
+
+ // Collect the results in MPI_AddPatchData.
+ BuildVisLeafs_Cluster( iThread, pData->m_pBuildVisLeafsTransfers, iCluster, MPI_AddPatchData );
+
+ // Now send the results back..
+ if ( pBuf )
+ {
+ pBuf->update( iSavePos, &pData->m_nPatchesInCluster, sizeof(pData->m_nPatchesInCluster) );
+ pData->m_pVisLeafsMB = NULL;
+ }
+}
+
+
+void RunMPIBuildVisLeafs()
+{
+ g_CPUTime.Init();
+
+ Msg( "%-20s ", "BuildVisLeafs :" );
+ if ( g_bMPIMaster )
+ {
+ StartPacifier("");
+ }
+
+ memset( g_VMPIVisLeafsData, 0, sizeof( g_VMPIVisLeafsData ) );
+ if ( !g_bMPIMaster || VMPI_GetActiveWorkUnitDistributor() == k_eWorkUnitDistributor_SDK )
+ {
+ // Allocate space for the transfers for each thread.
+ for ( int i=0; i < numthreads; i++ )
+ {
+ g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers = BuildVisLeafs_Start();
+ }
+ }
+
+ //
+ // Slaves ask for work via GetMPIBuildVisLeafWork()
+ // Results are returned in BuildVisRow()
+ //
+ VMPI_SetCurrentStage( "RunMPIBuildVisLeafs" );
+
+ double elapsed = DistributeWork(
+ dvis->numclusters,
+ VMPI_DISTRIBUTEWORK_PACKETID,
+ MPI_ProcessVisLeafs,
+ MPI_ReceiveVisLeafsResults );
+
+ // Free the transfers from each thread.
+ for ( int i=0; i < numthreads; i++ )
+ {
+ if ( g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers )
+ BuildVisLeafs_End( g_VMPIVisLeafsData[i].m_pBuildVisLeafsTransfers );
+ }
+
+ if ( g_bMPIMaster )
+ {
+ EndPacifier(false);
+ Msg( " (%d)\n", (int)elapsed );
+ }
+ else
+ {
+ if ( g_iVMPIVerboseLevel >= 1 )
+ Msg( "%.1f%% CPU utilization during PortalFlow\n", (g_CPUTime.GetSeconds() * 100.0f / elapsed) / numthreads );
+ }
+}
+
+void VMPI_DistributeLightData()
+{
+ if ( !g_bUseMPI )
+ return;
+
+ if ( g_bMPIMaster )
+ {
+ const char *pVirtualFilename = "--plightdata--";
+
+ CUtlBuffer lightFaceData;
+
+ // write out the light data
+ lightFaceData.EnsureCapacity( pdlightdata->Count() + (numfaces * (MAXLIGHTMAPS+sizeof(int))) );
+ Q_memcpy( lightFaceData.PeekPut(), pdlightdata->Base(), pdlightdata->Count() );
+ lightFaceData.SeekPut( CUtlBuffer::SEEK_HEAD, pdlightdata->Count() );
+
+ // write out the relevant face info into the stream
+ for ( int i = 0; i < numfaces; i++ )
+ {
+ for ( int j = 0; j < MAXLIGHTMAPS; j++ )
+ {
+ lightFaceData.PutChar(g_pFaces[i].styles[j]);
+ }
+ lightFaceData.PutInt(g_pFaces[i].lightofs);
+ }
+ VMPI_FileSystem_CreateVirtualFile( pVirtualFilename, lightFaceData.Base(), lightFaceData.TellMaxPut() );
+
+ char cPacketID[2] = { VMPI_VRAD_PACKET_ID, VMPI_SUBPACKETID_PLIGHTDATA_RESULTS };
+ VMPI_Send2Chunks( cPacketID, sizeof( cPacketID ), pVirtualFilename, strlen( pVirtualFilename ) + 1, VMPI_PERSISTENT );
+ }
+ else
+ {
+ VMPI_SetCurrentStage( "VMPI_DistributeLightData" );
+
+ // Wait until we've received the filename from the master.
+ while ( g_LightResultsFilename.Count() == 0 )
+ {
+ VMPI_DispatchNextMessage();
+ }
+
+ // Open
+ FileHandle_t fp = g_pFileSystem->Open( g_LightResultsFilename.Base(), "rb", VMPI_VIRTUAL_FILES_PATH_ID );
+ if ( !fp )
+ Error( "Can't open '%s' to read lighting info.", g_LightResultsFilename.Base() );
+
+ int size = g_pFileSystem->Size( fp );
+ int faceSize = (numfaces*(MAXLIGHTMAPS+sizeof(int)));
+
+ if ( size > faceSize )
+ {
+ int lightSize = size - faceSize;
+ CUtlBuffer faceData;
+ pdlightdata->EnsureCount( lightSize );
+ faceData.EnsureCapacity( faceSize );
+
+ g_pFileSystem->Read( pdlightdata->Base(), lightSize, fp );
+ g_pFileSystem->Read( faceData.Base(), faceSize, fp );
+ g_pFileSystem->Close( fp );
+
+ faceData.SeekPut( CUtlBuffer::SEEK_HEAD, faceSize );
+
+ // write out the face data
+ for ( int i = 0; i < numfaces; i++ )
+ {
+ for ( int j = 0; j < MAXLIGHTMAPS; j++ )
+ {
+ g_pFaces[i].styles[j] = faceData.GetChar();
+ }
+ g_pFaces[i].lightofs = faceData.GetInt();
+ }
+ }
+ }
+}
+
+