I'm trying to create a DXGI swapchain for a window created by SDL2 (v2.0.18), but every time I call the IDXGIFactory5::CreateSwapChainForHwnd
method, I get the E_INVALIDARG
error.
First, I create the SDL window.
Then I go about creating the swapchain, following these steps:
I'll now share the code I'm using to accomplish these steps
int posX = 0, int posY = 0, int width = 1920, int height = 1080;
// Init video subsystem
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s",
SDL_GetError());
return false;
}
window = SDL_CreateWindow("H264 HW Decoding with D3D11 Rendering to SDL window",
posX,
posY,
width,
height,
SDL_WINDOW_ALLOW_HIGHDPI
);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_CreateWindow() failed: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
if (!SDL_DXGIGetOutputInfo(SDL_GetWindowDisplayIndex(params->window),
&adapterIndex, &outputIndex))
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_DXGIGetOutputInfo() failed: %s",
SDL_GetError());
return false;
}
IDXGIFactory5* Factory = nullptr;
bool success = false;
IDXGIAdapter1* adapter = nullptr;
HRESULT hr;
hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG ,__uuidof(IDXGIFactory5), (void**)&Factory);
assert(!FAILED(hr));
hr = Factory->EnumAdapters1(adapterIndex, &adapter);
if (FAILED(hr))
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"IDXGIFactory::EnumAdapters1() failed: %x",
hr);
goto Exit;
}
hr = adapter->GetDesc1(&adapterDesc);
if (FAILED(hr))
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"IDXGIAdapter::GetDesc() failed: %x",
hr);
goto Exit;
}
if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
{
// Skip the WARP device. We know it will fail.
goto Exit;
}
hr = D3D11CreateDevice(adapter,
D3D_DRIVER_TYPE_UNKNOWN,
nullptr,
D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
nullptr,
0,
D3D11_SDK_VERSION,
&Device,
nullptr,
&DeviceContext);
// Fill the swapchain description structure
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
swapChainDesc.Flags = 0;
swapChainDesc.BufferCount = 5;
// Use the current window size as the swapchain size
SDL_GetWindowSize(window, (int*)&swapChainDesc.Width, (int*)&swapChainDesc.Height);
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
// Get the HWND from SDL
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(params->window, &info);
SDL_assert(info.subsystem == SDL_SYSWWINDOWS);
assert(IsWindow(info.info.win.window));
// Create the swapchain and associate it to the SDL window
IDXGISwapChain1* swapChain;
hr = Factory->CreateSwapChainForHwnd(Device,
info.info.win.window,
&swapChainDesc,
nullptr,
nullptr,
&swapChain);
I've turned the DXGI debug layer on, and this is the output from it
D3D11 INFO: Create ID3D11Context: Name="unnamed", Addr=0x000001B3F7978990, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097225: CREATE_CONTEXT]
D3D11 INFO: Create ID3DDeviceContextState: Name="unnamed", Addr=0x000001B3F7996B50, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #3145735: CREATE_DEVICECONTEXTSTATE]
D3D11 INFO: Create ID3D11BlendState: Name="unnamed", Addr=0x000001B3F79963A0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097270: CREATE_BLENDSTATE]
D3D11 INFO: Create ID3D11DepthStencilState: Name="unnamed", Addr=0x000001B3F79965E0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097273: CREATE_DEPTHSTENCILSTATE]
D3D11 INFO: Create ID3D11RasterizerState: Name="unnamed", Addr=0x000001B3F79A1F00, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097276: CREATE_RASTERIZERSTATE]
D3D11 INFO: Create ID3D11Sampler: Name="unnamed", Addr=0x000001B3F79A2140, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097267: CREATE_SAMPLER]
D3D11 INFO: Create ID3D11Query: Name="unnamed", Addr=0x000001B3F79A2380, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097279: CREATE_QUERY]
D3D11 INFO: Create ID3D11Fence: Name="unnamed", Addr=0x000001B3F79A2600, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #3146250: CREATE_FENCE]
D3D11 INFO: Destroy ID3D11Fence: Name="unnamed", Addr=0x000001B3F79A2600 [ STATE_CREATION INFO #3146252: DESTROY_FENCE]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA034FF0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035430, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035870, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035CB0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA0360F0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA0870F0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA08B540, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA08B980, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA08C1D0, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA08C610, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097234: CREATE_TEXTURE2D]
D3D11 INFO: Create ID3D11Fence: Name="unnamed", Addr=0x000001B3FA04E870, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #3146250: CREATE_FENCE]
D3D11 INFO: Create ID3D11Fence: Name="unnamed", Addr=0x000001B3FA090370, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #3146250: CREATE_FENCE]
D3D11 INFO: Destroy ID3D11Fence: Name="unnamed", Addr=0x000001B3FA04E870 [ STATE_CREATION INFO #3146252: DESTROY_FENCE]
D3D11 INFO: Destroy ID3D11Fence: Name="unnamed", Addr=0x000001B3FA090370 [ STATE_CREATION INFO #3146252: DESTROY_FENCE]
Exception thrown at 0x00007FFD803AFE7C in decode_video_ffmpeg_example.exe: Microsoft C++ exception: _com_error at memory location 0x00000079E9AFEF88.
Exception thrown at 0x00007FFD803AFE7C in decode_video_ffmpeg_example.exe: Microsoft C++ exception: _com_error at memory location 0x00000079E9AFF000.
D3D11 INFO: Destroy ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA034FF0 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035430 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035870 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA035CB0 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="unnamed", Addr=0x000001B3FA0360F0 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="DXGI cross-adapter flip proxy (dGPU opened)", Addr=0x000001B3FA0870F0 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="DXGI cross-adapter flip proxy (dGPU opened)", Addr=0x000001B3FA08B540 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="DXGI cross-adapter flip proxy (dGPU opened)", Addr=0x000001B3FA08B980 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="DXGI cross-adapter flip proxy (dGPU opened)", Addr=0x000001B3FA08C1D0 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
D3D11 INFO: Destroy ID3D11Texture2D: Name="DXGI cross-adapter flip proxy (dGPU opened)", Addr=0x000001B3FA08C610 [ STATE_CREATION INFO #2097236: DESTROY_TEXTURE2D]
The DirectX11 debug layer output is juts the following message
E_INVALIDARG One or more arguments are invalid.
IDXGIFactory2
and IDXGIFactory3
)D3D11Device
(like D3D_DRIVER_TYPE_HARDWARE
and D3D_DRIVER_TYPE_REFERENCE
)SDL_CreateWindow
, creating a native window with these style flags WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
, and then creating the SDL window using the SDL_CreateWindowFrom
functionCreateSwapchainForHwnd
is used. This program gives me no problems; the method executes successfully and the window is displayed correctlyDXGI_SWAP_CHAIN_DESC1
structure (output format, swap effect, scaling, buffer count, window size)OS: Windows 11
Processor: AMD Ryzen 9 5900HX with Radeon Graphics
Graphic Adapters: NVIDIA RTX3060 Laptop GPU; AMD Radeon Graphics (integrated)
I've solved my problem. It had nothing to do with SDL or the parameters of the swapchain.
There was an old version of dxgi.dll
file in the same directory as the compiled project. This DLL was not compatible with my sample project. After removing this file the code executed correctly. Embarrassing...