//----------------------------------------------------------------------------- void vktraceviewer_QTraceFileLoader::loadTraceFile(const QString& filename) { // open trace file and read in header memset(&m_traceFileInfo, 0, sizeof(vktraceviewer_trace_file_info)); m_traceFileInfo.pFile = fopen(filename.toStdString().c_str(), "rb"); bool bOpened = (m_traceFileInfo.pFile != NULL); if (!bOpened) { emit OutputMessage(VKTRACE_LOG_ERROR, "Unable to open file."); } else { m_traceFileInfo.filename = vktrace_allocate_and_copy(filename.toStdString().c_str()); if (populate_trace_file_info(&m_traceFileInfo) == FALSE) { emit OutputMessage(VKTRACE_LOG_ERROR, "Unable to populate trace file info from file."); bOpened = false; } else { // Make sure trace file version is supported if (m_traceFileInfo.header.trace_file_version < VKTRACE_TRACE_FILE_VERSION_MINIMUM_COMPATIBLE) { emit OutputMessage(VKTRACE_LOG_ERROR, QString("Trace file version %1 is older than minimum compatible version (%2).\nYou'll need to make a new trace file, or use an older replayer.").arg(m_traceFileInfo.header.trace_file_version).arg(VKTRACE_TRACE_FILE_VERSION_MINIMUM_COMPATIBLE)); bOpened = false; } #ifdef USE_STATIC_CONTROLLER_LIBRARY m_pController = vtvCreateQController(); if (bOpened) #else if (!load_controllers(&m_traceFileInfo)) { emit OutputMessage(VKTRACE_LOG_ERROR, "Failed to load necessary debug controllers."); bOpened = false; } else if (bOpened) #endif { connect(m_pController, SIGNAL(OutputMessage(VktraceLogLevel, const QString&)), this, SIGNAL(OutputMessage(VktraceLogLevel, const QString&))); connect(m_pController, SIGNAL(OutputMessage(VktraceLogLevel, uint64_t, const QString&)), this, SIGNAL(OutputMessage(VktraceLogLevel, uint64_t, const QString&))); // interpret the trace file packets for (uint64_t i = 0; i < m_traceFileInfo.packetCount; i++) { vktraceviewer_trace_file_packet_offsets* pOffsets = &m_traceFileInfo.pPacketOffsets[i]; switch (pOffsets->pHeader->packet_id) { case VKTRACE_TPI_MESSAGE: m_traceFileInfo.pPacketOffsets[i].pHeader = vktrace_interpret_body_as_trace_packet_message(pOffsets->pHeader)->pHeader; break; case VKTRACE_TPI_MARKER_CHECKPOINT: break; case VKTRACE_TPI_MARKER_API_BOUNDARY: break; case VKTRACE_TPI_MARKER_API_GROUP_BEGIN: break; case VKTRACE_TPI_MARKER_API_GROUP_END: break; case VKTRACE_TPI_MARKER_TERMINATE_PROCESS: break; //TODO processing code for all the above cases default: { vktrace_trace_packet_header* pHeader = m_pController->InterpretTracePacket(pOffsets->pHeader); if (pHeader == NULL) { bOpened = false; emit OutputMessage(VKTRACE_LOG_ERROR, QString("Unrecognized packet type: %1").arg(pOffsets->pHeader->packet_id)); m_traceFileInfo.pPacketOffsets[i].pHeader = NULL; break; } m_traceFileInfo.pPacketOffsets[i].pHeader = pHeader; } } // break from loop if there is an error if (bOpened == false) { break; } } #ifdef USE_STATIC_CONTROLLER_LIBRARY vtvDeleteQController(&m_pController); #else m_controllerFactory.Unload(&m_pController); #endif } } // TODO: We don't really want to close the trace file yet. // I think we want to keep it open so that we can dynamically read from it. // BUT we definitely don't want it to get locked open, so we need a smart // way to open / close from it when reading. fclose(m_traceFileInfo.pFile); m_traceFileInfo.pFile = NULL; } // populate the UI based on trace file info emit TraceFileLoaded(bOpened, m_traceFileInfo, m_controllerFilename); emit Finished(); }
int main_loop(Sequencer &seq, vktrace_trace_packet_replay_library *replayerArray[], vkreplayer_settings settings) { int err = 0; vktrace_trace_packet_header *packet; unsigned int res; vktrace_trace_packet_replay_library *replayer = NULL; vktrace_trace_packet_message* msgPacket; struct seqBookmark startingPacket; bool trace_running = true; int prevFrameNumber = -1; // record the location of looping start packet seq.record_bookmark(); seq.get_bookmark(startingPacket); while (settings.numLoops > 0) { while ((packet = seq.get_next_packet()) != NULL && trace_running) { switch (packet->packet_id) { case VKTRACE_TPI_MESSAGE: msgPacket = vktrace_interpret_body_as_trace_packet_message(packet); vktrace_LogAlways("Packet %lu: Traced Message (%s): %s", packet->global_packet_index, vktrace_LogLevelToShortString(msgPacket->type), msgPacket->message); break; case VKTRACE_TPI_MARKER_CHECKPOINT: break; case VKTRACE_TPI_MARKER_API_BOUNDARY: break; case VKTRACE_TPI_MARKER_API_GROUP_BEGIN: break; case VKTRACE_TPI_MARKER_API_GROUP_END: break; case VKTRACE_TPI_MARKER_TERMINATE_PROCESS: break; //TODO processing code for all the above cases default: { if (packet->tracer_id >= VKTRACE_MAX_TRACER_ID_ARRAY_SIZE || packet->tracer_id == VKTRACE_TID_RESERVED) { vktrace_LogError("Tracer_id from packet num packet %d invalid.", packet->packet_id); continue; } replayer = replayerArray[packet->tracer_id]; if (replayer == NULL) { vktrace_LogWarning("Tracer_id %d has no valid replayer.", packet->tracer_id); continue; } if (packet->packet_id >= VKTRACE_TPI_BEGIN_API_HERE) { // replay the API packet res = replayer->Replay(replayer->Interpret(packet)); if (res != VKTRACE_REPLAY_SUCCESS) { vktrace_LogError("Failed to replay packet_id %d.",packet->packet_id); return -1; } // frame control logic int frameNumber = replayer->GetFrameNumber(); if (prevFrameNumber != frameNumber) { prevFrameNumber = frameNumber; if (frameNumber == settings.loopStartFrame) { // record the location of looping start packet seq.record_bookmark(); seq.get_bookmark(startingPacket); } if (frameNumber == settings.loopEndFrame) { trace_running = false; } } } else { vktrace_LogError("Bad packet type id=%d, index=%d.", packet->packet_id, packet->global_packet_index); return -1; } } } } settings.numLoops--; seq.set_bookmark(startingPacket); trace_running = true; if (replayer != NULL) { replayer->ResetFrameNumber(); } } return err; }