static int ServiceMain(int argc, char **argv) { SOCKET s; int status; static struct sockaddr_in sin; int tablesize = FD_SETSIZE; extern fd_set FdActive(); struct timeval timeout = {1,0}; int error_count=0; fd_set readfds; fd_set fdactive; RedirectOutput(); InitializeService(); SetThisServiceStatus(SERVICE_RUNNING,0); if (GetMulti()) { IoRoutines *io; io=LoadIo(GetProtocol()); if (io && io->listen) io->listen(argc,argv); else { fprintf(stderr,"Protocol %s does not support servers\n",GetProtocol()); return 1; } return 0; } else { s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { printf("Error getting Connection Socket\n"); exit(1); } memset(&sin,0,sizeof(sin)); sin.sin_port = GetPort(); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; status = bind(s, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); if (status < 0) { perror("Error binding to service\n"); exit(1); } status = listen(s,128); if (status < 0) { perror("Error listen on port\n"); exit(1); } FD_ZERO(&fdactive); FD_SET(s,&fdactive); for (readfds=fdactive;!shut;readfds=fdactive) { int sstatus; if ((sstatus = select(tablesize, &readfds, 0, 0, &timeout)) != SOCKET_ERROR) { error_count=0; if (FD_ISSET(s, &readfds)){ int len = sizeof(struct sockaddr_in); SOCKET sock = accept(s, (struct sockaddr *)&sin, &len); SpawnWorker(sock); } } else { error_count++; perror("error in main select"); fprintf(stderr,"Error count=%d\n",error_count); fflush(stderr); if (error_count > 100) { fprintf(stderr,"Error count exceeded, shutting down\n"); shut=1; } } } shutdown(s,2); return 1; } }
//----------------------------------------------------------------------------- /// Submit command buffers and gather results. /// \param queue The queue issued work to. /// \param submitCount The number of submits. /// \param pSubmits The submit info structures. /// \param fence The fence wrapping this submit. //----------------------------------------------------------------------------- VkResult VktWrappedQueue::QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence) { m_executionID++; VkResult result = VK_INCOMPLETE; VktTraceAnalyzerLayer* pTraceAnalyzer = VktTraceAnalyzerLayer::Instance(); VktFrameProfilerLayer* pFrameProfiler = VktFrameProfilerLayer::Instance(); // Use this calibration timestamp structure to convert GPU events to the CPU timeline. CalibrationTimestampPair calibrationTimestamps = {}; calibrationTimestamps.mQueueCanBeTimestamped = true; VkFence fenceToWaitOn = fence; bool usingInternalFence = false; std::vector<VktWrappedCmdBuf*> wrappedCmdBufs; GatherWrappedCommandBufs(submitCount, pSubmits, wrappedCmdBufs); for (UINT i = 0; i < wrappedCmdBufs.size(); i++) { wrappedCmdBufs[i]->SetProfilerExecutionId(m_executionID); wrappedCmdBufs[i]->IncrementSubmitCount(); } // Surround the execution of CommandBuffers with timestamps so we can determine when the GPU work occurred in the CPU timeline. if (pTraceAnalyzer->ShouldCollectTrace() && pFrameProfiler->ShouldCollectGPUTime()) { // Collect calibration timestamps in case we need to align GPU events against the CPU timeline. if (calibrationTimestamps.mQueueCanBeTimestamped) { pFrameProfiler->CollectCalibrationTimestamps(this, &calibrationTimestamps); } else { Log(logTRACE, "Did not collect calibration timestamps for Queue '0x%p'\n", this); } // Inject our own fence if the app did not supply one if (fenceToWaitOn == VK_NULL_HANDLE) { // Create internal fence VkFenceCreateInfo fenceCreateInfo = {}; VkResult fenceResult = VK_INCOMPLETE; fenceResult = device_dispatch_table(queue)->CreateFence(m_createInfo.device, &fenceCreateInfo, nullptr, &fenceToWaitOn); VKT_ASSERT(fenceResult == VK_SUCCESS); usingInternalFence = true; } } // Invoke the real call to execute on the GPU result = QueueSubmit_ICD(queue, submitCount, pSubmits, fenceToWaitOn); if (pTraceAnalyzer->ShouldCollectTrace() && pFrameProfiler->ShouldCollectGPUTime()) { // Collect the CPU and GPU frequency to convert timestamps. QueryPerformanceFrequency(&calibrationTimestamps.cpuFrequency); #if GATHER_PROFILER_RESULTS_WITH_WORKERS SpawnWorker(&calibrationTimestamps, this, fenceToWaitOn, usingInternalFence, wrappedCmdBufs); #else VkResult waitResult = VK_TIMEOUT; #if GPU_FENCES_FOR_PROFILER_WAIT do { waitResult = device_dispatch_table(m_createInfo.device)->WaitForFences(m_createInfo.device, 1, &fenceToWaitOn, VK_TRUE, GPU_FENCE_TIMEOUT_TIME); } while (waitResult == VK_TIMEOUT); #else waitResult = device_dispatch_table(queue)->QueueWaitIdle(queue); #endif if (calibrationTimestamps.mQueueCanBeTimestamped) { // Put all results into thread ID 0 bucket const UINT32 threadID = 0; std::vector<ProfilerResult> results; for (UINT i = 0; i < wrappedCmdBufs.size(); i++) { ProfilerResultCode getResultsResult = PROFILER_FAIL; getResultsResult = wrappedCmdBufs[i]->GetCmdBufResultsST(results); VKT_ASSERT(getResultsResult != PROFILER_FAIL); } pFrameProfiler->VerifyAlignAndStoreResults(this, results, &calibrationTimestamps, threadID, VktTraceAnalyzerLayer::Instance()->GetFrameStartTime()); // Free the fence we created earlier if (usingInternalFence) { device_dispatch_table(m_createInfo.device)->DestroyFence(m_createInfo.device, fenceToWaitOn, nullptr); } } else { Log(logTRACE, "Didn't collect calibration timestamps for Queue '0x%p'.\n", this); } #endif } #if GATHER_PROFILER_RESULTS_WITH_WORKERS == 0 for (UINT i = 0; i < wrappedCmdBufs.size(); i++) { wrappedCmdBufs[i]->DestroyDynamicProfilers(); } #endif return result; }