D3D11CreateDeviceAndSwapChain在不同的计算机上失败并带有S_False

时间:2017-08-08 03:00:56

标签: c++ directx-11

自从我上次提出问题以来,我取得了相当大的进步。我现在有一个非常酷的构建,现在有山脉和湖泊的地形网格: LakeAndMountains

我发布了一个版本,调试它,现在它在我的计算机上工作得很好。我可以获取应用程序文件夹并在我的计算机上移动它并运行.exe文件,没有任何问题。但是,当我将应用程序目录复制到我的另一台计算机(和我朋友的计算机)时,它在D3D11CreateDeviceAndSwapChain步骤中失败,HR为S_False。

对于我的另一台计算机和我朋友的计算机,它只在调用create函数后触发if(failed(hr)),并且说dev / devcon / swapchain都是NULL。因为它们都是null,当它从swapchain命中函数时,它会因访问冲突错误而崩溃。

我搜索了几天寻找解决方案,但我还没有看到一个发生S_FALSE的解决方案。我尝试了一些更直截了当的答案,却一无所获。所有的计算机都在64位操作系统上运行64位,都有DirectX12,都是高端游戏PC,我的另一台计算机实际上也有VS2017CE设置用于c ++游戏编程,但它们都仍然在这条线上失败。我真的很感激,如果有人能给我一些指导,从哪里开始解释为什么发布版本可以在我的计算机上运行而不是在其他任何人的计算机上运行。这是初始化的代码,以及窗口创建的代码(代码仅摘录到函数的相关部分):

的WinMain:

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//MessageBox(NULL, "Start of WinMain", "WinMain", 0);
// the handle for the window, filled by a function
HWND hWnd;
// this struct holds information for the window class
WNDCLASSEX wc;

//Screen size variables
long screenWidth = 1280;
long screenHeight = 720;
UINT screenWidthUINT = 1280;
UINT screenHeightUINT = 720;

// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));

// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
//wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = "WindowClass1";

// register the window class
RegisterClassEx(&wc);

RECT wr = { 0, 0, screenWidth, screenHeight };    // set the size, but not the position
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);    // adjust the size

// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
    "WindowClass1",
    "Game",
    WS_OVERLAPPEDWINDOW,
    0,    // x-position of the window
    0,    // y-position of the window
    wr.right - wr.left,    // width of the window
    wr.bottom - wr.top,    // height of the window
    NULL,
    NULL,
    hInstance,
    NULL);

// display the window on the screen
ShowWindow(hWnd, nCmdShow);
//MessageBox(NULL, "called ShowWindow", "WinMain", 0);

/*****************************************
//  GAME ENGINE INITIALIZATION
******************************************/
//Need to initialize the graphics engine. This passes the window pointer through the
//game engine to the D3D engine so it knows what window to look at.
//MessageBox(NULL, "Calling InitGraphics", "WinMain", 0);
InitGraphics(hWnd);

InitGraphics:

//DEVICE CREATION
#include Windows.h
#include <windowsx.h>
#include <d3d11.h>
#include <DirectXMath.h>
#include <D3Dcompiler.h>
#include <dxgi.h>

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3dcompiler.lib")

#include "DirectXDeviceEngine.h"

using namespace DirectX;

