I'm trying to get DirectX 11 debug layer working. So far I've enabled debugging on the device, and that's as far as I can get. I'm not getting any kind of debug output. All the guides I can find are basically just lumps of code without any real explanation of what's going on, so when it gets to applying what's in there to my specific problem it immediately breaks down and I get nowhere. I'm also not actually learning anything about how to use the debug layer, I'm not learning how to best utilise these technologies for my needs etc.
Basically, can anyone provide me with a step by step of how to get the debug output working?
This is what I've got so far:
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 4;
swapChainDesc.Windowed = true;
D3D_FEATURE_LEVEL featureLevels [] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 };
UINT creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_FEATURE_LEVEL capabilities;
D3D11CreateDeviceAndSwapChain( NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
creationFlags,
featureLevels, //D3D_FEATURE_LEVEL *
ARRAYSIZE(featureLevels), //number of feature levels
D3D11_SDK_VERSION,
&swapChainDesc,
&m_swapChain,
&m_device,
&capabilities,
&m_devCon);
Thanks!
Related
I've made quite a bit of progress since the last time I asked a question. I've got a really cool build now with a terrain mesh with mountains and lakes:
LakeAndMountains
I made a release build, debugged it, and now it works just fine on my computer. I can take the application folder and move it around on my computer and run the .exe file with no issues. However, when I copy the application directory over to my other computer (and my friend's computer), it fails during the D3D11CreateDeviceAndSwapChain step with an HR of S_False.
For both my other computer and my friend's computer, it triggers only the if(failed(hr)) after the create function is called, and it says dev/devcon/swapchain are all NULL. Because they are all null, when it hits the function from swapchain, it crashes with an access violation error.
I searched for a few days looking for solutions, but I have yet to see one that had the S_FALSE occur. I tried some of the more straightforward answers but got nothing. All the computers are running 64bit on 64 bit OS, all have DirectX12, all are high end gaming PCs, my other computer actually has VS2017CE as well set up for c++ game programming, but they both still fail on that line. I'd really appreciate it if anyone could give me some guidance on where to begin deciphering why a release build works on my computer but not on anyone else's computer. Here is the code where it gets initialized, as well as the code for the window creation (code is excerpted to just the relevant parts of the functions):
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);
Thanks in advance.
----UPDATE 2017/09/08-----
So I swapped some code around but I still get the error on the other computer. Current code looks like this:
//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);
So, there is still some weird stuff happening here I'm not getting. If someone has an example of how to use FindClosestMatchingMode properly, I'd really appreciate it.
There is one other really peculiar thing though. When I am in the debugger on my laptop, the variable hWnd has a value, but the compiler says that it is Unused and can't display a value for it. Is this normal or could this be the source of the problem as hWnd is used in the Swap Chain Description? How can hWnd be bad/unused on the other computer but not on my desktop?
Thanks again.
So I FINALLY found the cause of the issue. For some reason, the Count 4 Quality 1 MSAA was not working on the other computer. When I set it to 1/0, it ran perfectly. I'll need to look into how to properly enumerate the MSAA stuff so it can be adjusted depending on the computer.
I've been learning DirectX by following some tutorials but every time I type something myself then DirectX won't work. Here is an example of the latest error that I can't fix after hours of research:
//Header.h
static HWND hWnd;
static IDXGISwapChain* swapChain;
static ID3D11Device* dev;
static ID3D11DeviceContext* devCon;
static ID3D11RenderTargetView* renderTarget;
//DirectX.cpp
bool InitD3D11(HINSTANCE hInst)
{
HRESULT hr;
DXGI_MODE_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
bufferDesc.Width = 800;
bufferDesc.Height = 600;
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;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.Windowed = true;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &dev, NULL, &devCon);
ID3D11Texture2D* backBuffer;
hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);
hr = dev->CreateRenderTargetView(backBuffer, NULL, &renderTarget);
backBuffer->Release();
devCon->OMSetRenderTargets(1, &renderTarget, NULL);
return true;
}
//This is not the full code - I linked directx and lib files and stuff like that.
//If I copy and paste code from tutorials, everything runs fine
Whenever I call InitD3d11, I get an error saying that the swapChain is a NULL pointer. I assume that bufferDesc and/or swapChainDesc has some invalid data but the compiler can't give me any clue what is responsible for the error. Can someone please show me how to trace and fix errors like this? Thanks.
You are not checking the HRESULT values so you are missing all error-handling. For COM programming, even with Direct3D, you must check the HRESULT of every method that can return one for failure. If the return value is safe to ignore, it returns void instead.
Checking HRESULT values in old-school C/C++ programs is done with either the FAILED or SUCCEEDED macros.
hr = D3D11CreateDeviceAndSwapChain( /* ... */ *);
if (FAILED(hr))
return false;
In most cases, a failed HRESULT is treated as a 'fast-fail' or a fatal error. In other words, the program cannot proceed if the call fails.
In other cases there can be special case handling to recover from the error perhaps by using different options. For a detailed example of that, see Anatomy of Direct3D 11 Create Device.
In older Microsoft samples based on the legacy DXUT framework, the error handling was done with macros like V or V_RETURN which did some tracing or tracing & fatal exit.
In modern C++ samples, we actually use a helper DX::ThrowIfFailed that generates a C++ exception on a failed HRESULT for the fast-fail scenario. This makes the code more streamlined and readable:
DX::ThrowIfFailed(
D3D11CreateDeviceAndSwapChain( /* ... */ *)
);
The function itself is defined as:
#include <exception>
namespace DX
{
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
// Set a breakpoint on this line to catch DirectX API errors
throw std::exception();
}
}
}
Your program should be compiled with /EHsc which is already in the default Visual Studio templates. See this topic page for more details.
From your code snippet above, you are following a pretty old-school tutorial. A lot has changed even for DirectX 11 development and most of those older tutorials are going to lead to confusion. As you are new to DirectX, I recommend you take a look at the DirectX Tool Kit and the tutorials there first. You can then come back to the older tutorials with a better understanding of 'modern' Direct3D and be able to extract more relevant information from the old stuff.
After checking all HRESULTS, the next thing you should do is enable the Direct3D debug layer which provides extra debugging information in the output window.
DWORD createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
hr = D3D11CreateDeviceAndSwapChain(
nullptr, D3D_DRIVER_TYPE_HARDWARE,
nullptr, createDeviceFlags, nullptr,
0, D3D11_SDK_VERSION,
&swapChainDesc, &swapChain, &dev, nullptr, &devCon);
You'll note I'm using the C++11 nullptr which is supported on Visual C++ 2010 or later instead of the old-school NULL. That's because it is typed. You were using NULL in two places in your version where the parameter wasn't actually a pointer, it's a number.
With this, you'll get a lot of feedback on basic errors that would help diagnose why in your particular case the swapchain is failing to create. I suspect it's because you are providing some values that are only meaningful for "exclusive fullscreen mode" and not for windowed mode (bufferDesc.RefreshRate). Instead, try:
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc.Width = 800;
swapChainDesc.BufferDesc.Height = 600;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
This works on VS 2013 or VS 2015 which will initialize the structure to 0 with the ={}; syntax. On older compilers, you'll need to use ZeroMemory like you did in your old-school code above.
Note that using D3D11_CREATE_DEVICE_DEBUG will fail on a system that lacks the debugging device which is intended only for developers to use. Details on where you obtain the debug device layer differs based on which version of Windows you are using. See Direct3D SDK Debug Layer Tricks which has a little summary table at the bottom.
Also, debugging in the presence of uninitialized variables is a huge pain. Uninitialized pointers in particular can be a huge time waster. It would help if you did the following:
static HWND hWnd = nullptr;
static IDXGISwapChain* swapChain = nullptr;
static ID3D11Device* dev = nullptr;
static ID3D11DeviceContext* devCon = nullptr;
static ID3D11RenderTargetView* renderTarget = nullptr;
Even better, instead of using raw pointers for your COM objects, you should be using a C++ smart-pointer like Microsoft::WRL::ComPtr. See this topic page for details. Our modern samples use it, and it works for classic Win32 desktop apps as well as for Windows Store, UWP, and Xbox One apps since it's just a C++ template.
I have a d3dDevice:
ComPtr<ID3D11Device1>d3dDevice;
I use it here for the dxgiDevice:
ComPtr<IDXGIDevice3> dxgiDevice2;
HRESULT hr;
hr = d3dDevice.As( &dxgiDevice2 ); // S_OK
hr = d2dFactory->CreateDevice( dxgiDevice2.Get(), d2dDevice.GetAddressOf() ); // E_INVALIDARG One or more arguments are invalid
hr = d2dDevice->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&d2dDeviceContext
);
Why might this error be happening on runtime?
http://msdn.microsoft.com/en-us/library/windows/desktop/dn280482(v=vs.85).aspx
Entirety of my code that is relevant to problem: http://pastebin.com/P7Rs9xdh
The problem is that you haven't created your DX11 device to be compatible with Direct2D. You need to pass the correct creation flags and you should also consider defining the required feature level. Something like:
// This flag adds support for surfaces with a different color channel
// ordering than the API default.
// You need it for compatibility with Direct2D.
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
// This array defines the set of DirectX hardware feature levels this
// app supports.
// The ordering is important and you should preserve it.
// Don't forget to declare your app's minimum required feature level in its
// description. All apps are assumed to support 9.1 unless otherwise stated.
D3D_FEATURE_LEVEL featureLevels[] =
{
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
};
D3D_FEATURE_LEVEL m_featureLevel;
// Create 3D device and device context objects
D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
creationFlags,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&d3dDevice11,
&m_featureLevel,
&d3dDeviceContext11);
I am working though some simple DX tutorials of the book 'Introduction to 3D Game Programming with Direct3D 10.0'. I encountered some problems when I use the function of D3D10CreateDeviceAndSwapChain. The following is the codeļ¼
// Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain.
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = mClientWidth;
sd.BufferDesc.Height = mClientHeight;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// No multisampling.
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = mhMainWnd;
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
// Create the device.
UINT createDeviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
HR( D3D10CreateDeviceAndSwapChain(
0, //default adapter
md3dDriverType,
//D3D10_DRIVER_TYPE_HARDWARE,
0, // no software device
createDeviceFlags,
D3D10_SDK_VERSION,
&sd,
&mSwapChain,
&md3dDevice) );
And the error information is that:
Error Code: E_FAIL (0x80004005) Calling:D3D10CreateDeviceAndSwapChain(.....
when I change the parameter 'createDeviceFlags' of D3D10CreateDeviceAndSwapChain to 0 , then It works. But why?? I want to know the reason, who can tell me ???
MSDN Says
To create a device that supports the debug layer, you must install the DirectX SDK (to get D3D10SDKLayers.DLL), and then specify the D3D10_CREATE_DEVICE_DEBUG flag when calling D3D10CreateDevice.
So, did you install the SDK and do you have D3D10SDKLayers.DLL?
I'm having this exact problem. I got it to work when I switched out the D3D10_CREATE_DEVICE_DEBUG flag for 0. I think my computer is having trouble creating the debug layer for some reason. Not sure why, but at least I was able to create a window that way.
I have exactly the same issue with VS2010 on Windows 8 with DirectX SDK June 2010.
If I disable the debug layer everything works fine. This is of course rather annoying because the debug layer of DirectX is rather handy.
I also tried this workaround for a succesful installation of the DirectX SDK, but it didn't help me:
http://blogs.msdn.com/b/chuckw/archive/2011/12/09/known-issue-directx-sdk-june-2010-setup-and-the-s1023-error.aspx
Is there already a solution for this?
I had a problem with my D3D11CreateDeviceAndSwapChain(). I thought I got a solution in a prev thread, so I already marked it as solved. [Create Swap Chain Failed
Looks like I fooled myself when I accidentally returned the HRESULT as a bool...
I been fighting this problem all day & still have not figured it out. Here are bunch of debug info about the inputs & outputs...
1] Taking the advice to use UNKNOWN with a non-null vAdapter:
Debug Pic http://content.wuala.com/contents/RandomClown/Public/RandomCrap/Debug%201.png
2] Following the DX sample by leaving it null & using type HARDWARE:
Debug Pic http://content.wuala.com/contents/RandomClown/Public/RandomCrap/Debug%202.png
The pics might be enough for someone to spot out the problem, but in case it was something else, code:
// This is some relevant stuff [anything referenced] in the class.
Graphics(){
selectedVAdapter=NULL;
deviceInterface=NULL;
deviceContext=NULL;
swapChain=NULL;
}
bool initDevice(HWND &hWnd){
HRESULT success=S_OK;
D3D_FEATURE_LEVEL featureLevels[]={
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
};
uint featuresSize=ARRAYSIZE(featureLevels);
D3D_DRIVER_TYPE driverTypes[]={
D3D_DRIVER_TYPE_UNKNOWN, // Needed for manual vid adapter setting
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
uint driversSize=ARRAYSIZE(driverTypes);
refreshVideoAdapters();
setVideoAdapter();
//setSampleQuality();
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = settings.bufferCount;
sd.BufferDesc.Width = settings.width;
sd.BufferDesc.Height = settings.height;
sd.BufferDesc.Format = settings.colorDepth;
sd.BufferDesc.RefreshRate.Numerator = settings.rateNumerator;
sd.BufferDesc.RefreshRate.Denominator = settings.rateDenominator;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = settings.sampleCount;
sd.SampleDesc.Quality = settings.sampleQuality;
sd.Windowed = !settings.fullScreen;
uint flag=0;
#ifdef _DEBUG
flag|=D3D11_CREATE_DEVICE_DEBUG;
#endif
for(uint i=0; i<driversSize; i++){ // SwapChain: http://msdn.microsoft.com/en-us/library/ff476083%28v=vs.85%29.aspx
D3D_DRIVER_TYPE driver=driverTypes[i];
success=D3D11CreateDeviceAndSwapChain(
//NULL,
selectedVAdapter, driver, NULL, flag,
featureLevels, featuresSize, D3D11_SDK_VERSION, &sd,
&swapChain, &deviceInterface, &selectedFeatureLevel, &deviceContext);
if(SUCCEEDED(success)) break;
}
return SUCCEEDED(success);
}
// Methods to manage video adapters
void refreshVideoAdapters(){
IDXGIAdapter1* pAdapter;
IDXGIFactory1* pFactory=NULL;
uint lastID=0;
if(selectedVAdapter){
DXGI_ADAPTER_DESC1* desc=NULL;
selectedVAdapter->GetDesc1(desc);
lastID=desc->DeviceId;
releaseVideoAdapters();
}
if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory))) return;
for(uint i=0; pFactory->EnumAdapters1(i, &pAdapter)!=DXGI_ERROR_NOT_FOUND; i++){
vAdapters.push_back(pAdapter);
if(lastID){
DXGI_ADAPTER_DESC1* desc=NULL;
pAdapter->GetDesc1(desc);
if(lastID==desc->DeviceId){
selectedVAdapter=pAdapter;
lastID=0;
}
}
}
if(pFactory) pFactory->Release();
}
void releaseVideoAdapters(){
for(uint i=0; i<vAdapters.size(); i++){
vAdapters[i]->Release();
vAdapters[i]=NULL;
}
vAdapters.clear();
selectedVAdapter=NULL;
}
IDXGIAdapter1* getVideoAdapter(){return selectedVAdapter;}
bool setVideoAdapter(uint num=0){
if(num<vAdapters.size()){
selectedVAdapter=vAdapters[num];
return 1;
}
return 0;
}
// Member vars
private:
SettingsGraphicsDevice settings;
D3D_FEATURE_LEVEL selectedFeatureLevel;
vector<IDXGIAdapter1*> vAdapters;
IDXGIAdapter1* selectedVAdapter;
ID3D11Device* deviceInterface;
ID3D11DeviceContext* deviceContext;
IDXGISwapChain* swapChain;
Settings struct from that code:
struct SettingsGraphicsDevice{
uint width, height;
bool fullScreen, vsync;
uint rateNumerator;
uint rateDenominator;
uint bufferCount;
uint sampleCount, sampleQuality;
DXGI_FORMAT colorDepth;
float minDist, maxDist;
SettingsGraphicsDevice(){
width=height=0;
fullScreen=0;
vsync=0;
rateNumerator=0;
rateDenominator=1;
bufferCount=1;
sampleCount=1, sampleQuality=0;
colorDepth=DXGI_FORMAT_R8G8B8A8_UINT;
minDist=0.1f;
maxDist=1000.0f;
}
};
Thanks for reading. Hope a solution is found this time.
Copy and Paste from my comment: "Also, a quick peek at my code shows that I use DXGI_FORMAT_R8G8B8A8_UNORM, although I currently have no clue whether that's the correct mode.". Ok, so it's in an answer now :-)
Yeah, the formats... the DXGI_FORMAT is a rather large enumeration, but in many situations only certain formats are allowed. It shouldn't be too surprising that only certain formats are allowed for displaying, whether it's fullscreen or not.
I got the value that I used from the docs (as usual), specifically the list in the DXGI_MODE_DESC description. I don't actually know whether I'm creating a blt-block transfer swapchain, but decided that these values are as good as any to start with, and even though I don't care about feature level 9 it seemed pretty safe :-)
I have no idea why your code seemed to work wit a null-adapter; I think that's confusing. Maybe the debug runtime would have caught it?
Switching to that color mode [DXGI_FORMAT_R8G8B8A8_UNORM] worked. I get S_OK now. Why do the other color modes exist if they dont work?