首页
社区
课程
招聘
[已解决] [求助][原创]如果像GPU-Z一样获取到显卡的颗粒度? 200.00雪花
发表于: 2021-6-2 18:17 8526

[已解决] [求助][原创]如果像GPU-Z一样获取到显卡的颗粒度? 200.00雪花

2021-6-2 18:17
8526
收藏
免费 2
支持
分享
最新回复 (12)
雪    币: 735
活跃值: (384)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
2
调他驱动...
2021-6-2 20:14
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
你与明日 调他驱动...
NVA的驱动,哪个函数?怎么调用?
2021-6-3 22:35
0
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
参考NvAPI_GPU_GetRamType,这个API是未公开的
https://github.com/processhacker/plugins-extra/blob/master/NvGpuPlugin/nvidia.c
大概用法是 
加载nvapi64.dll/nvapi.dll,获取nvapi_QueryInterface的地址,
使用nvapi_QueryInterface(0x57F7CAACUL)取得NvAPI_GPU_GetRamType的地址,
其中NvAPI_GPU_GetRamType有两个参数,第一个入参为GPU句柄,第二个出参为内存类型,定义如下
显示类型        第二个参数的返回值
Unknown        0
SDRAM        1
DDR1        2
DDR2        3
GDDR2        4
GDDR3        5
GDDR4        6
DDR3        7
GDDR5        8
LPDDR2        9
GDDR5X        10

2021-6-7 15:24
0
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

const char* nvidiadllname = "nvapi64.dll";//如果是32位,使用nvapi.dll

enum {
	UnknownType = 0,
	SDRAM,
	DDR1,
	DDR2,
	GDDR2,
	GDDR3,
	GDDR4,
	DDR3,
	GDDR5,
	LPDDR2,
	GDDR5X
};

typedef unsigned long NvU32;

typedef struct {
	int value;
	struct {
		int   mindelta;
		int   maxdelta;
	} valueRange;
} NV_GPU_PERF_PSTATES20_PARAM_DELTA;

typedef struct {
	NvU32   domainId;
	NvU32   typeId;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NV_GPU_PERF_PSTATES20_PARAM_DELTA   freqDelta_kHz;
	union {
		struct {
			NvU32   freq_kHz;
		} single;
		struct {
			NvU32   minFreq_kHz;
			NvU32   maxFreq_kHz;
			NvU32   domainId;
			NvU32   minVoltage_uV;
			NvU32   maxVoltage_uV;
		} range;
	} data;
} NV_GPU_PSTATE20_CLOCK_ENTRY_V1;

typedef struct {
	NvU32   domainId;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NvU32   volt_uV;
	int     voltDelta_uV;
} NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1;

typedef struct {
	NvU32   version;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NvU32   numPstates;
	NvU32   numClocks;
	NvU32   numBaseVoltages;
	struct {
		NvU32                                   pstateId;
		NvU32                                   bIsEditable : 1;
		NvU32                                   reserved : 31;
		NV_GPU_PSTATE20_CLOCK_ENTRY_V1          clocks[8];
		NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1   baseVoltages[4];
	} pstates[16];
} NV_GPU_PERF_PSTATES20_INFO_V1;

typedef void *(*NvAPI_QueryInterface_t)(unsigned int offset);
typedef int(*NvAPI_Initialize_t)();
typedef int(*NvAPI_Unload_t)();
typedef int(*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count);
typedef int(*NvAPI_GPU_GetRamType_t)(int *handle, int *memtype);

NvAPI_QueryInterface_t NvQueryInterface = 0;
NvAPI_Initialize_t NvInit = 0;
NvAPI_Unload_t NvUnload = 0;
NvAPI_EnumPhysicalGPUs_t NvEnumGPUs = 0;
NvAPI_GPU_GetRamType_t NvGetMemType = 0;

int main(int argc, char **argv)
{
	int nGPU = 0, memtype = 0;
	int *hdlGPU[64] = { 0 };
	NV_GPU_PERF_PSTATES20_INFO_V1 pstates_info;
	pstates_info.version = 0x11c94;

	NvQueryInterface = (void*)GetProcAddress(LoadLibrary(nvidiadllname), "nvapi_QueryInterface");
	NvInit = NvQueryInterface(0x0150E828);
	NvUnload = NvQueryInterface(0xD22BDD7E);
	NvEnumGPUs = NvQueryInterface(0xE5AC921F);
	NvGetMemType = NvQueryInterface(0x57F7CAAC);

	NvInit();//应该检查加载结果,此处为了方便没有编写,以下同
	NvEnumGPUs(hdlGPU, &nGPU);
	NvGetMemType(hdlGPU[0], &memtype);

	switch (memtype) {
	        case  SDRAM:
	        	printf("Memory Type: SDRAM\n");
			break;
		case DDR1:
			printf("Memory Type: DDR1\n");
			break;
		case DDR2:
			printf("Memory Type: DDR2\n");
			break;
		case GDDR2:
			printf("Memory Type: GDDR2\n");
			break;
		case GDDR3:
			printf("Memory Type: GDDR3\n");
			break;
		case GDDR4:
			printf("Memory Type: GDDR4\n");
			break;
		case DDR3:
			printf("Memory Type: DDR3\n");
			break;
		case GDDR5:
			printf("Memory Type: GDDR5\n");
			break;
		case LPDDR2:
			printf("Memory Type: LPDDR2\n");
			break;
		case GDDR5X:
			printf("Memory Type: GDDR5X\n");
			break;
		case UnknownType:
		default:
			printf("Memory Type: Unknown\n");
			break;
	}
	NvUnload();
	return 0;
}

