IDXGISwapChain::ResizeBuffers triggers breakpoint when switching from fullscreen to windowed - c++

Whenever my Direct3D 11 application switches from fullscreen to windowed mode, IDXGISwapChain::ResizeBuffers triggers a breakpoint. In Visual Studio's console, the message "Critical error 0xc0000374" is printed, with no other information. Apparently this means a heap corruption has occurred. Okay then. I can't get any more information about why this occurred because the window obnoxiously obscures my view and prevents me from controlling the visual studio window.
I'm following the suggestions made on this MSDN page. By that I mean I copied and pasted the code.
This is my setup code (ignore the lack of error checking):
DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
swap_chain_desc.BufferCount = 2;
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.OutputWindow = window::get();
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swap_chain_desc.Windowed = TRUE;
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
if (fullscreen == 1) {
swap_chain_desc.BufferDesc.Width = window::desktop_width();
swap_chain_desc.BufferDesc.Height = window::desktop_height();
} else {
swap_chain_desc.BufferDesc.Width = window::width();
swap_chain_desc.BufferDesc.Height = window::height();
}
HRESULT hr = D3D11CreateDeviceAndSwapChain (
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&swap_chain_desc,
&m_swap_chain,
&m_device,
NULL,
&m_context
);
ID3D11Texture2D* back_buffer;
hr = m_swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&back_buffer);
hr = m_device->CreateRenderTargetView(back_buffer, NULL, &m_view);
back_buffer->Release();
m_context->OMSetRenderTargets(1, &m_view, NULL);
D3D11_VIEWPORT viewport = { 0 };
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
if (fullscreen == 1) {
viewport.Width = window::desktop_width();
viewport.Height = window::desktop_height();
} else {
viewport.Width = window::width();
viewport.Height = window::height();
}
m_context->RSSetViewports(1, &viewport);
if (fullscreen == 1) {
m_swap_chain->SetFullscreenState(TRUE, NULL);
}
Is there anything there that might have caused this problem? The rendering code is just a ClearRenderTargetView and Present after a PeekMessage loop, nothing important.

This issue was fixed by showing the window before setting the swap chain's fullscreen state. Either call UpdateWindow(hwnd) and ShowWindow(hwnd, SW_SHOW) or set the window style to WS_VISIBLE when calling CreateWindow() or CreateWindowEx(), preferably before doing anything DirectX related.

Related

HRESULT 0x8876086c D3DERR_INVALIDCALL with DirectX9 pretty much following the documentation example

So i wanna draw an overlay over another window, but im getting no real runtime error the visual Studio debugging tools tell me that the result of
HRESULT res = object->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, &params, NULL, &device);
is 0x8876086c. So here are the snippets of my code that are important and lead to this error(D3DERR_INVALIDCALL), which leads to the device being a nullpointer, which means i can't do anything with it.
I couldn't really figure out what led to this as i pretty much followed the documentation
int Paint::init(HWND hWND) {
if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &object))) {
exit(1);
}
ZeroMemory(&params, sizeof(params));
params.BackBufferWidth = width;
params.BackBufferHeight = height;
params.Windowed = true;
params.hDeviceWindow = hWND;
params.MultiSampleQuality = D3DMULTISAMPLE_NONE;
params.BackBufferFormat = D3DFMT_A8R8G8B8;
params.EnableAutoDepthStencil = TRUE;
params.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT res = object->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, &params, NULL, &device);
and in the header file:
class Paint {
private:
IDirect3D9Ex* object = NULL;
IDirect3DDevice9Ex* device = NULL;
DWORD behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS params;
ID3DXFont* font = 0;
HWND TargetHWND;
int width, height;
int init(HWND(hWND));
}
D3DPRESENT_PARAMETERS params = {};
// Use Win32 BOOL "TRUE" instead of C++ "true"
params.Windowed = TRUE;
params.hDeviceWindow = m_window;
// params.BackBufferWidth, BackBufferHeight are ignored for Windowed = TRUE
// For Windowed = TRUE, use params.BackBufferFormat = D3DFMT_UNKNOWN, which is zero.
// For params.BackBufferCount zero is assumed to be 1, but best practice
// would be to set it
params.BackBufferCount = 1;
// You used D3DMULTISAMPLE_NONE for the MultiSampleQuality instead of MultiSampleType.
// It's all zero anyhow.
params.EnableAutoDepthStencil = TRUE;
params.AutoDepthStencilFormat = D3DFMT_D16;
// --->>> This is the actual bug: there is no valid SwapEffect that has a value of zero <<<---
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
You are making the assumption that the Direct3D9 device supports D3DCREATE_HARDWARE_VERTEXPROCESSING, but you haven't validated it actually supports it. That said, D3DCREATE_SOFTWARE_VERTEXPROCESSING has known performance issues on Windows 10 so you should probably just require HW anyhow.
You should not be using legacy Direct3D9 or Direct3D9Ex for new projects. It's mostly emulated on newer versions of Windows, has lots of strange behaviors, and is almost 20 years old at this point. There's no support for the Direct3D 9 debug device on Windows 8.x or Windows 10. You should consider Direct3D 11 as a much better starting place for developers new to DirectX.

