GCP VM 上的自定义分辨率在 Windows Server 2019 上使用 T4 GPU

如何解决GCP VM 上的自定义分辨率在 Windows Server 2019 上使用 T4 GPU

我目前正在寻找一种方法来在 Windows Server 2019 虚拟机上使用 C++ 设置完全自定义的分辨率。

我尝试了不同的方法来实现这一点,我可以在我的笔记本电脑上完成这项工作,但似乎对 GCP VM 有一些限制(或 Windows 服务器限制)。

我已经尝试使用 ChangedisplaySettings/ChangedisplaySettingsEx (winuser.h) 来做到这一点,我可以更改为已知分辨率,但无法使用自定义分辨率(即使使用 CDS_ENABLE_UNSAFE_MODE 也不行)。

DWORD deviceIndex = 0;
disPLAY_DEVICE displayDevice = { 0 };
displayDevice.cb = sizeof(disPLAY_DEVICE);

while (EnumdisplayDevices(NULL,deviceIndex,&displayDevice,0)) {
    deviceIndex++;

    DEVMODE dm = { 0 };
    dm.dmSize = sizeof(DEVMODE);

    DEVMODE finalDm = { 0 };
    finalDm.dmSize = sizeof(DEVMODE);

    //Check if able to retrieve current settings
    if (!EnumdisplaySettings(displayDevice.DeviceName,ENUM_CURRENT_SETTINGS,&dm)) {
        continue;
    }

    //Check if there is a difference in resolution list if UNSAFE_MODE is enabled or not (it seems to not change anything)
    int result = ChangedisplaySettingsEx(displayDevice.DeviceName,&dm,CDS_disABLE_UNSAFE_MODES,NULL);
    std::cout << "CDS_disABLE_UNSAFE_MODE" << std::endl;
    if (result == disP_CHANGE_SUCCESSFUL) {
        for (int i = 0; EnumdisplaySettings(displayDevice.DeviceName,i,&dm) != 0; i++) {
            if (dm.dmBitsPerPel == 32) {
                std::cout << i << ". Found available resolution : " << dm.dmPelsWidth << " x " << dm.dmPelsHeight << " x " << dm.dmBitsPerPel << " @ " << dm.dmdisplayFrequency << std::endl;
            }
        }
    }

    result = ChangedisplaySettingsEx(displayDevice.DeviceName,CDS_ENABLE_UNSAFE_MODES,NULL);
    std::cout << "CDS_ENABLE_UNSAFE_MODE" << std::endl;
    if (result == disP_CHANGE_SUCCESSFUL) {
        for (int i = 0; EnumdisplaySettings(displayDevice.DeviceName,&dm) != 0; i++) {
            if (dm.dmBitsPerPel == 32) {
                std::cout << i << ". Found available resolution : " << dm.dmPelsWidth << " x " << dm.dmPelsHeight << " x " << dm.dmBitsPerPel << " @ " << dm.dmdisplayFrequency << std::endl;
            }
        }
    }


    std::cout << "Please enter width : ";
    int width,height;
    std::cin >> width;
    std::cout << "Please enter height : ";
    std::cin >> height;

    dm.dmPelsWidth = width;
    dm.dmPelsHeight = height;
    if (width > height) {
        dm.dmdisplayOrientation = DMDO_DEFAULT;
    }
    else {
        dm.dmdisplayOrientation = DMDO_90;
    }
    dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_disPLAYORIENTATION;

    //result = ChangedisplaySettingsEx(displayDevice.DeviceName,NULL,CDS_TEST,NULL);
    result = ChangedisplaySettingsEx(displayDevice.DeviceName,NULL);

    if (result != disP_CHANGE_SUCCESSFUL) {
        std::cout << "Impossible to ChangedisplaySettings" << endl;
    }
    else {
        std::cout << "OK" << endl;
    }

    break;
}

