Beispiel #1
0
VOID EtSaveGpuMonitorSettings(
	VOID
	)
{
	PPH_STRING string;

	string = PhBufferToHexString((PUCHAR)EtGpuNodeBitMapBuffer, BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount));
	PhSetStringSetting2(SETTING_NAME_GPU_NODE_BITMAP, &string->sr);
	PhDereferenceObject(string);
}
Beispiel #2
0
VOID EtAllocateGpuNodeBitMap(
	_Out_ PRTL_BITMAP BitMap
	)
{
	SIZE_T numberOfBytes;

	numberOfBytes = BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount);

	BitMap->Buffer = PhAllocate(numberOfBytes);
	BitMap->SizeOfBitMap = EtGpuTotalNodeCount;
	memset(BitMap->Buffer, 0, numberOfBytes);
}
Beispiel #3
0
PETP_GPU_ADAPTER AllocateGpuAdapter( UINT32 NumberOfSegments )
{
    PETP_GPU_ADAPTER adapter;
    UINT32 sizeNeeded;

    sizeNeeded = FIELD_OFFSET(ETP_GPU_ADAPTER, ApertureBitMapBuffer);
    sizeNeeded += BYTES_NEEDED_FOR_BITS(NumberOfSegments);

	adapter = (PETP_GPU_ADAPTER) Memory::Allocate(sizeNeeded);

	Memory::Clear(adapter, sizeNeeded);

    return adapter;
}
Beispiel #4
0
PETP_GPU_ADAPTER EtpAllocateGpuAdapter(
	_In_ ULONG NumberOfSegments
	)
{
	PETP_GPU_ADAPTER adapter;
	SIZE_T sizeNeeded;

	sizeNeeded = FIELD_OFFSET(ETP_GPU_ADAPTER, ApertureBitMapBuffer);
	sizeNeeded += BYTES_NEEDED_FOR_BITS(NumberOfSegments);

	adapter = PhAllocate(sizeNeeded);
	memset(adapter, 0, sizeNeeded);

	return adapter;
}
Beispiel #5
0
VOID
D3DKMTInitialize()
{
    VOID *gdi32 = NULL;
    VOID *deviceInfoSet;
    UINT32 result;
    UINT32 memberIndex;
    UINT32 detailDataSize;
    SP_DEVICE_INTERFACE_DATA            deviceInterfaceData;
    SP_DEVICE_INTERFACE_DETAIL_DATA_W   *detailData;
    SP_DEVINFO_DATA                     deviceInfoData;
    //D3DKMT_OPENADAPTERFROMDEVICENAME    openAdapterFromDeviceName;
    D3DKMT_QUERYSTATISTICS              queryStatistics;

    gdi32 = Module::Load(L"gdi32.dll");

    if (!gdi32)
    {
        return;
    }

    D3DKMTOpenAdapterFromDeviceName = (TYPE_D3DKMTOpenAdapterFromDeviceName) Module::GetProcedureAddress(
                                                                                gdi32,
                                                                                "D3DKMTOpenAdapterFromDeviceName"
                                                                                );

    D3DKMTQueryStatistics = (TYPE_D3DKMTQueryStatistics) Module::GetProcedureAddress(gdi32, "D3DKMTQueryStatistics");

    if (!D3DKMTOpenAdapterFromDeviceName || !D3DKMTQueryStatistics)
    {
        return;
    }

    deviceInfoSet = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL_I,
                                         NULL, NULL,
                                         DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    if (!deviceInfoSet)
    {
        return;
    }

    memberIndex = 0;
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    while (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DISPLAY_DEVICE_ARRIVAL_I, memberIndex, &deviceInterfaceData))
    {
        detailDataSize = 0x100;
		detailData = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*) Memory::Allocate(detailDataSize);
        detailData->cbSize = 6; /*sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)*/
        deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

        result = SetupDiGetDeviceInterfaceDetailW(
                    deviceInfoSet,
                    &deviceInterfaceData,
                    detailData,
                    detailDataSize,
                    &detailDataSize,
                    &deviceInfoData
                    );

        if (result)
        {
            openAdapterFromDeviceName.pDeviceName = detailData->DevicePath;

            if (NT_SUCCESS(D3DKMTOpenAdapterFromDeviceName(&openAdapterFromDeviceName)))
            {
                memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));

                queryStatistics.Type = D3DKMT_QUERYSTATISTICS_ADAPTER;
                queryStatistics.AdapterLuid = openAdapterFromDeviceName.AdapterLuid;

                if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                {
                    UINT32 i;

                    D3dkmt_GpuAdapter = AllocateGpuAdapter(queryStatistics.QueryResult.AdapterInformation.NbSegments);

                    D3dkmt_GpuAdapter->AdapterLuid       = openAdapterFromDeviceName.AdapterLuid;
                    D3dkmt_GpuAdapter->NodeCount     = queryStatistics.QueryResult.AdapterInformation.NodeCount;
                    D3dkmt_GpuAdapter->SegmentCount  = queryStatistics.QueryResult.AdapterInformation.NbSegments;

                    RtlInitializeBitMap(
                        &D3dkmt_GpuAdapter->ApertureBitMap,
                        D3dkmt_GpuAdapter->ApertureBitMapBuffer,
                        queryStatistics.QueryResult.AdapterInformation.NbSegments
                        );

                    EtGpuTotalNodeCount += D3dkmt_GpuAdapter->NodeCount;

                    EtGpuTotalSegmentCount += D3dkmt_GpuAdapter->SegmentCount;

                    D3dkmt_GpuAdapter->FirstNodeIndex = EtGpuNextNodeIndex;
                    EtGpuNextNodeIndex += D3dkmt_GpuAdapter->NodeCount;

                    for (i = 0; i < D3dkmt_GpuAdapter->SegmentCount; i++)
                    {
                        memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));

                        queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT;
                        queryStatistics.AdapterLuid = D3dkmt_GpuAdapter->AdapterLuid;
                        queryStatistics.QuerySegment.SegmentId = i;

                        if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                        {
                            UINT64 commitLimit;
                            UINT32 aperature;

                            commitLimit = queryStatistics.QueryResult.SegmentInformationV1.CommitLimit;
                            aperature = queryStatistics.QueryResult.SegmentInformationV1.Aperture;

                            if (aperature)
                                RtlSetBits(&D3dkmt_GpuAdapter->ApertureBitMap, i, 1);
                            else
                                EtGpuDedicatedLimit += commitLimit;
                        }
                    }
                }
            }
        }

		Memory::Free(detailData);

        memberIndex++;
    }

    SetupDiDestroyDeviceInfoList(deviceInfoSet);

    EtGpuNodeBitMapBuffer = (UINT32*) Memory::Allocate(BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount));
    
	RtlInitializeBitMap(&EtGpuNodeBitMap, EtGpuNodeBitMapBuffer, EtGpuTotalNodeCount);

    EtGpuNodesTotalRunningTimeDelta = (PPH_UINT64_DELTA) Memory::Allocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);

    memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
}
Beispiel #6
0
BOOLEAN EtpInitializeD3DStatistics(
	VOID
	)
{
	LOGICAL result;
	HDEVINFO deviceInfoSet;
	ULONG memberIndex;
	SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
	SP_DEVINFO_DATA deviceInfoData;
	ULONG detailDataSize;
	D3DKMT_OPENADAPTERFROMDEVICENAME openAdapterFromDeviceName;
	D3DKMT_QUERYSTATISTICS queryStatistics;

	deviceInfoSet = SetupDiGetClassDevsW_I(&GUID_DISPLAY_DEVICE_ARRIVAL_I, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

	if (!deviceInfoSet)
		return FALSE;

	memberIndex = 0;
	deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	while (SetupDiEnumDeviceInterfaces_I(deviceInfoSet, NULL, &GUID_DISPLAY_DEVICE_ARRIVAL_I, memberIndex, &deviceInterfaceData))
	{
		detailDataSize = 0x100;
		detailData = PhAllocate(detailDataSize);
		detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

		if (!(result = SetupDiGetDeviceInterfaceDetailW_I(deviceInfoSet, &deviceInterfaceData, detailData, detailDataSize, &detailDataSize, &deviceInfoData)) &&
			GetLastError() == ERROR_INSUFFICIENT_BUFFER)
		{
			PhFree(detailData);
			detailData = PhAllocate(detailDataSize);

			if (detailDataSize >= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA))
				detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			result = SetupDiGetDeviceInterfaceDetailW_I(deviceInfoSet, &deviceInterfaceData, detailData, detailDataSize, &detailDataSize, &deviceInfoData);
		}

		if (result)
		{
			openAdapterFromDeviceName.pDeviceName = detailData->DevicePath;

			if (NT_SUCCESS(D3DKMTOpenAdapterFromDeviceName_I(&openAdapterFromDeviceName)))
			{
				memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
				queryStatistics.Type = D3DKMT_QUERYSTATISTICS_ADAPTER;
				queryStatistics.AdapterLuid = openAdapterFromDeviceName.AdapterLuid;

				if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics)))
				{
					PETP_GPU_ADAPTER gpuAdapter;
					ULONG i;

					gpuAdapter = EtpAllocateGpuAdapter(queryStatistics.QueryResult.AdapterInformation.NbSegments);
					gpuAdapter->AdapterLuid = openAdapterFromDeviceName.AdapterLuid;
					gpuAdapter->Description = EtpQueryDeviceDescription(deviceInfoSet, &deviceInfoData);
					gpuAdapter->NodeCount = queryStatistics.QueryResult.AdapterInformation.NodeCount;
					gpuAdapter->SegmentCount = queryStatistics.QueryResult.AdapterInformation.NbSegments;
					RtlInitializeBitMap(&gpuAdapter->ApertureBitMap, gpuAdapter->ApertureBitMapBuffer, queryStatistics.QueryResult.AdapterInformation.NbSegments);

					PhAddItemList(EtpGpuAdapterList, gpuAdapter);
					EtGpuTotalNodeCount += gpuAdapter->NodeCount;
					EtGpuTotalSegmentCount += gpuAdapter->SegmentCount;

					gpuAdapter->FirstNodeIndex = EtGpuNextNodeIndex;
					EtGpuNextNodeIndex += gpuAdapter->NodeCount;

					for (i = 0; i < gpuAdapter->SegmentCount; i++)
					{
						memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
						queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT;
						queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid;
						queryStatistics.QuerySegment.SegmentId = i;

						if (NT_SUCCESS(D3DKMTQueryStatistics_I(&queryStatistics)))
						{
							ULONG64 commitLimit;
							ULONG aperture;

								commitLimit = queryStatistics.QueryResult.SegmentInformation.CommitLimit;
								aperture = queryStatistics.QueryResult.SegmentInformation.Aperture;

							if (aperture)
								EtGpuSharedLimit += commitLimit;
							else
								EtGpuDedicatedLimit += commitLimit;

							if (aperture)
								RtlSetBits(&gpuAdapter->ApertureBitMap, i, 1);
						}
					}
				}
			}
		}

		PhFree(detailData);

		memberIndex++;
	}

	SetupDiDestroyDeviceInfoList_I(deviceInfoSet);

	EtGpuNodeBitMapBuffer = PhAllocate(BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount));
	RtlInitializeBitMap(&EtGpuNodeBitMap, EtGpuNodeBitMapBuffer, EtGpuTotalNodeCount);
	RtlSetBits(&EtGpuNodeBitMap, 0, 1);
	EtGpuNodeBitMapBitsSet = 1;

	return TRUE;
}
Beispiel #7
0
VOID EtGpuMonitorInitialization(
    VOID
)
{
    if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU_MONITOR))
    {
        EtpGpuAdapterList = PhCreateList(4);

        if (EtpInitializeD3DStatistics())
            EtGpuEnabled = TRUE;
    }

    if (EtGpuEnabled)
    {
        ULONG sampleCount;
        ULONG i;
        ULONG j;
        PPH_STRING bitmapString;
        D3DKMT_QUERYSTATISTICS queryStatistics;

        sampleCount = PhGetIntegerSetting(L"SampleCount");
        PhInitializeCircularBuffer_FLOAT(&EtGpuNodeHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtMaxGpuNodeHistory, sampleCount);
        PhInitializeCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtGpuDedicatedHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtGpuSharedHistory, sampleCount);

        EtGpuNodesTotalRunningTimeDelta = PhAllocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
        memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
        EtGpuNodesHistory = PhAllocate(sizeof(PH_CIRCULAR_BUFFER_FLOAT) * EtGpuTotalNodeCount);

        for (i = 0; i < EtGpuTotalNodeCount; i++)
        {
            PhInitializeCircularBuffer_FLOAT(&EtGpuNodesHistory[i], sampleCount);
        }

        PhRegisterCallback(
            &PhProcessesUpdatedEvent,
            EtGpuProcessesUpdatedCallback,
            NULL,
            &ProcessesUpdatedCallbackRegistration
        );

        // Load the node bitmap.

        bitmapString = PhGetStringSetting(SETTING_NAME_GPU_NODE_BITMAP);

        if (!(bitmapString->Length & 3) && bitmapString->Length / 4 <= BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount))
        {
            PhHexStringToBuffer(&bitmapString->sr, (PUCHAR)EtGpuNodeBitMapBuffer);
            EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap);
        }

        PhDereferenceObject(bitmapString);

        // Fix up the node bitmap if the current node count differs from what we've seen.
        if (EtGpuTotalNodeCount != PhGetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT))
        {
            ULONG maxContextSwitch = 0;
            ULONG maxContextSwitchNodeIndex = 0;

            RtlClearAllBits(&EtGpuNodeBitMap);
            EtGpuNodeBitMapBitsSet = 0;

            for (i = 0; i < EtpGpuAdapterList->Count; i++)
            {
                PETP_GPU_ADAPTER gpuAdapter = EtpGpuAdapterList->Items[i];

                for (j = 0; j < gpuAdapter->NodeCount; j++)
                {
                    memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
                    queryStatistics.Type = D3DKMT_QUERYSTATISTICS_NODE;
                    queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid;
                    queryStatistics.QueryNode.NodeId = j;

                    if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                    {
                        // The numbers below are quite arbitrary.
                        if (queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart != 0 &&
                                queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch > 10000)
                        {
                            RtlSetBits(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j, 1);
                            EtGpuNodeBitMapBitsSet++;
                        }

                        if (maxContextSwitch < queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch)
                        {
                            maxContextSwitch = queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch;
                            maxContextSwitchNodeIndex = gpuAdapter->FirstNodeIndex + j;
                        }
                    }
                }
            }

            // Just in case
            if (EtGpuNodeBitMapBitsSet == 0)
            {
                RtlSetBits(&EtGpuNodeBitMap, maxContextSwitchNodeIndex, 1);
                EtGpuNodeBitMapBitsSet = 1;
            }

            PhSetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT, EtGpuTotalNodeCount);
        }
    }
}
Beispiel #8
0
BOOLEAN EtpInitializeD3DStatistics(
    VOID
)
{
    PWSTR deviceInterfaceList;
    ULONG deviceInterfaceListLength = 0;
    PWSTR deviceInterface;
    D3DKMT_OPENADAPTERFROMDEVICENAME openAdapterFromDeviceName;
    D3DKMT_QUERYSTATISTICS queryStatistics;
    D3DKMT_CLOSEADAPTER closeAdapter;

    if (CM_Get_Device_Interface_List_Size(
                &deviceInterfaceListLength,
                (PGUID)&GUID_DISPLAY_DEVICE_ARRIVAL,
                NULL,
                CM_GET_DEVICE_INTERFACE_LIST_PRESENT
            ) != CR_SUCCESS)
    {
        return FALSE;
    }

    deviceInterfaceList = PhAllocate(deviceInterfaceListLength * sizeof(WCHAR));
    memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR));

    if (CM_Get_Device_Interface_List(
                (PGUID)&GUID_DISPLAY_DEVICE_ARRIVAL,
                NULL,
                deviceInterfaceList,
                deviceInterfaceListLength,
                CM_GET_DEVICE_INTERFACE_LIST_PRESENT
            ) != CR_SUCCESS)
    {
        PhFree(deviceInterfaceList);
        return FALSE;
    }

    for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += PhCountStringZ(deviceInterface) + 1)
    {
        memset(&openAdapterFromDeviceName, 0, sizeof(D3DKMT_OPENADAPTERFROMDEVICENAME));
        openAdapterFromDeviceName.pDeviceName = deviceInterface;

        if (NT_SUCCESS(D3DKMTOpenAdapterFromDeviceName(&openAdapterFromDeviceName)))
        {
            memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
            queryStatistics.Type = D3DKMT_QUERYSTATISTICS_ADAPTER;
            queryStatistics.AdapterLuid = openAdapterFromDeviceName.AdapterLuid;

            if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
            {
                PETP_GPU_ADAPTER gpuAdapter;
                ULONG i;

                gpuAdapter = EtpAllocateGpuAdapter(queryStatistics.QueryResult.AdapterInformation.NbSegments);
                gpuAdapter->AdapterLuid = openAdapterFromDeviceName.AdapterLuid;
                gpuAdapter->Description = EtpQueryDeviceDescription(deviceInterface);
                gpuAdapter->NodeCount = queryStatistics.QueryResult.AdapterInformation.NodeCount;
                gpuAdapter->SegmentCount = queryStatistics.QueryResult.AdapterInformation.NbSegments;
                RtlInitializeBitMap(&gpuAdapter->ApertureBitMap, gpuAdapter->ApertureBitMapBuffer, queryStatistics.QueryResult.AdapterInformation.NbSegments);

                PhAddItemList(EtpGpuAdapterList, gpuAdapter);
                EtGpuTotalNodeCount += gpuAdapter->NodeCount;
                EtGpuTotalSegmentCount += gpuAdapter->SegmentCount;

                gpuAdapter->FirstNodeIndex = EtGpuNextNodeIndex;
                EtGpuNextNodeIndex += gpuAdapter->NodeCount;

                for (i = 0; i < gpuAdapter->SegmentCount; i++)
                {
                    memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
                    queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT;
                    queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid;
                    queryStatistics.QuerySegment.SegmentId = i;

                    if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                    {
                        ULONG64 commitLimit;
                        ULONG aperture;

                        if (WindowsVersion >= WINDOWS_8)
                        {
                            commitLimit = queryStatistics.QueryResult.SegmentInformation.CommitLimit;
                            aperture = queryStatistics.QueryResult.SegmentInformation.Aperture;
                        }
                        else
                        {
                            commitLimit = queryStatistics.QueryResult.SegmentInformationV1.CommitLimit;
                            aperture = queryStatistics.QueryResult.SegmentInformationV1.Aperture;
                        }

                        if (aperture)
                            EtGpuSharedLimit += commitLimit;
                        else
                            EtGpuDedicatedLimit += commitLimit;

                        if (aperture)
                            RtlSetBits(&gpuAdapter->ApertureBitMap, i, 1);
                    }
                }
            }

            memset(&closeAdapter, 0, sizeof(D3DKMT_CLOSEADAPTER));
            closeAdapter.hAdapter = openAdapterFromDeviceName.hAdapter;
            D3DKMTCloseAdapter(&closeAdapter);
        }
    }

    PhFree(deviceInterfaceList);

    EtGpuNodeBitMapBuffer = PhAllocate(BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount));
    RtlInitializeBitMap(&EtGpuNodeBitMap, EtGpuNodeBitMapBuffer, EtGpuTotalNodeCount);
    RtlSetBits(&EtGpuNodeBitMap, 0, 1);
    EtGpuNodeBitMapBitsSet = 1;

    return TRUE;
}