// Load //------------------------------------------------------------------------------ /*static*/ Node * Node::Load( IOStream & stream ) { // read type uint32_t nodeType; if ( stream.Read( nodeType ) == false ) { return nullptr; } PROFILE_SECTION(Node::GetTypeName((Type)nodeType)); // read stamp (but not for file nodes) uint64_t stamp( 0 ); if ( nodeType != Node::FILE_NODE ) { if ( stream.Read( stamp ) == false ) { return nullptr; } } // read contents Node * n = nullptr; switch ( (Node::Type)nodeType ) { case Node::PROXY_NODE: ASSERT( false ); break; case Node::COPY_NODE: n = CopyNode::Load( stream ); break; case Node::DIRECTORY_LIST_NODE: n = DirectoryListNode::Load( stream ); break; case Node::EXEC_NODE: n = ExecNode::Load( stream ); break; case Node::FILE_NODE: n = FileNode::Load( stream ); break; case Node::LIBRARY_NODE: n = LibraryNode::Load( stream ); break; case Node::OBJECT_NODE: n = ObjectNode::Load( stream ); break; case Node::ALIAS_NODE: n = AliasNode::Load( stream ); break; case Node::EXE_NODE: n = ExeNode::Load( stream ); break; case Node::CS_NODE: n = CSNode::Load( stream ); break; case Node::UNITY_NODE: n = UnityNode::Load( stream ); break; case Node::TEST_NODE: n = TestNode::Load( stream ); break; case Node::COMPILER_NODE: n = CompilerNode::Load( stream ); break; case Node::DLL_NODE: n = DLLNode::Load( stream ); break; case Node::VCXPROJECT_NODE: n = VCXProjectNode::Load( stream ); break; case Node::OBJECT_LIST_NODE: n = ObjectListNode::Load( stream ); break; case Node::COPY_DIR_NODE: n = CopyDirNode::Load( stream ); break; case Node::SLN_NODE: n = SLNNode::Load( stream ); break; case Node::NUM_NODE_TYPES: ASSERT( false ); break; } ASSERT( n ); if ( n ) { // set stamp n->m_Stamp = stamp; } return n; }
void ProcessAdjacentMapTiles(Path& thePath, Map* map, const IntVec2& start, const IntVec2& goal, TilePtrs& adjacentTilePtrs){ PROFILE_SECTION(); //7 for (adjacent List of PathNodes) for (TilePtrsIterator it = adjacentTilePtrs.begin(); it != adjacentTilePtrs.end(); ++it){ Tile* tile = (*it); ProcessAdjacentMapTile(thePath, tile, map, start, goal); }//end of for }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void MyWindow::display() { WindowInertiaCamera::display(); if(!s_pCurRenderer->valid()) { glClearColor(0.5,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); swapBuffers(); return; } float dt = (float)m_realtime.getTiming(); // // render the scene // std::string stats; static std::string hudStats = "..."; { nv_helpers::Profiler::FrameHelper helper(g_profiler,sysGetTime(), 2.0, stats); PROFILE_SECTION("display"); s_pCurRenderer->display(m_camera, m_projection); // // additional HUD stuff // WindowInertiaCamera::beginDisplayHUD(); s_helpText -= dt; m_oglTextBig.drawString(5, 5, "('h' for help)", 1, vec4f(0.8,0.8,1.0,0.5f).vec_array); float h = 30; if(s_bStats) h += m_oglTextBig.drawString(5, m_winSz[1]-h, hudStats.c_str(), 0, vec4f(0.8,0.8,1.0,0.5).vec_array); if(s_helpText > 0) { // camera help const char *txt = getHelpText(); h += m_oglTextBig.drawString(5, m_winSz[1]-h, txt, 0, vec4f(0.8,0.8,1.0,s_helpText/HELPDURATION).vec_array); h += m_oglTextBig.drawString(5, m_winSz[1]-h, s_sampleHelp, 0, vec4f(0.8,0.8,1.0,s_helpText/HELPDURATION).vec_array); } WindowInertiaCamera::endDisplayHUD(); { //PROFILE_SECTION("SwapBuffers"); swapBuffers(); } } //PROFILE_SECTION("display"); // // Stats // if (s_bStats && (!stats.empty())) { hudStats = stats; // make a copy for the hud display } }
//------------------------------------------------------------------------------- void GameApp::updateDisplay() { PROFILE_SECTION( "GameApp" ); glClearColor( 0.2f, 0.2f, 0.2f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); m_renderer->pushCamera( m_camera ); if( m_camera ) { m_camera->update( DELTA_TIME ); } //m_renderer->setWireFrame( m_wireFrame ); m_actorManager.renderActors(); renderDebugHUD(); //m_GDOManager->renderGDOs( m_renderer, m_frameClock.getElapsedSecondsFloat() ); m_renderer->popCamera(); ProfileSystem::getInstance()->clearFrameData(); }
// CommunicateJobAvailability //------------------------------------------------------------------------------ void Client::CommunicateJobAvailability() { // too soon since last status update? if ( m_StatusUpdateTimer.GetElapsed() < CLIENT_STATUS_UPDATE_FREQUENCY_SECONDS ) { return; } m_StatusUpdateTimer.Start(); // reset time // possible for job queue to not exist yet if ( !JobQueue::IsValid() ) { return; } // has status changed since we last sent it? uint32_t numJobsAvailable = (uint32_t)JobQueue::Get().GetNumDistributableJobsAvailable(); Protocol::MsgStatus msg( numJobsAvailable ); MutexHolder mh( m_ServerListMutex ); if ( m_ServerList.IsEmpty() ) { return; // no servers to communicate with } // update each server to know how many jobs we have now ServerState * it = m_ServerList.Begin(); const ServerState * const end = m_ServerList.End(); while ( it != end ) { if ( it->m_Connection ) { MutexHolder ssMH( it->m_Mutex ); if ( it->m_NumJobsAvailable != numJobsAvailable ) { PROFILE_SECTION( "UpdateJobAvailability" ) msg.Send( it->m_Connection ); it->m_NumJobsAvailable = numJobsAvailable; } } ++it; } }
//much slower than the regular one void RecursiveCalcPath(Path& thePath, Map* map, const IntVec2& start, const IntVec2& goal, bool ignoreEntities){ PROFILE_SECTION(); if (!thePath.m_initialized && map){ thePath = Path(map, start, goal); //this adds a start node to open list } if (!thePath.IsOpenListEmpty() && !thePath.m_isComplete){ thePath = ProcessOneStepOfPath(thePath, map, start, goal, ignoreEntities); RecursiveCalcPath(thePath, map, start, goal, ignoreEntities); } else{ return; } }
// Main //------------------------------------------------------------------------------ /*virtual*/ void WorkerThread::Main() { while ( ( m_ShouldExit == false ) && ( FBuild::GetStopBuild() == false ) ) { PROFILE_FUNCTION bool didSomeWork = Update(); if ( didSomeWork ) { continue; // try to build some more } // no work to do right now { PROFILE_SECTION( "WorkerThread::Main::Sleep" ) Thread::Sleep( 1 ); // wait and try again later } } m_Exited = true; }
// Monitor //------------------------------------------------------------------------------ /*static*/ void FLog::Monitor( const char * formatString, ... ) { // Is monitoring enabled? if ( g_MonitorFileStream == nullptr ) { return; // No - nothing to do } PROFILE_SECTION( "FLog::Monitor" ) AStackString< 1024 > buffer; va_list args; va_start( args, formatString ); buffer.VFormat( formatString, args ); va_end( args ); AStackString< 1024 > finalBuffer; finalBuffer.Format( "%llu %s", Time::GetCurrentFileTime(), buffer.Get() ); MutexHolder lock( g_MonitorMutex ); g_MonitorFileStream->WriteBuffer( finalBuffer.Get(), finalBuffer.GetLength() ); }
//A* Pathfinding Algorithm //pass in a blank myPath to be filled Path& CalcPath(Path& thePath, Map* map, const MapPosition& start, const MapPosition& goal, bool ignoreEntities){ PROFILE_SECTION(); if (!thePath.m_initialized && map){ thePath = Path(map, start, goal); //this adds a start node to open list } //find the path and stuff while (!thePath.IsOpenListEmpty() && !thePath.m_isComplete){ ProcessOneStepOfPath(thePath, map, start, goal, ignoreEntities); }//end of while if (thePath.IsOpenListEmpty() && !thePath.m_isComplete){ thePath.m_isImpossible = true; } //17 return the path return thePath; }//end of calc path
// Finalize //------------------------------------------------------------------------------ bool Args::Finalize( const AString & exe, const AString & nodeNameForError, bool canUseResponseFile ) { ASSERT( !m_Finalized ); #if defined( __WINDOWS__ ) || defined( __OSX__ ) #if defined( __WINDOWS__ ) // Windows has a 32KiB (inc null terminator) command line length limit with CreateProcess // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx const uint32_t argLimit( 32767 ); #elif defined( __OSX__ ) const uint32_t argLimit( ARG_MAX - 1 ); #endif // Calculate final length of args (including exe name) const uint32_t exeLen = exe.GetLength(); const uint32_t extraLen = 3; // quotes around exe name and space const uint32_t argLen = m_Args.GetLength(); // We need to consider the executable, quotes around the exe and a space // as well as the args: "%exe%" %args% const uint32_t totalLen = ( argLen + exeLen + extraLen ); // Small enough? if ( totalLen <= argLimit ) { #if defined( ASSERTS_ENABLED ) m_Finalized = true; #endif return true; // Ok to proceed } // Args are too long. Can we cope using a Response File? if ( canUseResponseFile ) { // Handle per-line limit within response files (e.g. link.exe) #if defined( __WINDOWS__ ) if ( argLen >= 131071 ) // From LNK1170 { // Change spaces to carriage returns for ( uint32_t i : m_DelimiterIndices ) { ASSERT( m_Args[ i ] == ' ' ); m_Args[ i ] = '\n'; } } #endif #if defined( ASSERTS_ENABLED ) m_Finalized = true; #endif // Write args to response file { PROFILE_SECTION( "CreateResponseFile" ) m_ResponseFile.Create( *this ); } // Create new args referencing response file m_ResponseFileArgs = "@\""; m_ResponseFileArgs += m_ResponseFile.GetResponseFilePath(); m_ResponseFileArgs += "\""; return true; // Ok to proceed } // Need response file but not supported FLOG_ERROR( "FBuild: Error: Command Line Limit Exceeded (len: %u, limit: %u) '%s'\n", argLen, argLimit, nodeNameForError.Get() ); return false; #elif defined( __LINUX__ ) // TODO:LINUX Difficult to reliable determine this due to complex interaction with environment #if defined( ASSERTS_ENABLED ) m_Finalized = true; #endif return true; // Ok to proceed #endif }
Path& ProcessOneStepOfPath(Path& thePath, Map* map, const IntVec2& start, const IntVec2& goal, bool ignoreEntities ){ PROFILE_SECTION(); if (!thePath.m_initialized && map){ thePath = Path(map, start, goal); } if (!thePath.IsOpenListEmpty() && !thePath.m_isComplete){ thePath.m_iterations++; PROFILE_START(steps 1 to 4); //1 pick lowest f on openList check //2 remove from open list check PathNode* lowestFCostInThePath = thePath.PopLowestFCostInOpenList(); //3 add lowest cost to closed list check Tile* tileToCheckID = map->GetTileAtMapPosition(lowestFCostInThePath->m_position); tilesPathIDOpenCritSec.Enter(); tileToCheckID->m_inOpenListOfPathID = -1; tilesPathIDOpenCritSec.Exit(); //tilesPathIDCritSec.Enter(); if (tileToCheckID->m_inClosedListOfPathID != thePath.m_id){ thePath.AddToClosedList(lowestFCostInThePath); CRITICAL_SECTION_SCOPE(tilesPathIDClosedCritSec); tileToCheckID->m_inClosedListOfPathID = thePath.m_id; } //tilesPathIDCritSec.Exit(); // if (!thePath.IsMapPositionInClosedList(lowestFCostInThePath->m_position)){ // // thePath.AddToClosedList(lowestFCostInThePath); // // } //4 set lowest f node to active thePath.m_activeNode = lowestFCostInThePath; PROFILE_STOP(); //5 check if node is goal, break; if (thePath.m_activeNode->m_position == goal){ thePath.m_isComplete = true; //ConsoleGenericMessageBox("YAY Path is found."); thePath.m_openList.clear(); return thePath; } else{ TilePtrs adjacentTilePtrs; PROFILE_START(step 6); //6 ask "map" for adjacent positions of active node Tile* activeTile = map->GetTileAtMapPosition(thePath.m_activeNode->m_position); if (activeTile){ adjacentTilePtrs = map->GetValidAdjacentTiles(activeTile, ignoreEntities); } PROFILE_STOP(); //this is the longest part of pathing ProcessAdjacentMapTiles(thePath, map, start, goal, adjacentTilePtrs); } }//end of final outer if // else if (thePath.IsOpenListEmpty()){ // //ConsoleGenericMessageBox("No Path =("); // // //the path is impossible // thePath.m_isImpossible = true; // // return thePath; // } return thePath; }
void ProcessAdjacentMapTile(Path& thePath, Tile* tile, Map* map, const IntVec2& start, const IntVec2& goal ){ UNUSED(start); PROFILE_SECTION(); if (tile == NULL) return; //8 Get adjacent pos MapPosition& adjacentNodePos = tile->m_mapPosition; //float newFinalCostCheck = newPathNode->m_nodeCost.h; //if (newFinalCostCheck < 2.0f * map->m_size.x * map->m_size.y){ //9 if (adjacent pos on closed list) //continue; Tile* tileToCheckID = map->GetTileAtMapPosition(adjacentNodePos); bool tileCheckID; //tilesPathIDCritSec.Enter(); tileCheckID = (tileToCheckID->m_inClosedListOfPathID == thePath.m_id); //tilesPathIDCritSec.Exit(); if (tileCheckID){ //if (thePath.IsMapPositionInClosedList(adjacentNodePos)){ return; } else{ //10 & 11 decently fast // 10 if (not on open list){ if(tileToCheckID->m_inOpenListOfPathID != thePath.m_id){ //if (!thePath.IsMapPositionInOpenList(adjacentNodePos)){ PROFILE_START(step 10 and 11); //11 build new pathnode(local G, parentG = ActiveNode.G) // Add to OpenList PathNode* newPathNode = new PathNode(tile, thePath.m_activeNode, goal, thePath.m_bestAvoidCost); //this bit of path node has a memory leak thePath.AddToOpenList(newPathNode); tilesPathIDOpenCritSec.Enter(); tile->m_inOpenListOfPathID = thePath.m_id; tilesPathIDOpenCritSec.Exit(); PROFILE_STOP(); return; } else{ //is on openList float altTotalG; float tileAvoidCost; float currentG; PathNode* nodeInOpenList; PROFILE_START(step 12 and 13); //doesn't seem to ever get called tileAvoidCost = tile->m_tileAvoidanceCost; nodeInOpenList = thePath.GetPathNodeAtMapPositionFromOpenList(adjacentNodePos); if (!nodeInOpenList){ return; } //12 calc newG as calc hypothetical G to this node altTotalG = CalcHypotheticalGCostToAdjacentNodePosition(thePath.m_activeNode, adjacentNodePos, tileAvoidCost); //13 compare to G in openList for node holding this position currentG = nodeInOpenList->m_nodeCost.g; PROFILE_STOP(); //14 if better < if (altTotalG < currentG){ //15 update openListNode, update localG, parent, PROFILE_START(step 15); ReplaceOpenListPathNode(thePath, nodeInOpenList, tileAvoidCost); PROFILE_STOP(); return; } else{ //16 if worse or equal >= //throw out return; }//end of inside if/else }//end of if/else }//end of outer if/else }
// MainThreadWait //------------------------------------------------------------------------------ void JobQueueRemote::MainThreadWait( uint32_t timeoutMS ) { PROFILE_SECTION( "MainThreadWait" ) m_MainThreadSemaphore.Wait( timeoutMS ); }
// DoBuild //------------------------------------------------------------------------------ /*static*/ Node::BuildResult JobQueueRemote::DoBuild( Job * job, bool racingRemoteJob ) { Timer timer; // track how long the item takes ObjectNode * node = job->GetNode()->CastTo< ObjectNode >(); // remote tasks must output to a tmp file if ( job->IsLocal() == false ) { // file name should be the same as on host const char * fileName = ( job->GetRemoteName().FindLast( NATIVE_SLASH ) + 1 ); AStackString<> tmpFileName; WorkerThread::CreateTempFilePath( fileName, tmpFileName ); node->ReplaceDummyName( tmpFileName ); #ifdef DEBUG DEBUGSPAM( "REMOTE: %s (%s)\n", fileName, job->GetRemoteName().Get() ); #endif } ASSERT( node->IsAFile() ); // make sure the output path exists if ( Node::EnsurePathExistsForFile( node->GetName() ) == false ) { // error already output by EnsurePathExistsForFile return Node::NODE_RESULT_FAILED; } // Delete any left over PDB from a previous run (to be sure we have a clean pdb) if ( node->IsUsingPDB() && ( job->IsLocal() == false ) ) { AStackString<> pdbName; node->GetPDBName( pdbName ); FileIO::FileDelete( pdbName.Get() ); } Node::BuildResult result; { PROFILE_SECTION( racingRemoteJob ? "RACE" : "LOCAL" ); result = ((Node *)node )->DoBuild2( job, racingRemoteJob ); } uint32_t timeTakenMS = uint32_t( timer.GetElapsedMS() ); if ( result == Node::NODE_RESULT_OK ) { // record new build time only if built (i.e. if failed, the time // does not represent how long it takes to create this resource) node->SetLastBuildTime( timeTakenMS ); node->SetStatFlag( Node::STATS_BUILT ); //FLOG_INFO( "-Build: %u ms\t%s", timeTakenMS, node->GetName().Get() ); #ifdef DEBUG if ( job->IsLocal() ) { // record new file time for remote job we built locally ASSERT( node->m_Stamp == FileIO::GetFileLastWriteTime(node->GetName()) ); } #endif } if ( result == Node::NODE_RESULT_FAILED ) { // build of file failed - if there is a file.... if ( FileIO::FileExists( node->GetName().Get() ) ) { // ... it is invalid, so try to delete it if ( FileIO::FileDelete( node->GetName().Get() ) == false ) { // failed to delete it - this might cause future build problems! FLOG_ERROR( "Post failure deletion failed for '%s'", node->GetName().Get() ); } } } else { // build completed ok, or retrieved from cache... ASSERT( result == Node::NODE_RESULT_OK ); // TODO:A Also read into job if cache is being used if ( job->IsLocal() == false ) { // read results into memory to send back to client if ( ReadResults( job ) == false ) { result = Node::NODE_RESULT_FAILED; } } } // if compiling to a tmp file, do cleanup if ( job->IsLocal() == false ) { // Cleanup obj file FileIO::FileDelete( node->GetName().Get() ); // Cleanup PDB file if ( node->IsUsingPDB() ) { AStackString<> pdbName; node->GetPDBName( pdbName ); FileIO::FileDelete( pdbName.Get() ); } } // log processing time node->AddProcessingTime( timeTakenMS ); return result; }
// WorkerThreadWait //------------------------------------------------------------------------------ void JobQueueRemote::WorkerThreadWait( uint32_t timeoutMS ) { PROFILE_SECTION( "WorkerThreadWait" ) m_WorkerThreadSemaphore.Wait( timeoutMS ); }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void RendererVk::display(const InertiaCamera& camera, const mat4f& projection) { PROFILE_SECTION("RendererVk::display"); if(m_bValid == false) return; //NXPROFILEFUNC(__FUNCTION__); // // Update general params for all sub-sequent operations IN CMD BUFFER #1 // g_globalMatrices.mV = camera.m4_view; g_globalMatrices.mP = projection; float w = (float)m_nvFBOBox.getBufferWidth(); float h = (float)m_nvFBOBox.getBufferHeight(); VkRenderPass renderPass = m_nvFBOBox.getScenePass(); VkFramebuffer framebuffer = m_nvFBOBox.getFramebuffer(); NVK::VkRect2D viewRect = m_nvFBOBox.getViewRect(); // // Create the primary command buffer // // // pingpong between 2 cmd-buffers to avoid waiting for them to be done // m_cmdSceneIdx ^= 1; if(m_cmdScene[m_cmdSceneIdx]) { while(nvk.vkWaitForFences(1, &m_sceneFence[m_cmdSceneIdx], VK_TRUE, 100000000) == false) { } nvk.vkResetFences(1, &m_sceneFence[m_cmdSceneIdx]); nvk.vkFreeCommandBuffer(m_cmdPool, m_cmdScene[m_cmdSceneIdx]); m_cmdScene[m_cmdSceneIdx] = NULL; } m_cmdScene[m_cmdSceneIdx] = nvk.vkAllocateCommandBuffer(m_cmdPool, true); nvk.vkBeginCommandBuffer(m_cmdScene[m_cmdSceneIdx], false, NVK::VkCommandBufferInheritanceInfo(renderPass, 0, framebuffer, VK_FALSE, 0, 0) ); vkCmdBeginRenderPass(m_cmdScene[m_cmdSceneIdx], NVK::VkRenderPassBeginInfo( renderPass, framebuffer, viewRect, NVK::VkClearValue(NVK::VkClearColorValue(0.0f, 0.1f, 0.15f, 1.0f)) (NVK::VkClearDepthStencilValue(1.0, 0))), VK_SUBPASS_CONTENTS_INLINE ); vkCmdUpdateBuffer (m_cmdScene[m_cmdSceneIdx], m_matrix.buffer, 0, sizeof(g_globalMatrices), (uint32_t*)&g_globalMatrices); // // render the mesh // vkCmdBindPipeline(m_cmdScene[m_cmdSceneIdx], VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelinefur); vkCmdSetViewport( m_cmdScene[m_cmdSceneIdx], 0, 1, NVK::VkViewport(0.0, 0.0, w, h, 0.0f, 1.0f) ); vkCmdSetScissor( m_cmdScene[m_cmdSceneIdx], 0, 1, NVK::VkRect2D(0.0, 0.0, w, h) ); VkDeviceSize vboffsets[1] = {0}; vkCmdBindVertexBuffers(m_cmdScene[m_cmdSceneIdx], 0, 1, &m_furBuffer.buffer, vboffsets); // // bind the descriptor set for global stuff // vkCmdBindDescriptorSets(m_cmdScene[m_cmdSceneIdx], VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, DSET_GLOBAL, 1, &m_descriptorSetGlobal, 0, NULL); vkCmdDraw(m_cmdScene[m_cmdSceneIdx], m_nElmts, 1, 0, 0); // // // vkCmdEndRenderPass(m_cmdScene[m_cmdSceneIdx]); vkEndCommandBuffer(m_cmdScene[m_cmdSceneIdx]); const VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; nvk.vkQueueSubmit( NVK::VkSubmitInfo( 1, &m_semOpenGLReadDone, &waitStages, 1, &m_cmdScene[m_cmdSceneIdx], 1, &m_semVKRenderingDone), m_sceneFence[m_cmdSceneIdx] ); // // this is going to issue another command-buffer // m_nvFBOBox.Draw(downsamplingMode); w = m_nvFBOBox.getWidth(); h = m_nvFBOBox.getHeight(); // NO Depth test glDisable(GL_DEPTH_TEST); // // Wait for the queue of Our VK rendering to signal m_semVKRenderingDone so we know the image is ready // glWaitVkSemaphoreNV((GLuint64)m_semVKRenderingDone); // // Blit the image // glDrawVkImageNV((GLuint64)m_nvFBOBox.getColorImage(), 0, 0,0,w,h, 0, 0,1,1,0); // // Signal m_semOpenGLReadDone to tell the VK rendering queue that it can render the next one // glSignalVkSemaphoreNV((GLuint64)m_semOpenGLReadDone); // // Depth test back to ON (assuming we needed to put it back) // glEnable(GL_DEPTH_TEST); }