然后我看了一下 nvapi,这里也是一样,我可以让它在我的 PC 上运行,但在 GCP 虚拟机上仍然没有......我找到了一种方法来让 nvapi 在我的本地 PC 上创建和使用自定义分辨率,但无法再次在 GCP VM 上运行...(代码示例找到 here

nvapi_Status result = nvapi_ERROR;
NvU32 primarydisplayId = 0;


//Testing resolution
int horizontal = 1920,vertical = 1090;

result = nvapi_Initialize();

if (result != nvapi_OK) {
    printf("Could not initialize nvapi");
    return false;
}

MONITORINFOEX monInfo;
HMONITOR hMon;
const POINT ptZero = { 0,0 };

// determine the location of the primary monitor
hMon = MonitorFromPoint(ptZero,MONITOR_DEFAULTTOPRIMARY);
ZeroMemory(&monInfo,sizeof(monInfo));
monInfo.cbSize = sizeof(monInfo);
GetMonitorInfo(hMon,&monInfo);

result = nvapi_disP_GetGDIPrimarydisplayId(&primarydisplayId);

if (result != nvapi_OK) {
    printf("Could not get display ID from device");
    nvapi_Unload();
    return false;
}

NvU32 deviceCount = 0;
NV_CUSTOM_disPLAY cd[nvapi_MAX_disPLAYS] = { 0 };

float refreshRate = 60;
// timing computation (to get timing that suits the changes made)
NV_TIMING_FLAG flag = { 0 };
NV_TIMING_INPUT timing = { 0 };
timing.version = NV_TIMING_INPUT_VER;
timing.height = vertical;
timing.width = horizontal;
timing.rr = refreshRate;
timing.flag = flag;
timing.type = NV_TIMING_OVERRIDE_CVT_RB;

result = nvapi_disP_GetTiming(primarydisplayId,&timing,&cd[0].timing);

if (result != nvapi_OK) {
    printf("Failed to get timing for display"); // Failed to get custom display timing
    nvapi_Unload();
    return false;
}



cd[0].width = horizontal;
cd[0].height = vertical;
cd[0].xRatio = 1;
cd[0].yRatio = 1;
cd[0].srcPartition = { 0,1.0,1.0 };
cd[0].depth = 32;
cd[0].version = NV_CUSTOM_disPLAY_VER;
cd[0].colorFormat = NV_FORMAT_A8R8G8B8;

//Returns nvapi_ERROR on GCP but nvapi_OK on my laptop
result = nvapi_disP_TryCustomdisplay(&primarydisplayId,1,cd); 

if (result != nvapi_OK) {
    printf("Could not set custom resolution");
    nvapi_disP_RevertCustomdisplayTrial(&primarydisplayId,1);
    nvapi_Unload();
    return false;
}
else {
    nvapi_disP_SaveCustomdisplay(&primarydisplayId,true,true);
}

这部分在我的笔记本电脑上运行得很好,我可以使用新的动态分辨率(它适用于 1920x400、1920x500、1920x600),但不能在我的 GCP VM 上使用,这部分:

nvapi_disP_TryCustomdisplay(&primarydisplayId,cd);

总是返回 nvapi_ERROR

我发现了另一个技巧,我可以编辑这个注册表项:HKEY_LOCAL_MACHINE\SYstem\CurrentControlSet\Control\Video{RANDOM_ID}\0001\NV_Modes (这是一个old pdf,经过一些测试,它似乎仍然以这种方式工作) 如果我使用 nvapi 添加一些分辨率,然后我可以通过 ChangedisplaySettingsEx 函数设置此分辨率(它需要重新启动 GPU 驱动程序,或者重新启动 Windows 才能更改为新添加的分辨率)。 但是我需要能够旋转屏幕,玩“dmdisplayOrientation”,而且它似乎不能再次在 GCP VM 上工作,如果我授权例如 1920x1090,我可以将分辨率设置为此,但不能使用“dmdisplayOrientation”设置 1090x1920 = DMDO_90"(即使我也授权了 1090x1920...)

所以如果有人找到了方法,或者对如何做到这一点有任何想法,那就太好了,我现在没有想法了......

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?