//-----------------------------------------------------------------------------
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();
}
Beispiel #2
0
void vktraceviewer::onTraceFileLoaded(bool bSuccess, vktraceviewer_trace_file_info fileInfo, const QString& controllerFilename)
{
    QApplication::restoreOverrideCursor();

    if (fileInfo.packetCount == 0)
    {
        LogWarning("The trace file has 0 packets.");
    }
    else if (fileInfo.pPacketOffsets == NULL)
    {
        LogError("No packet offsets read from trace file.");
        bSuccess = false;
    }

    if (!bSuccess)
    {
        LogAlways("...FAILED!");
        QMessageBox::critical(this, tr("Error"), tr("Could not open trace file."));
        close_trace_file();

        if (m_bGeneratingTrace)
        {
            // if the user was generating a trace file, but the trace failed to load,
            // then re-spawn the generate trace dialog.
            prompt_generate_trace();
        }
    }
    else
    {
        m_traceFileInfo = fileInfo;

        setWindowTitle(QString(m_traceFileInfo.filename) + " - " + g_PROJECT_NAME);
        LogAlways("...success!");

        // update settings to reflect the currently open file
        g_settings.trace_file_to_open = vktrace_allocate_and_copy(m_traceFileInfo.filename);
        vktraceviewer_settings_updated();

#ifndef USE_STATIC_CONTROLLER_LIBRARY
        if (!controllerFilename.isEmpty())
        {
            m_pController = m_controllerFactory.Load(controllerFilename.toStdString().c_str());
        }
#else
        m_pController = vtvCreateQController();
#endif

        if (m_pController != NULL)
        {
            connect(m_pController, SIGNAL(OutputMessage(VktraceLogLevel, const QString&)), this, SLOT(OnOutputMessage(VktraceLogLevel, const QString&)));
            connect(m_pController, SIGNAL(OutputMessage(VktraceLogLevel, uint64_t, const QString&)), this, SLOT(OnOutputMessage(VktraceLogLevel, uint64_t, const QString&)));

            // Merge in settings from the controller.
            // This won't replace settings that may have already been loaded from disk.
            vktrace_SettingGroup_merge(m_pController->GetSettings(), &g_pAllSettings, &g_numAllSettings);

            // now update the controller with the loaded settings
            m_pController->UpdateFromSettings(g_pAllSettings, g_numAllSettings);

            //// trace file was loaded, now attempt to open additional session data
            //if (load_or_create_session(filename.c_str(), m_pTraceReader) == false)
            //{
            //    // failing to load session data is not critical, but may result in unexpected behavior at times.
            //    vktraceviewer_output_error("VkTraceViewer was unable to create a session folder to save viewing information. Functionality may be limited.");
            //}

            // Update the UI with the controller
            m_pController->LoadTraceFile(&m_traceFileInfo, this);
        }

        // update toolbar
        ui->searchTextBox->setEnabled(true);
        ui->searchPrevButton->setEnabled(true);
        ui->searchNextButton->setEnabled(true);

        ui->action_Close->setEnabled(true);
        ui->actionExport_API_Calls->setEnabled(true);

        ui->prevDrawcallButton->setEnabled(true);
        ui->nextDrawcallButton->setEnabled(true);

        // reset flag indicating that the ui may have been generating a trace file.
        m_bGeneratingTrace = false;

        GenerateTraceFileStats();
    }