コード例 #1
0
//-----------------------------------------------------------------------------
/// Return GPU-time in text format, to be parsed by the Client and displayed as its own timeline.
/// \return A line-delimited, ASCII-encoded, version of the GPU Trace data.
//-----------------------------------------------------------------------------
std::string VktTraceAnalyzerLayer::GetGPUTraceTXT()
{
    gtASCIIString appendString = "";

    VktFrameProfilerLayer* pProfilerLayer = VktFrameProfilerLayer::Instance();

    WaitAndFetchResults(pProfilerLayer);

    // During QueueSubmit we stored ProfilerResults in mEntriesWithProfilingResults. Form a response using it here.
    ProfilerResultsMap& profiledCmdBufResultsMap = pProfilerLayer->GetCmdBufProfilerResultsMap();

    // Gather all profiler results
    if (!profiledCmdBufResultsMap.empty())
    {
        std::vector<ProfilerResult*> flatResults;

        for (ProfilerResultsMap::iterator profIt = profiledCmdBufResultsMap.begin(); profIt != profiledCmdBufResultsMap.end(); ++profIt)
        {
            QueueWrapperToProfilingResultsMap& resultsPerThread = profIt->second;

            for (QueueWrapperToProfilingResultsMap::iterator queuesIt = resultsPerThread.begin();
                 queuesIt != resultsPerThread.end();
                 ++queuesIt)
            {
                // This structure holds all of the profiler results that were collected at QueueSubmit. The form is LinkId->ProfilerResult.
                const SampleIdToProfilerResultMap* pResults = queuesIt->second;

                for (SampleIdToProfilerResultMap::const_iterator sampleIdIt = pResults->begin();
                     sampleIdIt != pResults->end();
                     ++sampleIdIt)
                {
                    ProfilerResult* pResult = sampleIdIt->second;
                    pResult->measurementInfo.idInfo.pWrappedQueue = queuesIt->first;

                    flatResults.push_back(pResult);
                }
            }
        }

        const UINT numResults = (UINT)flatResults.size();

        // We'll need to insert the GPU Trace section header before the response data, even if there aren't any results.
        appendString += "//==GPU Trace==";
        appendString += "\n";

        appendString += "//API=";
        appendString += GetAPIString();
        appendString += "\n";

        appendString += "//CommandBufEventCount=";
        appendString += IntToString((INT)numResults);
        appendString += "\n";

#ifdef WIN32
        sort(flatResults.begin(), flatResults.end(), SortByStartTime);

        for (UINT i = 0; i < numResults; i++)
        {
            ProfilerResultToStr(flatResults[i], appendString);
        }
#else
        ProfilerResult* pFlatResults = new ProfilerResult[numResults];

        for (UINT i = 0; i < numResults; i++)
        {
            pFlatResults[i] = *(flatResults[i]);
        }

        qsort(pFlatResults, numResults, sizeof(ProfilerResult), (compfn)SortByStartTime);

        for (UINT i = 0; i < numResults; i++)
        {
            ProfilerResultToStr(&pFlatResults[i], appendString);
        }

        delete[] pFlatResults;
        pFlatResults = nullptr;
#endif
    }
    else
    {
        appendString += "NODATA";
    }

    return appendString.asCharArray();
}
コード例 #2
0
//-----------------------------------------------------------------------------
/// Return GPU-time in text format, to be parsed by the Client and displayed as its own timeline.
/// \return A line-delimited, ASCII-encoded, version of the GPU Trace data.
//-----------------------------------------------------------------------------
std::string VktTraceAnalyzerLayer::GetGPUTraceTXT()
{
    gtASCIIString appendString = "";

    VktFrameProfilerLayer* pProfilerLayer = VktFrameProfilerLayer::Instance();

    WaitAndFetchResults(pProfilerLayer);

    // Query the CPU clock frequency so we can accurately convert to wall clock time.
    GPS_TIMESTAMP cpuClockFrequency;
    QueryPerformanceFrequency(&cpuClockFrequency);

    // During QueueSubmit we stored ProfilerResults in mEntriesWithProfilingResults. Form a response using it here.
    ProfilerResultsMap& profiledCmdBufResultsMap = pProfilerLayer->GetCmdBufProfilerResultsMap();

    // During QueueSubmit we stored ProfilerResults in mEntriesWithProfilingResults. Form a response using it here.
    if (!profiledCmdBufResultsMap.empty())
    {
        // Keep a count of the number of lines that we'll write in the response string.
        UINT numResponseLines = 0;

        gtASCIIString profiledCommandsLinesStr;

        ProfilerResultsMap::iterator profIt;

        for (profIt = profiledCmdBufResultsMap.begin(); profIt != profiledCmdBufResultsMap.end(); ++profIt)
        {
            QueueWrapperToProfilingResultsMap::iterator queuesWithProfilingResults;

            QueueWrapperToProfilingResultsMap& resultsPerThread = profIt->second;

            for (queuesWithProfilingResults = resultsPerThread.begin(); queuesWithProfilingResults != resultsPerThread.end(); ++queuesWithProfilingResults)
            {
                VktWrappedQueue* pWrappedQueue = queuesWithProfilingResults->first;

                const double timestampFrequency = pWrappedQueue->GetTimestampFrequency();

                // This structure holds all of the profiler results that were collected at QueueSubmit. The form is LinkId->ProfilerResult.
                const SampleIdToProfilerResultMap* pQueueResults = queuesWithProfilingResults->second;

                SampleIdToProfilerResultMap::const_iterator queueResultsIterInner;

                for (queueResultsIterInner = pQueueResults->begin(); queueResultsIterInner != pQueueResults->end(); ++queueResultsIterInner)
                {
                    UINT64 sampleId = queueResultsIterInner->first;
                    const ProfilerResult* pResult = queueResultsIterInner->second;

                    // Convert timestamps to milliseconds by using the clock frequency.
#ifndef CODEXL_GRAPHICS
                    double preStartTimestamp = (pResult->timestampResult.rawClocks.preStart / timestampFrequency) * 1000.0;
#endif
                    double startTimestamp = (pResult->timestampResult.rawClocks.start / timestampFrequency) * 1000.0;
                    double endTimestamp = (pResult->timestampResult.rawClocks.end / timestampFrequency) * 1000.0;

                    FuncId funcId = (FuncId)pResult->measurementInfo.idInfo.funcId;

                    gtASCIIString funcName = GetFunctionNameFromId(funcId);
                    gtASCIIString retVal = "void";
                    gtASCIIString params = "";

                    if (pResult->measurementInfo.idInfo.funcId != FuncId_WholeCmdBuf)
                    {
                        VktAPIEntry* pResultEntry = pProfilerLayer->FindInvocationBySampleId(sampleId);

                        if (pResultEntry != nullptr)
                        {
                            // Convert the functionID and return values from integers into full strings that we can use in the response.
                            funcName = GetFunctionNameFromId(pResultEntry->mFunctionId);
                            retVal = (pResultEntry->m_returnValue != -1) ? VktUtil::WriteResultCodeEnumAsString(pResultEntry->m_returnValue) : "void";
                            params = pResultEntry->mParameters.asCharArray();
                        }
                    }

                    UINT queueIndex = pWrappedQueue->GetQueueIndex();

#ifndef CODEXL_GRAPHICS
                    std::string queueInfo = "";
#else
                    std::string queueInfo = "0";
#endif

                    // Vulkan Response line format:
                    // CommandQueuePtr CommandBufferType CommandBufferPtr APIType FuncId Vulkan_FuncName(Args) = ReturnValue StartTime EndTime SampleId

                    profiledCommandsLinesStr += "0x";
                    profiledCommandsLinesStr += IntToString(queueIndex);
                    profiledCommandsLinesStr += " ";

                    profiledCommandsLinesStr += queueInfo.c_str();
                    profiledCommandsLinesStr += " ";

                    profiledCommandsLinesStr += "0x";
                    profiledCommandsLinesStr += UINT64ToHexString((UINT64)pResult->measurementInfo.idInfo.pWrappedCmdBuf->AppHandle());
                    profiledCommandsLinesStr += " ";

                    profiledCommandsLinesStr += IntToString(VktTraceAnalyzerLayer::Instance()->GetAPIGroupFromAPI(funcId));
                    profiledCommandsLinesStr += " ";

                    profiledCommandsLinesStr += IntToString(funcId);
                    profiledCommandsLinesStr += " ";

                    profiledCommandsLinesStr += "Vulkan_";
                    profiledCommandsLinesStr += funcName;

                    profiledCommandsLinesStr += "(";
                    profiledCommandsLinesStr += params;
                    profiledCommandsLinesStr += ") = ";

                    profiledCommandsLinesStr += retVal;

#ifndef CODEXL_GRAPHICS
                    profiledCommandsLinesStr += " ";
                    profiledCommandsLinesStr += DoubleToString(preStartTimestamp);
#endif

                    profiledCommandsLinesStr += " ";
                    profiledCommandsLinesStr += DoubleToString(startTimestamp);

                    profiledCommandsLinesStr += " ";
                    profiledCommandsLinesStr += DoubleToString(endTimestamp);

                    profiledCommandsLinesStr += " ";
                    profiledCommandsLinesStr += UINT64ToString(pResult->measurementInfo.idInfo.sampleId);

                    profiledCommandsLinesStr += "\n";

                    // We just added another line to our response buffer. Increment the count that the client will read.
                    numResponseLines++;
                }
            }
        }

        // We'll need to insert the GPU Trace section header before the response data, even if there aren't any results.
        appendString += "//==GPU Trace==";
        appendString += "\n";

        appendString += "//CommandBufEventCount=";
        appendString += DWORDToString(numResponseLines);
        appendString += "\n";

        // Include the response lines after the section header.
        if (numResponseLines > 0)
        {
            appendString += profiledCommandsLinesStr;
        }
    }
    else
    {
        appendString += "NODATA";
    }

    return appendString.asCharArray();
}