c++ - 是什么导致全屏模式下“D3D11CreateDeviceAndSwapChain”出现访问冲突?
问题描述
我正在尝试从 dll 创建交换链。我的进程创建一个窗口,初始化 Direct3D11 并加载 dll。
当该过程创建非全屏窗口时,它工作得非常好。但是,一旦该过程创建了一个全屏窗口,我在从 dll 调用 D3D11CreateDeviceAndSwapChain 时就会遇到访问冲突。
调用发生在单独的线程中。(不是来自 dllmain 线程。)
现在不幸的是,我什至无法正确调试,因为断点冻结了全屏窗口并且它位于我的调试器窗口的顶部。
是什么导致访问冲突?
编辑:我对 dxgi.dll 进行了一些静态分析,发现在创建交换链时它会检查一系列扩展和基本窗口样式。我还注意到它应该在崩溃之前打印一条调试消息,所以我连接了一个远程调试器来捕获它。该消息只是说明了我已经知道的内容:
DXGI ERROR: IDXGIFactory::CreateSwapChain: The specified output window has a style that is incompatible with DXGI. Output windows must have at least one of:
WS_POPUP
WS_BORDER
WS_CAPTION
WS_SYSMENU
WS_MAXIMIZEBOX
WS_MINIMIZEBOX
WS_THICKFRAME
WS_EX_CLIENTEDGE
WS_EX_CONTEXTHELP
WS_EX_DLGMODALFRAME
WS_EX_TOOLWINDOW
WS_EX_WINDOWEDGE
or not have WS_EX_TOPMOST. [ MISCELLANEOUS ERROR #78: ]
错误代码是:DXGI_ERROR_INVALID_CALL
那么为什么从我的可执行文件初始化direct3d但使用它在我的dll中创建的窗口却不行呢?
EDIT2:显然调用 D3D11CreateDeviceAndSwapChain 并在可执行文件中将 DXGI_SWAP_CHAIN_DESC::Windowed 设置为 FALSE 会更改窗口样式,从而导致对 D3D11CreateDeviceAndSwapChain 的下一次调用失败。
代码片段:
IDXGISwapChain* swapChain;
ID3D11Device* device;
ID3D11DeviceContext* deviceContext;
DXGI_SWAP_CHAIN_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.BufferCount = 1;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
desc.OutputWindow = FindWindowW(L"Window Title", NULL);
desc.SampleDesc.Count = 1;
desc.Windowed = ((GetWindowLongPtr(desc.OutputWindow, GWL_STYLE) & WS_POPUP) != 0) ? false : true;
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
desc.BufferDesc.Width = 1;
desc.BufferDesc.Height = 1;
desc.BufferDesc.RefreshRate.Numerator = 0;
desc.BufferDesc.RefreshRate.Denominator = 1;
if (!desc.OutputWindow)
{
return nullptr;
}
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, };
if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, featureLevelArray, ARRAYSIZE(featureLevelArray), D3D11_SDK_VERSION, &desc, &swapChain, &device, &featureLevel, &deviceContext)))
{
return nullptr;
}
解决方案
在可执行文件中将 DXGI_SWAP_CHAIN_DESC::Windowed 设置为 FALSE 时调用 D3D11CreateDeviceAndSwapChain 会更改窗口样式,从而导致对 D3D11CreateDeviceAndSwapChain 的下一次调用失败。
推荐阅读
- c# - Unity 中的 Sprite 运动故障排除帮助?
- swift - SwiftUI 笔触颜色和宽度?
- react-native - 用虚线样式反应原生顶部和底部边框
- python - 使用高通滤波器过滤低频似乎不起作用
- javascript - 如何将 ID 转换为 React/Angular 中唯一 ID 的引用
- javascript - Node.js 全局变量只工作一次
- c# - URL 单元格中未定义的协议
- ionic-framework - 主插件弃用后如何正确获取设备方向
- java - Spring Boot,Hibernate,Jackson - 延迟序列化
- r - 使用 ggplot 和 facet grid 将数据可视化转换为表格