void GPA_CounterGeneratorDX11Base::ComputeSWCounterValue(gpa_uint32 softwareCounterIndex,
                                                         gpa_uint64 value,
                                                         void* pResult,
                                                         const GPA_HWInfo* pHwInfo) const
{
    gpa_uint32 numAMDCounters = GetNumAMDCounters();

    if (softwareCounterIndex >= numAMDCounters)
    {
        softwareCounterIndex -= numAMDCounters;  //adjust index for AMD counters
    }

    const SwCounterDescVec* pSwCounters = SwCounterManager::Instance()->GetSwCounters();

    if (softwareCounterIndex < static_cast<gpa_uint32>(pSwCounters->size()))
    {
        const std::string nvGPUTime = "GPUTime";
        const std::string d3dGPUTime = "D3DGPUTime";
        const std::string counterName = pSwCounters->at(softwareCounterIndex).m_name;

        if (counterName == d3dGPUTime || counterName == nvGPUTime)
        {
            gpa_uint64 freq = 1u;
            GPA_ASSERT(pHwInfo->GetTimeStampFrequency(freq));
            gpa_float64* pBuf = static_cast<gpa_float64*>(pResult);
            *pBuf = static_cast<gpa_float64>(value) / static_cast<gpa_float64>(freq) * 1000.0;
        }
        else // other SW DX counters
        {
            GPA_Data_Type type = (*pSwCounters)[softwareCounterIndex].m_type;

            if (GPA_DATA_TYPE_UINT64 == type)
            {
                gpa_uint64* pBuf = static_cast<gpa_uint64*>(pResult);
                *pBuf = static_cast<gpa_uint64>(value);
            }
            else if (GPA_DATA_TYPE_FLOAT64 == type)
            {
                memcpy(pResult, &value, sizeof(gpa_float64));
            }
            else
            {
                GPA_LogError("Unexpected software counter type.");
            }
        }
    }
}
Example #2
0
bool VkUtils::GetTimestampFrequency(VkPhysicalDevice vkPhysicalDevice, gpa_uint64& timestampFrequency)
{
    bool success = false;

    if (s_isEntryPointsInitialized)
    {
        VkPhysicalDeviceProperties properties;
        _vkGetPhysicalDeviceProperties(vkPhysicalDevice, &properties);

        // Vulkan's timestampPeriod is expressed in nanoseconds per clock tick, convert to frequency in seconds
        float timestampPeriod = properties.limits.timestampPeriod;
        timestampFrequency    = static_cast<gpa_uint64>(1000000000.0f / (timestampPeriod));

        success = true;
    }
    else
    {
        GPA_LogError("Vulkan entrypoints are not initialized.");
    }

    return success;
}
Example #3
0
GPA_SessionId CLGPAContext::CreateSession(GPA_Session_Sample_Type sampleType)
{
    GPA_SessionId pRetSessionId = nullptr;

    CLGPASession* pNewGpaCLGpaSession = new(std::nothrow) CLGPASession(this, sampleType);

    if (nullptr == pNewGpaCLGpaSession)
    {
        GPA_LogError("Unable to allocate memory for the session.");
    }
    else
    {
        AddGpaSession(pNewGpaCLGpaSession);

        if (nullptr != pNewGpaCLGpaSession)
        {
            pRetSessionId = reinterpret_cast<GPA_SessionId>(GPAUniqueObjectManager::Instance()->CreateObject(pNewGpaCLGpaSession));
        }
    }

    return pRetSessionId;
}
Example #4
0
GPA_Status GPAImplementor::OpenContext(void* pContext,
                                       GPA_OpenContextFlags flags,
                                       GPA_ContextId* pContextId)
{
    // validate that only a single clock mode is specified
    unsigned int numClockModes = 0;

    if (GPA_OPENCONTEXT_CLOCK_MODE_NONE_BIT & flags)
    {
        numClockModes++;
    }

    if (GPA_OPENCONTEXT_CLOCK_MODE_PEAK_BIT & flags)
    {
        numClockModes++;
    }

    if (GPA_OPENCONTEXT_CLOCK_MODE_MIN_MEMORY_BIT & flags)
    {
        numClockModes++;
    }

    if (GPA_OPENCONTEXT_CLOCK_MODE_MIN_ENGINE_BIT & flags)
    {
        numClockModes++;
    }

    if (1 < numClockModes)
    {
        GPA_LogError("More than one clock mode specified.");
        return GPA_STATUS_ERROR_INVALID_PARAMETER;
    }

    GPA_Status gpaStatus = GPA_STATUS_OK;

    std::lock_guard<std::mutex> lock(m_deviceGpaContextMapMutex);

    if (!DoesContextInfoExist(pContext))
    {
        GPA_HWInfo hwInfo;

        if (GPA_STATUS_OK == IsDeviceSupported(pContext, &hwInfo))
        {
            IGPAContext* pNewGPAContext = nullptr;
            pNewGPAContext = OpenAPIContext(pContext, hwInfo, flags);

            if (nullptr != pNewGPAContext)
            {
                *pContextId = reinterpret_cast<GPA_ContextId>(GPAUniqueObjectManager::Instance()->CreateObject(pNewGPAContext));
                m_appContextInfoGpaContextMap.insert(GPADeviceIdentifierGPAContextPair(GetDeviceIdentifierFromContextInfo(pContext), pNewGPAContext));
            }
            else
            {
                GPA_LogError("Failed to open API-specific GPA Context.");
                gpaStatus = GPA_STATUS_ERROR_FAILED;
            }
        }
        else
        {
            GPA_LogError("Device not supported.");
            gpaStatus = GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED;
        }
    }
    else
    {
        GPA_LogError("Context is already open.");
        gpaStatus = GPA_STATUS_ERROR_CONTEXT_ALREADY_OPEN;
    }

    return gpaStatus;
}
Example #5
0
GPA_Status GPAImplementor::IsDeviceSupported(GPAContextInfoPtr pContextInfo, GPA_HWInfo* pHwInfo) const
{
    bool foundMatchingHWInfo = false;
    AsicInfoList asicInfoList;
    GPA_HWInfo apiHwInfo;

    if (!GetHwInfoFromAPI(pContextInfo, apiHwInfo))
    {
        GPA_LogError("Unable to get hardware information from the API.");
        return GPA_STATUS_ERROR_FAILED;
    }

    if (apiHwInfo.IsAMD())
    {
        AMDTADLUtils::Instance()->GetAsicInfoList(asicInfoList);
        GPA_HWInfo asicHwInfo;

        // make sure there are available asics for AMD card.
        // In case there is no AMD driver, we output a message.
        if (asicInfoList.empty())
        {
            GPA_LogMessage("Cannot get asicInfoList from ADL.");
        }

        for (auto asicInfo : asicInfoList)
        {
            asicHwInfo.SetVendorID(asicInfo.vendorID);
            asicHwInfo.SetDeviceName(asicInfo.adapterName.c_str());
            asicHwInfo.SetDeviceID(asicInfo.deviceID);
            asicHwInfo.SetRevisionID(asicInfo.revID);
            asicHwInfo.SetGpuIndex(asicInfo.gpuIndex);
            asicHwInfo.UpdateDeviceInfoBasedOnDeviceID();

            if (CompareHwInfo(apiHwInfo, asicHwInfo))
            {
                gpa_uint32 apiRevId = 0;

                // make sure revision id is set correctly based on the actual hardware
                if (apiHwInfo.GetRevisionID(apiRevId) && REVISION_ID_ANY == apiRevId)
                {
                    apiHwInfo.SetRevisionID(asicInfo.revID);
                }

                apiHwInfo.UpdateDeviceInfoBasedOnDeviceID();

                // this device matches what the application is running on, so break from the loop.
                foundMatchingHWInfo = true;
                break;
            }
        }
    }

#if defined(WIN32)

    if (!foundMatchingHWInfo) // ADL will not be available on a clean system that has never had the AMD driver installed
    {
        Adapter adapter;
        asicInfoList.clear();

        if (adapter.getAsicInfoList(asicInfoList))
        {
            for (auto asicInfo : asicInfoList)
            {
                GPA_HWInfo asicHwInfo;
                asicHwInfo.SetVendorID(asicInfo.vendorID);
                asicHwInfo.SetDeviceName(asicInfo.adapterName.c_str());
                asicHwInfo.SetDeviceID(asicInfo.deviceID);
                asicHwInfo.SetRevisionID(asicInfo.revID);

                if (NVIDIA_VENDOR_ID == asicInfo.vendorID)
                {
                    asicHwInfo.SetHWGeneration(GDT_HW_GENERATION_NVIDIA);
                }
                else if (INTEL_VENDOR_ID == asicInfo.vendorID)
                {
                    asicHwInfo.SetHWGeneration(GDT_HW_GENERATION_INTEL);
                }
                else
                {
                    // this call makes sure the hw generation is set correctly
                    asicHwInfo.UpdateDeviceInfoBasedOnDeviceID();
                }

                if (CompareHwInfo(apiHwInfo, asicHwInfo))
                {
                    gpa_uint32 apiRevId = 0;

                    // make sure revision id is set correctly based on the actual hardware
                    if (apiHwInfo.GetRevisionID(apiRevId) && REVISION_ID_ANY == apiRevId)
                    {
                        apiHwInfo.SetRevisionID(asicInfo.revID);
                    }

                    apiHwInfo.UpdateDeviceInfoBasedOnDeviceID();

                    // this device matches what the application is running on, so break from the loop.
                    foundMatchingHWInfo = true;
                    break;
                }
            }
        }
        else
        {
            GPA_LogMessage("Unable to get asic info from the Adapter.");
        }
    }

#endif // WIN32

    if (!foundMatchingHWInfo)
    {
        // This code path is for systems where ADL is not available. ADL is not available on ROCm systems as well as on amdgpu systems.
        // API specific hardware information mostly gets basic information (namely just needs to get VendorID and DeviceID), so we need to update
        // the device info with additional information that we store per-deviceID.
        bool deviceInfoOk = apiHwInfo.UpdateDeviceInfoBasedOnDeviceID();

        if (!deviceInfoOk)
        {
            // If this fails, then the hardware must not be supported because we don't know enough about it
            GPA_LogError("Cannot update device information.");
            return GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED;
        }
    }

    // Give the API-specific implementation a chance to verify that the hardware is supported.
    GPA_Status status = VerifyAPIHwSupport(pContextInfo, apiHwInfo) ? GPA_STATUS_OK : GPA_STATUS_ERROR_FAILED;

    if (GPA_STATUS_OK == status)
    {
        *pHwInfo = apiHwInfo;
    }

    return status;
}
Example #6
0
GPASampleResult* DX12GPASample::PopulateSampleResult()
{
    size_t sampleDataBytes = 0u;

    // Validate result space
    sampleDataBytes = GetSampleResultLocation()->GetBufferBytes();

    if (0 != sampleDataBytes)
    {
        if (nullptr != GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer())
        {
            gpa_uint64* pResultBuffer = nullptr;
            gpa_uint64 timingData[2] = {};

            if (GetPass()->IsTimingPass())
            {
                pResultBuffer = timingData;
                sampleDataBytes = sizeof(timingData);
            }
            else
            {
                pResultBuffer = GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer();
            }

            if (CopyResult(sampleDataBytes, pResultBuffer))
            {
                if (GetPass()->IsTimingPass())
                {
                    const GPA_HardwareCounters* pHardwareCounters = GetPass()->GetSessionContextCounterAccessor()->GetHardwareCounters();

                    for (CounterCount i = 0; i < GetPass()->GetEnabledCounterCount(); ++i)
                    {
                        CounterIndex counterIndex;
                        GetPass()->GetCounterByIndexInPass(i, &counterIndex);

                        if (counterIndex == pHardwareCounters->m_gpuTimeBottomToBottomDurationCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[1] - timingData[0];
                        }
                        else if (counterIndex == pHardwareCounters->m_gpuTimeBottomToBottomStartCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[0];
                        }
                        else if (counterIndex == pHardwareCounters->m_gpuTimeBottomToBottomEndCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[1];
                        }
                        else if (counterIndex == pHardwareCounters->m_gpuTimeTopToBottomDurationCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[1] - timingData[0];
                        }
                        else if (counterIndex == pHardwareCounters->m_gpuTimeTopToBottomStartCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[0];
                        }
                        else if (counterIndex == pHardwareCounters->m_gpuTimeTopToBottomEndCounterIndex)
                        {
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = timingData[1];
                        }
                        else
                        {
                            GPA_LogError("Unknown timing counter.");
                            GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[i] = 0;
                        }
                    }
                }

                if (IsSampleContinuing())
                {
                    GPASampleResult* pSampleResult = reinterpret_cast<DX12GPASample*>(GetContinuingSample())->PopulateSampleResult();

                    for (size_t counterIter = 0; counterIter < GetPass()->GetEnabledCounterCount(); counterIter++)
                    {
                        GetSampleResultLocation()->GetAsCounterSampleResult()->GetResultBuffer()[counterIter] += pSampleResult->GetAsCounterSampleResult()->GetResultBuffer()[counterIter];
                    }
                }

                MarkAsCompleted();
            }
            else
            {
                GPA_LogError("Unable to get the result from the driver.");
            }
        }
        else
        {
            GPA_LogError("Incorrect space allocated for sample result.");
        }
    }

    return GetSampleResultLocation();
}
Example #7
0
bool DX12GPASample::CopyResult(size_t sampleDataSize, void* pResultBuffer) const
{
    bool isDataReady = false;
    bool isAnyHardwareCounterEnabled = GetPass()->GetEnabledCounterCount() > 0;

    if (nullptr != pResultBuffer)
    {
        if (isAnyHardwareCounterEnabled)
        {
            DX12GPACommandList* pDX12GpaCmdList = reinterpret_cast<DX12GPACommandList*>(GetCmdList());

            IAmdExtGpaSession* pResultSession = nullptr;

            if (IsCopied())
            {
                pResultSession = pDX12GpaCmdList->GetBundleResultAmdExtSession(GetClientSampleId());
            }
            else
            {
                pResultSession = pDX12GpaCmdList->GetAmdExtSession();
            }

            if (nullptr == pResultSession)
            {
                GPA_LogError("Invalid profiling session encountered while copying results.");
            }
            else
            {
                if (pResultSession->IsReady())
                {
                    size_t sampleDataSizeInDriver = 0u;
                    HRESULT driverResult = pResultSession->GetResults(GetDriverSampleId(), &sampleDataSizeInDriver, nullptr);
                    assert(SUCCEEDED(driverResult));
                    assert(sampleDataSize == sampleDataSizeInDriver);

                    if (SUCCEEDED(driverResult) && sampleDataSize == sampleDataSizeInDriver)
                    {
                        driverResult = pResultSession->GetResults(GetDriverSampleId(), &sampleDataSizeInDriver, pResultBuffer);
                        assert(SUCCEEDED(driverResult));

                        if (SUCCEEDED(driverResult))
                        {
                            isDataReady = true;
                        }
                        else
                        {
                            GPA_LogError("Error occurred while getting sample results from driver.");
                        }
                    }
                    else
                    {
                        GPA_LogError("Error occurred while getting sample result size from driver.");
                    }
                }
            }
        }
        else
        {
            // there is no hardware counter enabled in the driver, put zeros in all result location
            memcpy(pResultBuffer, 0, sampleDataSize);
            isDataReady = true;
        }
    }

    return isDataReady;
}
Example #8
0
//=========================================================================================================
bool GetASICInfo(ASICInfo& rASICInfo)
{
    if (nullptr == oglUtils::_oglGetPerfMonitorCountersAMD      ||
        nullptr == oglUtils::_oglGetPerfMonitorGroupStringAMD   ||
        nullptr == oglUtils::_oglGetPerfMonitorCounterInfoAMD   ||
        nullptr == oglUtils::_oglGetPerfMonitorCounterStringAMD ||
        nullptr == oglUtils::_oglGenPerfMonitorsAMD             ||
        nullptr == oglUtils::_oglDeletePerfMonitorsAMD          ||
        nullptr == oglUtils::_oglSelectPerfMonitorCountersAMD   ||
        nullptr == oglUtils::_oglBeginPerfMonitorAMD            ||
        nullptr == oglUtils::_oglEndPerfMonitorAMD              ||
        nullptr == oglUtils::_oglGetPerfMonitorCounterDataAMD)
    {
        // No AMD_peformance_monitor support, means no ASIC info
        GPA_LogError("One or more of the GL_AMD_performance_monitor functions were not found.");
        return false;
    }

    // Find the ASIC info group (GPIN = GPu INformation)
    GLint nASICGroupId = GetGroupID(ASIC_GROUP);

    if (nASICGroupId == -1)
    {
        GPA_LogError("Unable to find the GPIN group.");
        return false;
    }

    // Get the ASIC ID
    GLuint nAsicType = 0;

    if (!GetCounterValue(nASICGroupId, ASIC_TYPE, nAsicType))
    {
        GPA_LogError("Unable to get the asic id.");
        return false;
    }

    // query the driver version so that we can correct the asic ID after a driver
    // change that happened for 10.2, where support for pre-R6xx hardware was removed
    //(legacy driver will support that)

#ifndef GLES
    // Since GL ES didn't exist before version 9551, there's no need to check the
    // version number. For now, it is assumed the version number will be >9551

    const GLubyte* pVersion = oglUtils::_oglGetString(GL_VERSION);
    int nVersion = extractVersionNumber(pVersion);

    std::stringstream message;
    message << "ASIC ID returned from driver is: " << nAsicType << " and GL_VERSION is: " << reinterpret_cast<const char*>(pVersion) << ".";
    GPA_LogMessage(message.str().c_str());
#else
    int nVersion = INT_MAX;
#endif

    if (nVersion < 13452)
    {
        // pre-GCN devices were removed from the driver starting with version 13452.
        // if the driver version is earlier than that we will return an error.
        GPA_LogError("OpenGL driver version is too old. Please update your driver.");
        return false;
    }

    // store the Asic Revision ID
    rASICInfo.eAsicRev = (ATIAsicID) nAsicType;

    // Decode the ASIC Type
    if (nAsicType == ATIASIC_ID_TAHITI_P ||
        nAsicType == ATIASIC_ID_PITCAIRN_PM ||
        nAsicType == ATIASIC_ID_CAPEVERDE_M ||
        nAsicType == ATIASIC_ID_OLAND_M ||
        nAsicType == ATIASIC_ID_HAINAN_M)
    {
        GPA_LogMessage("Recognized a GFX6 card.");
        rASICInfo.eAsicType = ASIC_Gfx6;
    }
    else if (nAsicType == ATIASIC_ID_BONAIRE_M ||
             nAsicType == ATIASIC_ID_HAWAII_P)
    {
        GPA_LogMessage("Recognized a GFX7 card.");
        rASICInfo.eAsicType = ASIC_Gfx7;
    }
    else if (nAsicType == ATIASIC_ID_KALINDI ||
             nAsicType == ATIASIC_ID_GODAVARI ||
             nAsicType == ATIASIC_ID_SPECTRE ||
             nAsicType == ATIASIC_ID_SPOOKY)
    {
        GPA_LogMessage("Recognized an APU with GFX7 graphics.");
        rASICInfo.eAsicType = ASIC_Gfx7;
    }
    else if (nAsicType == ATIASIC_ID_ICELAND_M ||
             nAsicType == ATIASIC_ID_TONGA_P ||
             nAsicType == ATIASIC_ID_FIJI_P ||
             nAsicType == ATIASIC_ID_ELLESMERE ||
             nAsicType == ATIASIC_ID_BAFFIN ||
             nAsicType == ATIASIC_ID_LEXA ||
             nAsicType == ATIASIC_ID_VEGAM)
    {
        GPA_LogMessage("Recognized a GFX8 card.");
        rASICInfo.eAsicType = ASIC_Gfx8;
    }
    else if (nAsicType == ATIASIC_ID_CARRIZO ||
             nAsicType == ATIASIC_ID_STONEY)
    {
        GPA_LogMessage("Recognized an APU with GFX8 graphics.");
        rASICInfo.eAsicType = ASIC_Gfx8;
    }
    else if (nAsicType == ATIASIC_ID_GFX900 ||
             nAsicType == ATIASIC_ID_PLACEHOLDER1 ||
             nAsicType == ATIASIC_ID_GFX906)
    {
        GPA_LogMessage("Recognized a GFX9 card.");
        rASICInfo.eAsicType = ASIC_Gfx9;
    }
    else if (nAsicType == ATIASIC_ID_GFX902 ||
             nAsicType == ATIASIC_ID_PLACEHOLDER)
    {
        GPA_LogMessage("Recognized an APU with GFX9 graphics.");
        rASICInfo.eAsicType = ASIC_Gfx9;
    }
    else
    {
        std::stringstream errorMessage;
        errorMessage << "Unrecognized asic type: " << nAsicType << ".";
        GPA_LogError(errorMessage.str().c_str());
        assert(0); // Unknown ASIC Type, need to update enums list from UGL driver
        rASICInfo.eAsicType = ASIC_UNKNOWN;
        return false;
    }

    // Now, fill in the rest of the ASIC structure
    switch (rASICInfo.eAsicType)
    {
        case ASIC_Gfx6:
        case ASIC_Gfx7:
        case ASIC_Gfx8:
        case ASIC_Gfx9:
            if (!GetCounterValue(nASICGroupId, "GPIN_001", rASICInfo.nNumSIMD))
            {
                GPA_LogError("Unable to query GPIN_001.");
                return false;
            }

            if (!GetCounterValue(nASICGroupId, "GPIN_002", rASICInfo.nNumQuadPipe))
            {
                GPA_LogError("Unable to query GPIN_002.");
                return false;
            }

            if (!GetCounterValue(nASICGroupId, "GPIN_003", rASICInfo.nNumRB))
            {
                GPA_LogError("Unable to query GPIN_003.");
                return false;
            }

            if (!GetCounterValue(nASICGroupId, "GPIN_004", rASICInfo.nNumSPI))
            {
                GPA_LogError("Unable to query GPIN_004.");
                return false;
            }

            break;

        default:
            break;
    }

    return true;
}
GPA_Status GPA_CounterGeneratorDX12::GenerateHardwareCounters(
    GDT_HW_GENERATION desiredGeneration,
    GDT_HW_ASIC_TYPE asicType,
    gpa_uint8 generateAsicSpecificCounters,
    GPA_HardwareCounters* pHardwareCounters)
{
    UNREFERENCED_PARAMETER(asicType);
    UNREFERENCED_PARAMETER(generateAsicSpecificCounters);

    GPA_Status status = GPA_STATUS_OK;

    if (nullptr == pHardwareCounters)
    {
        status = GPA_STATUS_ERROR_NULL_POINTER;
    }
    else
    {
        pHardwareCounters->Clear();

        if (true == pHardwareCounters->m_countersGenerated) //only generate counters once to improve performance
        {
            return GPA_STATUS_OK;
        }

        pHardwareCounters->Clear();

        if (desiredGeneration == GDT_HW_GENERATION_SEAISLAND)
        {
            pHardwareCounters->m_ppCounterGroupArray = DX12CounterGroupArrayGfx7;
            pHardwareCounters->m_pGroups = HWDX12GroupsGfx7;
            pHardwareCounters->m_groupCount = HWDX12GroupCountGfx7;
            pHardwareCounters->m_pSQCounterGroups = HWDX12SQGroupsGfx7;
            pHardwareCounters->m_sqGroupCount = HWDX12SQGroupCountGfx7;
            pHardwareCounters->m_timestampBlockIds = HWDX12TimestampBlockIdsGfx7;
            pHardwareCounters->m_timeCounterIndices = HWDX12TimeCounterIndicesGfx7;
            pHardwareCounters->m_gpuTimeBottomToBottomDurationCounterIndex = HWDX12GputimeBottomToBottomDurationIndexGfx7;
            pHardwareCounters->m_gpuTimeBottomToBottomStartCounterIndex = HWDX12GputimeBottomToBottomStartIndexGfx7;
            pHardwareCounters->m_gpuTimeBottomToBottomEndCounterIndex = HWDX12GputimeBottomToBottomEndIndexGfx7;
            pHardwareCounters->m_gpuTimeTopToBottomDurationCounterIndex = HWDX12GputimeTopToBottomDurationIndexGfx7;
            pHardwareCounters->m_gpuTimeTopToBottomStartCounterIndex = HWDX12GputimeTopToBottomStartIndexGfx7;
            pHardwareCounters->m_gpuTimeTopToBottomEndCounterIndex = HWDX12GputimeTopToBottomEndIndexGfx7;
            pHardwareCounters->m_pIsolatedGroups = HWDX12SQIsolatedGroupsGfx7;
            pHardwareCounters->m_isolatedGroupCount = HWDX12SQIsolatedGroupCountGfx7;
        }
        else if (desiredGeneration == GDT_HW_GENERATION_VOLCANICISLAND)
        {
            pHardwareCounters->m_ppCounterGroupArray = DX12CounterGroupArrayGfx8;
            pHardwareCounters->m_pGroups = HWDX12GroupsGfx8;
            pHardwareCounters->m_groupCount = HWDX12GroupCountGfx8;
            pHardwareCounters->m_pSQCounterGroups = HWDX12SQGroupsGfx8;
            pHardwareCounters->m_sqGroupCount = HWDX12SQGroupCountGfx8;
            pHardwareCounters->m_timestampBlockIds = HWDX12TimestampBlockIdsGfx8;
            pHardwareCounters->m_timeCounterIndices = HWDX12TimeCounterIndicesGfx8;
            pHardwareCounters->m_gpuTimeBottomToBottomDurationCounterIndex = HWDX12GputimeBottomToBottomDurationIndexGfx8;
            pHardwareCounters->m_gpuTimeBottomToBottomStartCounterIndex = HWDX12GputimeBottomToBottomStartIndexGfx8;
            pHardwareCounters->m_gpuTimeBottomToBottomEndCounterIndex = HWDX12GputimeBottomToBottomEndIndexGfx8;
            pHardwareCounters->m_gpuTimeTopToBottomDurationCounterIndex = HWDX12GputimeTopToBottomDurationIndexGfx8;
            pHardwareCounters->m_gpuTimeTopToBottomStartCounterIndex = HWDX12GputimeTopToBottomStartIndexGfx8;
            pHardwareCounters->m_gpuTimeTopToBottomEndCounterIndex = HWDX12GputimeTopToBottomEndIndexGfx8;
            pHardwareCounters->m_pIsolatedGroups = HWDX12SQIsolatedGroupsGfx8;
            pHardwareCounters->m_isolatedGroupCount = HWDX12SQIsolatedGroupCountGfx8;
        }
        else if (desiredGeneration == GDT_HW_GENERATION_GFX9)
        {
            pHardwareCounters->m_ppCounterGroupArray = DX12CounterGroupArrayGfx9;
            pHardwareCounters->m_pGroups = HWDX12GroupsGfx9;
            pHardwareCounters->m_groupCount = HWDX12GroupCountGfx9;
            pHardwareCounters->m_pSQCounterGroups = HWDX12SQGroupsGfx9;
            pHardwareCounters->m_sqGroupCount = HWDX12SQGroupCountGfx9;
            pHardwareCounters->m_timestampBlockIds = HWDX12TimestampBlockIdsGfx9;
            pHardwareCounters->m_timeCounterIndices = HWDX12TimeCounterIndicesGfx9;
            pHardwareCounters->m_gpuTimeBottomToBottomDurationCounterIndex = HWDX12GputimeBottomToBottomDurationIndexGfx9;
            pHardwareCounters->m_gpuTimeBottomToBottomStartCounterIndex = HWDX12GputimeBottomToBottomStartIndexGfx9;
            pHardwareCounters->m_gpuTimeBottomToBottomEndCounterIndex = HWDX12GputimeBottomToBottomEndIndexGfx9;
            pHardwareCounters->m_gpuTimeTopToBottomDurationCounterIndex = HWDX12GputimeTopToBottomDurationIndexGfx9;
            pHardwareCounters->m_gpuTimeTopToBottomStartCounterIndex = HWDX12GputimeTopToBottomStartIndexGfx9;
            pHardwareCounters->m_gpuTimeTopToBottomEndCounterIndex = HWDX12GputimeTopToBottomEndIndexGfx9;
            pHardwareCounters->m_pIsolatedGroups = HWDX12SQIsolatedGroupsGfx9;
            pHardwareCounters->m_isolatedGroupCount = HWDX12SQIsolatedGroupCountGfx9;
        }
        else
        {
            GPA_LogError("Unrecognized or unhandled hardware generation.");
            return GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED;
        }
    }

    // need to count total number of internal counters, since split into groups
    if (!pHardwareCounters->m_countersGenerated)
    {
        if (!GenerateInternalCounters(pHardwareCounters, desiredGeneration))
        {
            GPA_LogError("Unable to generate internal counters.");
            pHardwareCounters->m_currentGroupUsedCounts.resize(0);
            return GPA_STATUS_ERROR_CONTEXT_NOT_OPEN;
        }
    }

    unsigned int uGroupCount = pHardwareCounters->m_groupCount;
    pHardwareCounters->m_currentGroupUsedCounts.resize(uGroupCount);

    return status;
}
Example #10
0
GPA_Status GPA_IMP_OpenContext(void* pContext)
{
    GPA_Status result = GPA_STATUS_OK;

    if (nullptr == pContext)
    {
        GPA_LogError("Unable to open context. Parameter 'pContext' is NULL.");
        result = GPA_STATUS_ERROR_NULL_POINTER;
    }
    else
    {
        IUnknown* pUnknown = static_cast<IUnknown*>(pContext);

        ID3D12GraphicsCommandList* pCommandList = nullptr;
        HRESULT hr = pUnknown->QueryInterface(__uuidof(ID3D12GraphicsCommandList), reinterpret_cast<void**>(&pCommandList));

        if (S_OK != hr)
        {
            GPA_LogError("Failed to get command list from context");
            result = GPA_STATUS_ERROR_FAILED;
        }
        else
        {
            bool setCommandList = GetCurrentContext()->SetCommandList(pCommandList);

            if (!setCommandList)
            {
                result = GPA_STATUS_ERROR_FAILED;
            }

            if (GPA_STATUS_OK == result)
            {
                gpa_uint32 vendorId = 0;
                gpa_uint32 deviceId = 0;
                gpa_uint32 revisionId = 0;

                if (false == (g_pCurrentContext->m_hwInfo.GetVendorID(vendorId)))
                {
                    result = GPA_STATUS_ERROR_FAILED;
                }
                else if (false == (g_pCurrentContext->m_hwInfo.GetDeviceID(deviceId)))
                {
                    result = GPA_STATUS_ERROR_FAILED;
                }
                else if (false == (g_pCurrentContext->m_hwInfo.GetRevisionID(revisionId)))
                {
                    result = GPA_STATUS_ERROR_FAILED;
                }

                if (GPA_STATUS_OK == result)
                {
                    GPA_ICounterAccessor* pCounterAccessor = nullptr;
                    GPA_ICounterScheduler* pCounterScheduler = nullptr;
                    result = GenerateCounters(
                                 GPA_API_DIRECTX_12,
                                 vendorId,
                                 deviceId,
                                 revisionId,
                                 &pCounterAccessor,
                                 &pCounterScheduler);

                    if (GPA_STATUS_OK == result)
                    {
                        g_pCurrentContext->m_pCounterAccessor =
                            static_cast<GPA_CounterGeneratorBase*>(pCounterAccessor);
                        g_pCurrentContext->m_pCounterScheduler = pCounterScheduler;
                    }
                }
            }

            pCommandList->Release();
        }
    }

    return result;
} // end of GPA_IMP_OpenContext
Example #11
0
GPA_Status GPA_IMP_GetHWInfo(void* pContext, GPA_HWInfo* pHwInfo)
{
    GPA_Status result = GPA_STATUS_OK;

    if (nullptr == pContext)
    {
        GPA_LogError("Parameter 'pContext' is NULL.");
        result = GPA_STATUS_ERROR_NULL_POINTER;
    }
    else if (nullptr == pHwInfo)
    {
        GPA_LogError("Parameter 'pHwInfo' is NULL.");
        result = GPA_STATUS_ERROR_NULL_POINTER;
    }
    else
    {
        IUnknown* pUnknown = static_cast<IUnknown*>(pContext);

        ID3D12GraphicsCommandList* pCommandList = nullptr;
        HRESULT hr = pUnknown->QueryInterface(__uuidof(ID3D12GraphicsCommandList), reinterpret_cast<void**>(&pCommandList));

        if (S_OK != hr)
        {
            GPA_LogError("Failed to get command list from context");
            result = GPA_STATUS_ERROR_FAILED;
        }
        else
        {
            ID3D12Device* pDevice;
            hr = pCommandList->GetDevice(__uuidof(ID3D12Device), reinterpret_cast<void**>(&pDevice));

            if (S_OK != hr)
            {
                GPA_LogError("Failed to get device from command list");
                result = GPA_STATUS_ERROR_FAILED;
            }
            else
            {
                DXGI_ADAPTER_DESC adapterDesc;
                result = DX12GetAdapterDesc(pDevice, adapterDesc);

                if (GPA_STATUS_OK != result)
                {
                    GPA_LogError("Could not get adapter description, hardware cannot be supported.");
                    result = GPA_STATUS_ERROR_FAILED;
                }
                else
                {
                    //get Time stamp frequency
                    gpa_uint64 freq = 0ull;

                    if (nullptr == g_pCurrentContext)
                    {
                        GPA_LogError("g_pCurrentContext is NULL.");
                        result = GPA_STATUS_ERROR_NULL_POINTER;
                        return result;
                    }

                    GetCurrentContext()->SetCommandList(pCommandList);
                    result = GetCurrentContext()->GetTimestampFrequency(freq);

                    if (GPA_STATUS_OK != result)
                    {
                        GPA_LogError("GetTimestampFrequency() failed.");
                    }
                    else
                    {

                        // For now it is assumed that DX12 MGPU support is exposed to the app
                        // and the app always opens the device on the correct GPU.
                        // In case where MGPU support hides the GPU from the app, then
                        // we will need to use DX12 MGPU extension (and possibly ADL util)
                        // to get the correct HW info
                        pHwInfo->SetVendorID(adapterDesc.VendorId);

                        // TODO: To enable running on WARP driver, fake a Bonaire HW ID if the device is the WARP device
                        if (0x8c == adapterDesc.DeviceId && AMD_VENDOR_ID == adapterDesc.VendorId)
                        {
                            pHwInfo->SetDeviceID(0x665C);
                            pHwInfo->SetRevisionID(0);
                        }
                        else
                        {
                            pHwInfo->SetVendorID(adapterDesc.VendorId);
                            pHwInfo->SetDeviceID(adapterDesc.DeviceId);
                            pHwInfo->SetRevisionID(adapterDesc.Revision);
                        }

                        std::wstring adapterNameW(adapterDesc.Description);
                        std::string adapterName(adapterNameW.begin(), adapterNameW.end());
                        pHwInfo->SetDeviceName(adapterName.c_str());
                        GDT_HW_GENERATION hwGen = GDT_HW_GENERATION_NONE;

                        if (NVIDIA_VENDOR_ID == adapterDesc.VendorId)
                        {
                            hwGen = GDT_HW_GENERATION_NVIDIA;
                        }
                        else if (INTEL_VENDOR_ID == adapterDesc.VendorId)
                        {
                            hwGen = GDT_HW_GENERATION_INTEL;
                        }

                        else if (AMD_VENDOR_ID == adapterDesc.VendorId)
                        {
                            AMDTDeviceInfoUtils::Instance()->GetHardwareGeneration(adapterDesc.DeviceId, hwGen);
                        }

                        pHwInfo->SetHWGeneration(hwGen);
                        pHwInfo->SetTimeStampFrequency(freq);
                    }

                }

                pDevice->Release();
            }

            pCommandList->Release();
        }
    }

    return result;
}
Example #12
0
GPA_Status GPA_IMP_VerifyHWSupport(void* pContext, GPA_HWInfo* pHwInfo)
{
    GPA_Status result = GPA_STATUS_OK;

    if ((nullptr == pContext) || (nullptr == pHwInfo))
    {
        result = GPA_STATUS_ERROR_FAILED;
    }
    else
    {
        IUnknown* pUnknown = static_cast<IUnknown*>(pContext);

        ID3D12GraphicsCommandList* pCommandList = nullptr;
        HRESULT hr = pUnknown->QueryInterface(__uuidof(ID3D12GraphicsCommandList), reinterpret_cast<void**>(&pCommandList));

        if (S_OK != hr)
        {
            GPA_LogError("Failed to get command list from context");
            result = GPA_STATUS_ERROR_FAILED;
        }
        else
        {
            ID3D12Device* pDevice;
            hr = pCommandList->GetDevice(__uuidof(ID3D12Device), reinterpret_cast<void**>(&pDevice));

            if (S_OK != hr)
            {
                GPA_LogError("Failed to get D3D12 device");
                result = GPA_STATUS_ERROR_FAILED;
            }
            else
            {
                D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevels;
                static const D3D_FEATURE_LEVEL requestedFeatureLevels[] =
                {
                    D3D_FEATURE_LEVEL_11_0,
                    D3D_FEATURE_LEVEL_11_1,
                };
                featureLevels.NumFeatureLevels =
                    (sizeof(requestedFeatureLevels) / sizeof(D3D_FEATURE_LEVEL));
                featureLevels.pFeatureLevelsRequested = requestedFeatureLevels;
                featureLevels.MaxSupportedFeatureLevel = D3D_FEATURE_LEVEL_11_1;
                hr = pDevice->CheckFeatureSupport(
                         D3D12_FEATURE_FEATURE_LEVELS, &featureLevels, sizeof(featureLevels));

                if (S_OK != hr)
                {
                    GPA_LogError("Failed to get D3D12 device feature levels");
                    result = GPA_STATUS_ERROR_FAILED;
                }
                else
                {
                    if (D3D_FEATURE_LEVEL_11_0 > featureLevels.MaxSupportedFeatureLevel)
                    {
                        result = GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED;
                    }
                    else
                    {
                        // TODO Once DX12 performance extension is available, check
                        //      it's possible to create a HW counter
                    }
                }

                pDevice->Release();
            }

            pCommandList->Release();
        }
    }

    return result;
} // end of GPA_IMP_VerifyHwSupport
Example #13
0
bool DX12GPAImplementor::GetHwInfoFromAPI(const GPAContextInfoPtr pContextInfo, GPA_HWInfo& hwInfo) const
{
    bool success = false;

    IUnknown* pUnknownPtr = static_cast<IUnknown*>(pContextInfo);
    ID3D12Device* pD3D12Device;

    if (DX12Utils::GetD3D12Device(pUnknownPtr, &pD3D12Device) && DX12Utils::IsFeatureLevelSupported(pD3D12Device))
    {
        DXGI_ADAPTER_DESC adapterDesc;
        GPA_Status result = DX12Utils::DX12GetAdapterDesc(pD3D12Device, adapterDesc);

        if (GPA_STATUS_OK == result)
        {
            // For now it is assumed that DX12 MGPU support is exposed to the app
            // and the app always opens the device on the correct GPU.
            // In case where MGPU support hides the GPU from the app, then
            // we will need to use DX12 MGPU extension (and possibly ADL util)
            // to get the correct HW info
            hwInfo.SetVendorID(adapterDesc.VendorId);
            hwInfo.SetDeviceID(adapterDesc.DeviceId);
            hwInfo.SetRevisionID(adapterDesc.Revision);
            std::wstring adapterNameW(adapterDesc.Description);
            std::string adapterName(adapterNameW.begin(), adapterNameW.end());
            hwInfo.SetDeviceName(adapterName.c_str());
            GDT_HW_GENERATION hwGen = GDT_HW_GENERATION_NONE;

            if (NVIDIA_VENDOR_ID == adapterDesc.VendorId)
            {
                hwGen = GDT_HW_GENERATION_NVIDIA;
            }
            else if (INTEL_VENDOR_ID == adapterDesc.VendorId)
            {
                hwGen = GDT_HW_GENERATION_INTEL;
            }
            else if (AMD_VENDOR_ID == adapterDesc.VendorId)
            {
                GDT_GfxCardInfo cardInfo;

                if (AMDTDeviceInfoUtils::Instance()->GetDeviceInfo(adapterDesc.DeviceId, adapterDesc.Revision, cardInfo))
                {
                    hwGen = cardInfo.m_generation;

                    // GPA DX12 requires GFX8 or above (but also works on Hawaii)
                    if (GDT_HW_GENERATION_VOLCANICISLAND > hwGen && GDT_HAWAII != cardInfo.m_asicType)
                    {
                        GPA_LogError("Hardware not supported.");
                    }
                    else
                    {
                        UINT64 deviceFrequency = 0ull;
                        GPA_ASSERT(DX12Utils::GetTimestampFrequency(pD3D12Device, deviceFrequency));
                        hwInfo.SetTimeStampFrequency(deviceFrequency);
                        success = true;
                    }
                }
            }

            hwInfo.SetHWGeneration(hwGen);
        }
    }

    return success;
}