InitGraphics(HWND hWnd)
{
//call at start to initialize D3DX
if (hWnd == NULL)
{
    MessageBox(NULL, "hWnd was NULL", "DirectXDeviceEngine", 0);
}

HRESULT hr;
//initialize swap chain
//Describe our Buffer
DXGI_MODE_DESC bufferDesc;

ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

bufferDesc.Width = winWidth;
bufferDesc.Height = winHeight;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;

// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

// fill the swap chain description struct
scd.BufferCount = 1;                                    // one back buffer
scd.BufferDesc = bufferDesc;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
scd.OutputWindow = hWnd;                                // the window to be used
scd.SampleDesc.Count = 4;                               // how many multisamples
scd.SampleDesc.Quality = 1;
scd.Windowed = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;  // windowed/full-screen mode
scd.Flags = 0;

// create a device, device context and swap chain using the information in the scd struct
dev = NULL;
devcon = NULL;
swapchain = NULL;

hr = D3D11CreateDeviceAndSwapChain(
    NULL, //null
    D3D_DRIVER_TYPE_HARDWARE, //driver type
    NULL, //handle to a software rasterizer, should be null if driver type isn't software
    NULL, //UINT device creation flags, can be ORed together
    NULL, //D3D Feature level, when NULL defaults to 11.0-9.1 feature levels
    NULL, //the number of elements in the D3D feature level array
    D3D11_SDK_VERSION, //set to D3D11_SDK_VERSION
    &scd, //reference to the swap chain desc
    &swapchain, //reference to the pointer to the swap chain
    &dev, //reference to the pointer to the device
    NULL, //returns a reference to the first supported element in the feature level array
    &devcon); //reference to the pointer to the device context
if (FAILED(hr))
{
    //CODE FALLS INTO THIS BLOCK ON OTHER COMPUTER
    MessageBox(NULL, "Create Device and SwapChain FAILED", "DirectXDeviceEngine", 0);
    if (swapchain == NULL)
    {
        MessageBox(NULL, "swapchain was NULL", "DirectXDeviceEngine", 0);
    }
    if (dev == NULL)
    {
        MessageBox(NULL, "dev was NULL", "DirectXDeviceEngine", 0);
    }
    if (devcon == NULL)
    {
        MessageBox(NULL, "devcon was NULL", "DirectXDeviceEngine", 0);
    }
}
//prepare buffers
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
//VVVV CODE THEN CRASHES ON NEXT LINE BECAUSE SWAPCHAIN IS NULL VVVV
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

提前致谢。

----更新2017/09/08 ----- 所以我交换了一些代码,但我仍然在另一台计算机上得到错误。当前代码如下所示:

//call at start to initialize D3DX
if (&hWnd == NULL)
{
    MessageBox(NULL, "hWnd was NULL", "DirectXDeviceEngine", 0);
}

HRESULT hr;

// create a device, device context and swap chain using the information in the scd struct
dev = NULL;
devcon = NULL;
swapchain = NULL;

D3D_FEATURE_LEVEL lvl[] = {
    D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0,
    D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 };

DWORD createDeviceFlags = 0;
hash ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
hash endif

D3D_FEATURE_LEVEL fl;
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
    createDeviceFlags, lvl, _countof(lvl),
    D3D11_SDK_VERSION, &dev, &fl, &devcon);
if (hr == E_INVALIDARG)
{
    hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
        createDeviceFlags, &lvl[1], _countof(lvl) - 1,
        D3D11_SDK_VERSION, &dev, &fl, &devcon);
}
if (FAILED(hr))
{
    MessageBox(NULL, "Create Device Failed", "DirectXDeviceEngine", 0);
}

IDXGIDevice * dxgiDevice = 0;
dev->QueryInterface(__uuidof(IDXGIDevice), (void **)& dxgiDevice);

IDXGIAdapter * dxgiAdapter = 0;
dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)& dxgiAdapter);

IDXGIFactory * dxgiFactory = 0;
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)& dxgiFactory);

//initialize swap chain
//Describe our Buffer
DXGI_MODE_DESC bufferDesc;

ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

/*bufferDesc.Width = winWidth;
bufferDesc.Height = winHeight;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
*/
bufferDesc.Width = 0;
bufferDesc.Height = 0;
bufferDesc.RefreshRate.Numerator = 0;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;

// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

// fill the swap chain description struct
scd.BufferCount = 1;                                    // one back buffer
scd.BufferDesc = bufferDesc;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
scd.OutputWindow = hWnd;                                // the window to be used
scd.SampleDesc.Count = 4;                               // how many multisamples
scd.SampleDesc.Quality = 1;
scd.Windowed = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;  // windowed/full-screen mode
scd.Flags = 0;

hr = dxgiFactory->CreateSwapChain(dev, &scd, &swapchain);
if (FAILED(hr))
{
//fails here
    MessageBox(NULL, "Create Swap Chain Failed", "DirectXDeviceEngine", 0);
}

if (dxgiDevice != NULL)
{
    dxgiDevice->Release();
}
if (dxgiAdapter != NULL)
{
    dxgiAdapter->Release();
}
if (dxgiFactory != NULL)
{
    dxgiFactory->Release();
}

//prepare buffers
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

所以,还有一些奇怪的事情发生在这里,我没有得到。如果有人有一个如何正确使用FindClosestMatchingMode的例子,我真的很感激。

但另外还有一件非常奇怪的事情。当我在我的笔记本电脑上的调试器中时,变量hWnd有一个值,但编译器说它是未使用的并且无法显示它的值。这是正常的还是这可能是问题的根源,因为交换链描述中使用了hWnd?怎么可能在另一台计算机上坏/不使用但在我的桌面上没有?

再次感谢。

1 个答案:

答案 0 :(得分:0)

所以我最终找到了问题的原因。出于某种原因,Count 4 Quality 1 MSAA无法在另一台计算机上运行。当我将它设置为1/0时,它运行得很好。我需要研究如何正确枚举MSAA的内容,以便根据计算机进行调整。