手边没有NVIDIA显卡的设备,不过这个代码应该没问题,代码里面遗漏了好多异常错误检查,实际使用需要补上

最后于 2021-6-7 16:19 被minczsys编辑 ,原因: 漏了一个
2021-6-7 16:05
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
minczsys #include&nbsp;&lt;stdio.h&gt; #include&nbsp;&lt;stdlib.h&gt; #include& ...
谢谢大神,这里有个问题,就是我想知道的是显存的制造商,比如三星,海力士等,怎么获取
2021-6-11 09:18
0
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

const char* nvidiadllname = "nvapi64.dll";

typedef enum _NV_RAM_TYPE
{
	NV_RAM_TYPE_UNKNOWN = 0,
	NV_RAM_TYPE_SDRAM,
	NV_RAM_TYPE_DDR1,
	NV_RAM_TYPE_DDR2,
	NV_RAM_TYPE_GDDR2,
	NV_RAM_TYPE_GDDR3,
	NV_RAM_TYPE_GDDR4,
	NV_RAM_TYPE_DDR3,
	NV_RAM_TYPE_GDDR5,
	NV_RAM_TYPE_LPDDR2,
	NV_RAM_TYPE_GDDR5X
}NV_RAM_TYPE;

typedef enum _NV_RAM_MAKER
{
	NV_RAM_MAKER_NONE,
	NV_RAM_MAKER_SAMSUNG,
	NV_RAM_MAKER_QIMONDA,
	NV_RAM_MAKER_ELPIDA,
	NV_RAM_MAKER_ETRON,
	NV_RAM_MAKER_NANYA,
	NV_RAM_MAKER_HYNIX,
	NV_RAM_MAKER_MOSEL,
	NV_RAM_MAKER_WINBOND,
	NV_RAM_MAKER_ELITE,
	NV_RAM_MAKER_MICRON
}NV_RAM_MAKER;

typedef unsigned long NvU32;

typedef struct {
	int value;
	struct {
		int   mindelta;
		int   maxdelta;
	} valueRange;
} NV_GPU_PERF_PSTATES20_PARAM_DELTA;

typedef struct {
	NvU32   domainId;
	NvU32   typeId;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NV_GPU_PERF_PSTATES20_PARAM_DELTA   freqDelta_kHz;
	union {
		struct {
			NvU32   freq_kHz;
		} single;
		struct {
			NvU32   minFreq_kHz;
			NvU32   maxFreq_kHz;
			NvU32   domainId;
			NvU32   minVoltage_uV;
			NvU32   maxVoltage_uV;
		} range;
	} data;
} NV_GPU_PSTATE20_CLOCK_ENTRY_V1;

typedef struct {
	NvU32   domainId;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NvU32   volt_uV;
	int     voltDelta_uV;
} NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1;

typedef struct {
	NvU32   version;
	NvU32   bIsEditable : 1;
	NvU32   reserved : 31;
	NvU32   numPstates;
	NvU32   numClocks;
	NvU32   numBaseVoltages;
	struct {
		NvU32                                   pstateId;
		NvU32                                   bIsEditable : 1;
		NvU32                                   reserved : 31;
		NV_GPU_PSTATE20_CLOCK_ENTRY_V1          clocks[8];
		NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1   baseVoltages[4];
	} pstates[16];
} NV_GPU_PERF_PSTATES20_INFO_V1;

typedef void *(*NvAPI_QueryInterface_t)(unsigned int offset);
typedef int(*NvAPI_Initialize_t)();
typedef int(*NvAPI_Unload_t)();
typedef int(*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count);
typedef int(*NvAPI_GPU_GetRamType_t)(int *handle, NV_RAM_TYPE* memtype);
typedef int(*NvAPI_GPU_GetRamMaker_t)(int *handle, NV_RAM_MAKER* pRamMaker);

NvAPI_QueryInterface_t NvQueryInterface = NULL;
NvAPI_Initialize_t NvInit = NULL;
NvAPI_Unload_t NvUnload = NULL;
NvAPI_EnumPhysicalGPUs_t NvEnumGPUs = NULL;
NvAPI_GPU_GetRamType_t NvGetMemType = NULL;
NvAPI_GPU_GetRamMaker_t NvGetMemMarker = NULL;

