我认为只有第一张卡上的第一台显示器是由没有实际输出的卡上的nvidia-bios / drivers启用的(无头)。
如果您需要更多监视器,则必须为“连接”监视器提供有效的EDID。
EDID数据通常由某种类型的远程显示解决方案设置,但大多数协议在一张卡上支持更多监视器而不支持多卡。
您可以使用以下代码测试此问题并设置EDID(来自“Windows上的无显示多GPU”.pdf)。
您需要VisualStudio C编译器(免费的VS Express 2013 for Desktop即可)和免费的NVAPI。
#包括
#包括
#include“NvAPI / NvAPI.h”
// 0
unsigned char testEDID [128] = {0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x10,0xAC,0x7A,0xA0,0x4C,0x50,0x32,0x32,0x0D,0x17,0x01,0x03,0x80,
0x34,0x20,0x78,0xEA,0xEE,0x95,0xA3,0x54,0x4C,0x99,0x26,0x0F,0x50,0x54,0xA1,0x08,0x00,0x81,0x40,0x81,0x80,0xA9,0x40,0xB3,0x00,
0xD1,0xC0,0x01,0x01,0x01,0x01,0x01,0x01,0x28,0x3C,0x80,0xA0,0x70,0xB0,0x23,0x40,0x30,0x20,0x36,0x00,0x06,0x44,0x21,0x00,0x00,
0x1A,0x00,0x00,0x00,0xFF,0x00,0x30,0x46,0x46,0x58,0x44,0x33,0x33,0x54,0x32,0x32,0x50,0x4C,0x0A,0x00,0x00,0x00,0xFC,0x00,0x44,
0x45,0x4C,0x4C,0x20,0x55,0x32,0x34,0x31,0x32,0x4D,0x0A,0x20,0x00,0x00,0x00,0xFD,0x00,0x32,0x3D,0x1E,0x53,0x11,0x00,0x0A,0x20,
0x20,0x20,0x20,0x20,0x20,0x00,0x45};
int main(int argc,char * argv []){
NvAPI_Status ret = NVAPI_OK;
NvU32 nDisplayIds = 0;
NvU32 physicalGpuCount = 0;
NV_GPU_DISPLAYIDS pDisplayIds [NVAPI_MAX_DISPLAYS];
NvPhysicalGpuHandle hPhysicalGpu [NVAPI_MAX_PHYSICAL_GPUS];
NV_EDID edid;
// 1
ret = NvAPI_Initialize();
if(ret!= NVAPI_OK)返回-1;
//枚举物理GPU句柄并获取DisplayID
ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu,& physicalGpuCount);
if(ret!= NVAPI_OK)返回-1;
//查询显示ID的总数
printf(“physicals:%d n”,physicalGpuCount);
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu [0],NULL,& nDisplayIds);
if(ret!= NVAPI_OK)返回-1;
//将所有显示ID检索到pDisplayID中
printf(“在physical [0]上显示:%d n”,nDisplayIds);
pDisplayIds [0] .version = NV_GPU_DISPLAYIDS_VER;
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu [0],pDisplayIds,& nDisplayIds);
if(ret!= NVAPI_OK)返回-1;
// 2
memset(& edid,0,sizeof(edid));
edid.version = NV_EDID_VER;
memcpy(edid.EDID_Data,testEDID,sizeof(testEDID));
edid.sizeofEDID = sizeof(testEDID);
//设置EDID(在重新启动之间保持不变)
//edid.sizeofEDID = 0;
//删除EDID
printf(“物理[0]显示[1] n”的NvAPI_GPU_SetEDID);
ret = NvAPI_GPU_SetEDID(hPhysicalGpu [0],pDisplayIds [1] .displayId,& edid);
if(ret!= NVAPI_OK){printf(“NvAPI_GPU_SetEDID failed =%d n”,ret);
返回-1;
}
printf(“NvAPI_GPU_SetEDID success n”);
// 3
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu [0],NULL,&nDisplayIds,NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if(ret!= NVAPI_OK)返回-1;
//从连接的显示中检索显示ID
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu [0],pDisplayIds,& nDisplayIds,NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if(ret!= NVAPI_OK)返回-1;
printf(“物理[0]连接的监视器:%d n”,nDisplayIds);
返回0;
}
// 0 - 样本EDID适用于DELL U2412M监视器1920x1200
// 1 - 计算物理gpu卡和一个物理[0]的“所有显示”(监视器)(你应该得到1,2,3的NvAPI_GPU_GetAllDisplayIds())
// 2 - 在物理[0] +显示[1]上设置EDID(对于1 + 0,2 + 0,3 + 0,你应该NvAPI_GPU_SetEDID())
- 重新启动之间的设置是持久的
- edid.sizeofEDID = 0删除EDID(例如断开连接监视器)
// 3 - 获取“连接显示”的计数
快乐的黑客攻击,M.C>
以上来自于谷歌翻译
以下为原文
I think that only the first monitor on the first card is enabled by nvidia-bios/drivers on cards without real outputs (headless). If you need more monitors you must supply valid EDID to "connect" monitor.
The EDID data is usually set by some type of remote display solution but most protocols support more monitors on
one card and not multi cards.
You can test this problem and setup EDID with following code (from "Displayless Multi-GPU on Windows.pdf"). You need VisualStudio C compiler (free VS Express 2013 for Desktop is OK) and free NVAPI.
#include
#include
#include "NvAPI/NvAPI.h"
// 0
unsigned char testEDID[128] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0xAC, 0x7A, 0xA0, 0x4C, 0x50, 0x32, 0x32, 0x0D, 0x17, 0x01, 0x03, 0x80, 0x34, 0x20, 0x78, 0xEA, 0xEE, 0x95, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54, 0xA1, 0x08, 0x00, 0x81, 0x40, 0x81, 0x80, 0xA9, 0x40, 0xB3, 0x00, 0xD1, 0xC0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3C, 0x80, 0xA0, 0x70, 0xB0, 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x30, 0x46, 0x46, 0x58, 0x44, 0x33, 0x33, 0x54, 0x32, 0x32, 0x50, 0x4C, 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x44, 0x45, 0x4C, 0x4C, 0x20, 0x55, 0x32, 0x34, 0x31, 0x32, 0x4D, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x32, 0x3D, 0x1E, 0x53, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x45 };
int main(int argc, char* argv[]) {
NvAPI_Status ret = NVAPI_OK;
NvU32 nDisplayIds = 0;
NvU32 physicalGpuCount = 0;
NV_GPU_DISPLAYIDS pDisplayIds[NVAPI_MAX_DISPLAYS];
NvPhysicalGpuHandle hPhysicalGpu[NVAPI_MAX_PHYSICAL_GPUS];
NV_EDID edid;
// 1
ret = NvAPI_Initialize();
if (ret != NVAPI_OK) return -1; // Enumerate the physical GPU handle and get the DisplayID
ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu, &physicalGpuCount);
if (ret != NVAPI_OK) return -1; // Query the total number of Display IDs
printf("physicals: %dn", physicalGpuCount);
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu[0], NULL, &nDisplayIds);
if (ret != NVAPI_OK) return -1; // Retrieve all of the Display IDs into pDisplayIDs
printf("displays on physical[0]: %dn", nDisplayIds);
pDisplayIds[0].version = NV_GPU_DISPLAYIDS_VER;
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu[0], pDisplayIds, &nDisplayIds);
if (ret != NVAPI_OK) return -1;
// 2
memset(&edid, 0, sizeof(edid));
edid.version = NV_EDID_VER;
memcpy(edid.EDID_Data, testEDID, sizeof(testEDID));
edid.sizeofEDID = sizeof(testEDID); // to set EDID (it is persistent between reboots)
//edid.sizeofEDID = 0; // to remove EDID
printf("NvAPI_GPU_SetEDID for physical[0] display[1]n");
ret = NvAPI_GPU_SetEDID(hPhysicalGpu[0], pDisplayIds[1].displayId, &edid);
if (ret != NVAPI_OK) { printf("NvAPI_GPU_SetEDID failed = %dn", ret); return -1; }
printf("NvAPI_GPU_SetEDID successn");
// 3
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[0], NULL, &nDisplayIds, NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if (ret != NVAPI_OK) return -1; // Retrieve Display IDs from connected displays
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[0], pDisplayIds, &nDisplayIds, NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if (ret != NVAPI_OK) return -1;
printf("connected monitors on physical[0]: %dn", nDisplayIds);
return 0;
}
// 0 - sample EDID is for DELL U2412M monitor 1920x1200
// 1 - get count about physical gpu card and "all displays" (monitors) of one physical[0] (you should get NvAPI_GPU_GetAllDisplayIds() for 1,2,3)
// 2 - setup EDID on physical[0]+display[1] (you should NvAPI_GPU_SetEDID() for 1+0,2+0,3+0)
- setup is persistent between reboots
- edid.sizeofEDID=0 remove EDID (eg. disconnect monitor)
// 3 - get count of "connected displays"
Happy hacking, M.C>
我认为只有第一张卡上的第一台显示器是由没有实际输出的卡上的nvidia-bios / drivers启用的(无头)。
如果您需要更多监视器,则必须为“连接”监视器提供有效的EDID。
EDID数据通常由某种类型的远程显示解决方案设置,但大多数协议在一张卡上支持更多监视器而不支持多卡。
您可以使用以下代码测试此问题并设置EDID(来自“Windows上的无显示多GPU”.pdf)。
您需要VisualStudio C编译器(免费的VS Express 2013 for Desktop即可)和免费的NVAPI。
#包括
#包括
#include“NvAPI / NvAPI.h”
// 0
unsigned char testEDID [128] = {0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x10,0xAC,0x7A,0xA0,0x4C,0x50,0x32,0x32,0x0D,0x17,0x01,0x03,0x80,
0x34,0x20,0x78,0xEA,0xEE,0x95,0xA3,0x54,0x4C,0x99,0x26,0x0F,0x50,0x54,0xA1,0x08,0x00,0x81,0x40,0x81,0x80,0xA9,0x40,0xB3,0x00,
0xD1,0xC0,0x01,0x01,0x01,0x01,0x01,0x01,0x28,0x3C,0x80,0xA0,0x70,0xB0,0x23,0x40,0x30,0x20,0x36,0x00,0x06,0x44,0x21,0x00,0x00,
0x1A,0x00,0x00,0x00,0xFF,0x00,0x30,0x46,0x46,0x58,0x44,0x33,0x33,0x54,0x32,0x32,0x50,0x4C,0x0A,0x00,0x00,0x00,0xFC,0x00,0x44,
0x45,0x4C,0x4C,0x20,0x55,0x32,0x34,0x31,0x32,0x4D,0x0A,0x20,0x00,0x00,0x00,0xFD,0x00,0x32,0x3D,0x1E,0x53,0x11,0x00,0x0A,0x20,
0x20,0x20,0x20,0x20,0x20,0x00,0x45};
int main(int argc,char * argv []){
NvAPI_Status ret = NVAPI_OK;
NvU32 nDisplayIds = 0;
NvU32 physicalGpuCount = 0;
NV_GPU_DISPLAYIDS pDisplayIds [NVAPI_MAX_DISPLAYS];
NvPhysicalGpuHandle hPhysicalGpu [NVAPI_MAX_PHYSICAL_GPUS];
NV_EDID edid;
// 1
ret = NvAPI_Initialize();
if(ret!= NVAPI_OK)返回-1;
//枚举物理GPU句柄并获取DisplayID
ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu,& physicalGpuCount);
if(ret!= NVAPI_OK)返回-1;
//查询显示ID的总数
printf(“physicals:%d n”,physicalGpuCount);
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu [0],NULL,& nDisplayIds);
if(ret!= NVAPI_OK)返回-1;
//将所有显示ID检索到pDisplayID中
printf(“在physical [0]上显示:%d n”,nDisplayIds);
pDisplayIds [0] .version = NV_GPU_DISPLAYIDS_VER;
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu [0],pDisplayIds,& nDisplayIds);
if(ret!= NVAPI_OK)返回-1;
// 2
memset(& edid,0,sizeof(edid));
edid.version = NV_EDID_VER;
memcpy(edid.EDID_Data,testEDID,sizeof(testEDID));
edid.sizeofEDID = sizeof(testEDID);
//设置EDID(在重新启动之间保持不变)
//edid.sizeofEDID = 0;
//删除EDID
printf(“物理[0]显示[1] n”的NvAPI_GPU_SetEDID);
ret = NvAPI_GPU_SetEDID(hPhysicalGpu [0],pDisplayIds [1] .displayId,& edid);
if(ret!= NVAPI_OK){printf(“NvAPI_GPU_SetEDID failed =%d n”,ret);
返回-1;
}
printf(“NvAPI_GPU_SetEDID success n”);
// 3
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu [0],NULL,&nDisplayIds,NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if(ret!= NVAPI_OK)返回-1;
//从连接的显示中检索显示ID
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu [0],pDisplayIds,& nDisplayIds,NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if(ret!= NVAPI_OK)返回-1;
printf(“物理[0]连接的监视器:%d n”,nDisplayIds);
返回0;
}
// 0 - 样本EDID适用于DELL U2412M监视器1920x1200
// 1 - 计算物理gpu卡和一个物理[0]的“所有显示”(监视器)(你应该得到1,2,3的NvAPI_GPU_GetAllDisplayIds())
// 2 - 在物理[0] +显示[1]上设置EDID(对于1 + 0,2 + 0,3 + 0,你应该NvAPI_GPU_SetEDID())
- 重新启动之间的设置是持久的
- edid.sizeofEDID = 0删除EDID(例如断开连接监视器)
// 3 - 获取“连接显示”的计数
快乐的黑客攻击,M.C>
以上来自于谷歌翻译
以下为原文
I think that only the first monitor on the first card is enabled by nvidia-bios/drivers on cards without real outputs (headless). If you need more monitors you must supply valid EDID to "connect" monitor.
The EDID data is usually set by some type of remote display solution but most protocols support more monitors on
one card and not multi cards.
You can test this problem and setup EDID with following code (from "Displayless Multi-GPU on Windows.pdf"). You need VisualStudio C compiler (free VS Express 2013 for Desktop is OK) and free NVAPI.
#include
#include
#include "NvAPI/NvAPI.h"
// 0
unsigned char testEDID[128] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0xAC, 0x7A, 0xA0, 0x4C, 0x50, 0x32, 0x32, 0x0D, 0x17, 0x01, 0x03, 0x80, 0x34, 0x20, 0x78, 0xEA, 0xEE, 0x95, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54, 0xA1, 0x08, 0x00, 0x81, 0x40, 0x81, 0x80, 0xA9, 0x40, 0xB3, 0x00, 0xD1, 0xC0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3C, 0x80, 0xA0, 0x70, 0xB0, 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x30, 0x46, 0x46, 0x58, 0x44, 0x33, 0x33, 0x54, 0x32, 0x32, 0x50, 0x4C, 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x44, 0x45, 0x4C, 0x4C, 0x20, 0x55, 0x32, 0x34, 0x31, 0x32, 0x4D, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x32, 0x3D, 0x1E, 0x53, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x45 };
int main(int argc, char* argv[]) {
NvAPI_Status ret = NVAPI_OK;
NvU32 nDisplayIds = 0;
NvU32 physicalGpuCount = 0;
NV_GPU_DISPLAYIDS pDisplayIds[NVAPI_MAX_DISPLAYS];
NvPhysicalGpuHandle hPhysicalGpu[NVAPI_MAX_PHYSICAL_GPUS];
NV_EDID edid;
// 1
ret = NvAPI_Initialize();
if (ret != NVAPI_OK) return -1; // Enumerate the physical GPU handle and get the DisplayID
ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu, &physicalGpuCount);
if (ret != NVAPI_OK) return -1; // Query the total number of Display IDs
printf("physicals: %dn", physicalGpuCount);
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu[0], NULL, &nDisplayIds);
if (ret != NVAPI_OK) return -1; // Retrieve all of the Display IDs into pDisplayIDs
printf("displays on physical[0]: %dn", nDisplayIds);
pDisplayIds[0].version = NV_GPU_DISPLAYIDS_VER;
ret = NvAPI_GPU_GetAllDisplayIds(hPhysicalGpu[0], pDisplayIds, &nDisplayIds);
if (ret != NVAPI_OK) return -1;
// 2
memset(&edid, 0, sizeof(edid));
edid.version = NV_EDID_VER;
memcpy(edid.EDID_Data, testEDID, sizeof(testEDID));
edid.sizeofEDID = sizeof(testEDID); // to set EDID (it is persistent between reboots)
//edid.sizeofEDID = 0; // to remove EDID
printf("NvAPI_GPU_SetEDID for physical[0] display[1]n");
ret = NvAPI_GPU_SetEDID(hPhysicalGpu[0], pDisplayIds[1].displayId, &edid);
if (ret != NVAPI_OK) { printf("NvAPI_GPU_SetEDID failed = %dn", ret); return -1; }
printf("NvAPI_GPU_SetEDID successn");
// 3
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[0], NULL, &nDisplayIds, NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if (ret != NVAPI_OK) return -1; // Retrieve Display IDs from connected displays
ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[0], pDisplayIds, &nDisplayIds, NV_GPU_CONNECTED_IDS_FLAG_FAKE);
if (ret != NVAPI_OK) return -1;
printf("connected monitors on physical[0]: %dn", nDisplayIds);
return 0;
}
// 0 - sample EDID is for DELL U2412M monitor 1920x1200
// 1 - get count about physical gpu card and "all displays" (monitors) of one physical[0] (you should get NvAPI_GPU_GetAllDisplayIds() for 1,2,3)
// 2 - setup EDID on physical[0]+display[1] (you should NvAPI_GPU_SetEDID() for 1+0,2+0,3+0)
- setup is persistent between reboots
- edid.sizeofEDID=0 remove EDID (eg. disconnect monitor)
// 3 - get count of "connected displays"
Happy hacking, M.C>
举报