D3D11CreateDeviceAndSwapChain fails with S_False on different computer

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.

`E_FAIL` when creating DirectX 10 Device and Swap Chain - _com_error

I am working though some simple DX tutorials, and have hit an early snag. I am working on both an old laptop and a new PC, so I'm using d3d10_1.lib which lets me use a 9 feature set. The PC, however, does support all the way to DX11, so nothing should be a problem on there.
So here's the function where it fails:
bool DirectX9Renderer::Initialise(HWND* handle)
{
//window handle
hWnd = handle;
//get window dimensions
RECT rc;
GetClientRect( *hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
//set buffer dimensions and format
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;;
//set refresh rate
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
//sampling settings
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SampleDesc.Count = 1;
//output window handle
swapChainDesc.OutputWindow = *hWnd;
swapChainDesc.Windowed = true;
HRESULT result = D3D10CreateDeviceAndSwapChain1( // this is line 57
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
D3D10_CREATE_DEVICE_SINGLETHREADED | D3D10_CREATE_DEVICE_DEBUG,
D3D10_FEATURE_LEVEL_9_1,
D3D10_1_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice
);
if(FAILED(result))
{
return FatalError("D3D device creation failed");
}
// there's more stuff after this, but I don't get that far
}
So the call to D3D10CreateDeviceAndSwapChain1 fails with the less-helpful error code E_FAIL.
There is a line in the Debug output too:
First-chance exception at 0x770f56c4 in TileTest.exe: Microsoft C++ exception: _com_error at memory location 0x00b6e8d4..
I have tried using D3D10_DRIVER_TYPE_REFERENCE and different D3D10_FEATURE_LEVEL_xx values, but it doesn't seem to work.
I think the problem may have been to do with the D3D10_CREATE_DEVICE_FLAG I sent in. I changed the D3D10_CREATE_DEVICE_SINGLETHREADED | D3D10_CREATE_DEVICE_DEBUG to 0 and it now works.
I tried to create the device inside a VMware virtual machine. It failed (device stayed NULL) until I changed the requested FEATURE_LEVEL from D3D10_FEATURE_LEVEL_10_1 to D3D10_FEATURE_LEVEL_9_3. I've heard this also helps other PCs with real hardware.

Directx 11 Bitblt Alternative

I have the following function which I am trying to integrate into my directx 11 application. When I am using directx9 everything works fine but when converting to directx 11 I am getting a blue screen of death error at the Bitblt line (I must be doing something wrong with the HDC's?). I was wondering what the best way to convert this code to directx 11 compatible surfaces instead of HDC's would be.
Here is the function:
void CFlashDXPlayer::DrawFrame(HDC dc)
{
if (m_dirtyFlag)
{
IViewObject* pViewObject = NULL;
m_flashInterface->QueryInterface(IID_IViewObject, (LPVOID*) &pViewObject);
if (pViewObject != NULL)
{
// Combine regions
HRGN unionRgn, first, second = NULL;
unionRgn = CreateRectRgnIndirect(&m_dirtyRects[0]);
if (m_dirtyRects.size() >= 2)
second = CreateRectRgn(0, 0, 1, 1);
for (std::vector<RECT>::iterator it = m_dirtyRects.begin() + 1; it != m_dirtyRects.end(); ++it)
{
// Fill combined region
first = unionRgn;
SetRectRgn(second, it->left, it->top, it->right, it->bottom);
unionRgn = CreateRectRgn(0, 0, 1, 1);
CombineRgn(unionRgn, first, second, RGN_OR);
DeleteObject(first);
}
if (second)
DeleteObject(second);
RECT clipRgnRect; GetRgnBox(unionRgn, &clipRgnRect);
RECTL clipRect = { 0, 0, m_width, m_height };
// Fill background
if (m_transpMode != TMODE_FULL_ALPHA)
{
// Set clip region
SelectClipRgn(dc, unionRgn);
COLORREF fillColor = GetBackgroundColor();
HBRUSH fillColorBrush = CreateSolidBrush(fillColor);
FillRgn(dc, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
// Draw to main buffer
HRESULT hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, dc, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
}
else
{
if (m_alphaBlackDC == NULL)
{
// Create memory buffers
BITMAPINFOHEADER bih = {0};
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biWidth = LONG(m_width);
bih.biHeight = -LONG(m_height);
m_alphaBlackDC = CreateCompatibleDC(dc);
m_alphaBlackBitmap = CreateDIBSection(m_alphaBlackDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaBlackBuffer, 0, 0);
SelectObject(m_alphaBlackDC, m_alphaBlackBitmap);
m_alphaWhiteDC = CreateCompatibleDC(dc);
m_alphaWhiteBitmap = CreateDIBSection(m_alphaWhiteDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaWhiteBuffer, 0, 0);
SelectObject(m_alphaWhiteDC, m_alphaWhiteBitmap);
}
HRESULT hr;
HBRUSH fillColorBrush;
// Render frame twice - against white and against black background to calculate alpha
SelectClipRgn(m_alphaBlackDC, unionRgn);
COLORREF blackColor = 0x00000000;
fillColorBrush = CreateSolidBrush(blackColor);
FillRgn(m_alphaBlackDC, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaBlackDC, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
// White background
SelectClipRgn(m_alphaWhiteDC, unionRgn);
COLORREF whiteColor = 0x00FFFFFF;
fillColorBrush = CreateSolidBrush(whiteColor);
FillRgn(m_alphaWhiteDC, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaWhiteDC, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
// Combine alpha
for (LONG y = clipRgnRect.top; y < clipRgnRect.bottom; ++y)
{
int offset = y * m_width * 4 + clipRgnRect.left * 4;
for (LONG x = clipRgnRect.left; x < clipRgnRect.right; ++x)
{
BYTE blackRed = m_alphaBlackBuffer[offset];
BYTE whiteRed = m_alphaWhiteBuffer[offset];
m_alphaBlackBuffer[offset + 3] = 255 - (whiteRed - blackRed);
offset += 4;
}
}
// Blit result to target DC
BitBlt(dc, clipRgnRect.left, clipRgnRect.top,
clipRgnRect.right - clipRgnRect.left,
clipRgnRect.bottom - clipRgnRect.top,
m_alphaBlackDC, clipRgnRect.left, clipRgnRect.top, SRCCOPY);
}
DeleteObject(unionRgn);
pViewObject->Release();
}
m_dirtyFlag = false;
m_dirtyRects.clear();
m_dirtyUnionRect.left = m_dirtyUnionRect.top = LONG_MAX;
m_dirtyUnionRect.right = m_dirtyUnionRect.bottom = -LONG_MAX;
}
}
The HDC I am passing to this function is created in the following manner:
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr = device->CreateTexture2D(&textureDesc, NULL, &m_flashTexture);
HRESULT hResult;
HDC hDC;
IDXGISurface1 *pSurface = NULL;
hResult = m_flashTexture->QueryInterface(__uuidof(IDXGISurface1), (void**)&pSurface);
hResult = pSurface->GetDC(TRUE, &hDC);
assert(SUCCEEDED(hResult));
m_flashPlayer->DrawFrame(hDC);
Any ideas of what I am doing wrong? I can't seem to figure out what is going on and why this is casuing a blue screen when if I use Directx 9 obejcts it doesn't. Is there a better way to do this?
(Also I've tried updating my drivers and they are all up to date).
Thank you for the help.
Turns out that this was indeed a driver issue. It works without a problem when I run with my graphics card set to the radeon in my latop, but when I have it on switchable for some reason it still crashes even though it should be selecting my radeon. I need to have the graphics mode fixed. Weird, but atleast its not my program I guess.
Can't really tell from code inspection. I haven't noticed anything blatantly wrong. There certainly should not be a any BSOD - that part is a driver bug. What hardware/driver are you running on?
A common reason for driver crashes though is illegally writing to some memory area, often if you're blitting to outside of your DC memory. I'd double check to verify that your regions are not out of bounds and that m_alphaBlackDC is the same size as dc.
I would also highly, highly recommend testing on another non-related GPU (that doesn't share the same hardware architecture).

D3D10CreateDeviceAndSwapChain() always failing with DXGI_ERROR_INVALID_CALL

I'm creating a hidden window and I'm looking to getting a pointer to IDXGISwapChain::Present(). The problem is that I can't get a valid Direct3D10 device, nor a valid swap chain.
HWND hwnd = CreateWindow(TEXT("flhiSTATIC"), TEXT("flh DXGI Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, NULL, NULL, 0);
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(scd));
scd.BufferCount = 2;
RECT rcWnd;
GetClientRect(hwnd, &rcWnd);
scd.BufferDesc.Width = rcWnd.right - rcWnd.left;
scd.BufferDesc.Height = rcWnd.bottom - rcWnd.top;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // also tried DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
scd.BufferDesc.RefreshRate.Numerator = 60;
scd.BufferDesc.RefreshRate.Denominator = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hwnd;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CREATEDEVICEANDSWAPCHAIN_PROC *>(GetProcAddress(d3d10, "D3D10CreateDeviceAndSwapChain"));
HRESULT hr = pD3D10CreateDeviceAndSwapChain(NULL /*pAdapter*/, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_DEBUG, D3D10_SDK_VERSION, &scd, &pSwapChain, &pDev);
// this guy always fails with 0 in both pSwapChain and pDev...
Any idea what might be wrong with the above code?
I completely forgot about the need to create or assign a pre-existing window class :(
That was the problem; lesson learned - always check the return codes of all the calls.
edit
I completely forgot to call CreateWindow with a valid window class, either one I'd previously registered or one that's registered by someone within the current module.