int main(int argc, char **argv)
{
	int nGPU = 0;
	NV_RAM_TYPE memtype = NV_RAM_TYPE_UNKNOWN;
	NV_RAM_MAKER memmarker = NV_RAM_MAKER_NONE;
	int *hdlGPU[64] = { 0 };
	NV_GPU_PERF_PSTATES20_INFO_V1 pstates_info;
	pstates_info.version = 0x11c94;

	NvQueryInterface = (void*)GetProcAddress(LoadLibrary(nvidiadllname), "nvapi_QueryInterface");
	NvInit = NvQueryInterface(0x0150E828);
	NvUnload = NvQueryInterface(0xD22BDD7E);
	NvEnumGPUs = NvQueryInterface(0xE5AC921F);
	NvGetMemType = NvQueryInterface(0x57F7CAAC);
	NvGetMemMarker = NvQueryInterface(0x42AEA16AUL);

	NvInit();
	NvEnumGPUs(hdlGPU, &nGPU);
	NvGetMemType(hdlGPU[0], &memtype);
	NvGetMemMarker(hdlGPU[0], &memmarker);

	switch (memtype) {
		case NV_RAM_TYPE_SDRAM:
			printf("Memory Type: SDRAM");
			break;
		case NV_RAM_TYPE_DDR1:
			printf("Memory Type: DDR1");
			break;
		case NV_RAM_TYPE_DDR2:
			printf("Memory Type: DDR2");
			break;
		case NV_RAM_TYPE_GDDR2:
			printf("Memory Type: GDDR2");
			break;
		case NV_RAM_TYPE_GDDR3:
			printf("Memory Type: GDDR3");
			break;
		case NV_RAM_TYPE_GDDR4:
			printf("Memory Type: GDDR4");
			break;
		case NV_RAM_TYPE_DDR3:
			printf("Memory Type: DDR3");
			break;
		case NV_RAM_TYPE_GDDR5:
			printf("Memory Type: GDDR5");
			break;
		case NV_RAM_TYPE_LPDDR2:
			printf("Memory Type: LPDDR2");
			break;
		case NV_RAM_TYPE_GDDR5X:
			printf("Memory Type: GDDR5X");
			break;
		case NV_RAM_TYPE_UNKNOWN:
		default:
			printf("Memory Type: Unknown");
			break;
	}
	switch (memmarker) {
		case NV_RAM_MAKER_SAMSUNG:
			printf("(Samsung)\n");
			break;
		case NV_RAM_MAKER_QIMONDA:
			printf("(Qimonda)\n");
			break;
		case NV_RAM_MAKER_ELPIDA:
			printf("(Elpida)\n");
			break;
		case NV_RAM_MAKER_ETRON:
			printf("(Etron)\n");
			break;
		case NV_RAM_MAKER_NANYA:
			printf("(Nanya)\n");
			break;
		case NV_RAM_MAKER_HYNIX:
			printf("(Hynix)\n");
			break;
		case NV_RAM_MAKER_MOSEL:
			printf("(Mosel)\n");
			break;
		case NV_RAM_MAKER_WINBOND:
			printf("(Winbond)\n");
			break;
		case NV_RAM_MAKER_ELITE:
			printf("(Elite)\n");
			break;
		case NV_RAM_MAKER_MICRON:
			printf("(Micron)\n");
			break;
		default:
			printf("(Unknown)\n");
			break;
	}
	NvUnload();
	return 0;
}

大概像这样

最后于 2021-6-11 10:48 被minczsys编辑 ,原因: 调整代码缩进
2021-6-11 10:43
2
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
langzi8818 谢谢大神,这里有个问题,就是我想知道的是显存的制造商,比如三星,海力士等,怎么获取
还是参考
https://github.com/processhacker/plugins-extra/blob/master/NvGpuPlugin/nvidia.c
2021-6-11 10:49
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
minczsys 还是参考 https://github.com/processhacker/plugins-extra/blob/master/NvGpuPlugin/nvidia.c
大神大神,NvGetMemMarker这个对应的是哪个函数?知道了应该就通了。
2021-8-3 18:51
0
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
minczsys #include&nbsp;&lt;stdio.h&gt; #include&nbsp;&lt;stdlib.h&gt; #include& ...
参考这个
NvGetMemMarker = NvQueryInterface(0x42AEA16AUL);
2021-8-5 21:20
0
雪    币: 359
活跃值: (114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
langzi8818 大神大神,NvGetMemMarker这个对应的是哪个函数?知道了应该就通了。
7楼是完整的方法,刚才找了台机器试了下,没有问题
2021-8-5 21:23
0
雪    币: 179
活跃值: (264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
       NvQueryInterface = (NvAPI_QueryInterface_t)GetProcAddress(LoadLibrary(nvidiadllname), "nvapi_QueryInterface");
       NvInit = (NvAPI_Initialize_t)NvQueryInterface(0x0150E828);
       NvUnload = (NvAPI_Unload_t)NvQueryInterface(0xD22BDD7E);
       NvEnumGPUs = (NvAPI_EnumPhysicalGPUs_t)NvQueryInterface(0xE5AC921F);
       NvGetMemType = (NvAPI_GPU_GetRamType_t)NvQueryInterface(0x57F7CAAC);
       NvGetMemMarker = (NvAPI_GPU_GetRamMaker_t)NvQueryInterface(0x42AEA16AUL);
2021-8-21 21:15
0
雪    币: 179
活跃值: (264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
使用多字节字符集
2021-8-21 21:24
0
游客
登录 | 注册 方可回帖
返回
//