質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

2回答

3796閲覧

DirectX12でCreateSwapChainForHwndによるSwapChain作成が失敗します。

BelLwaLkeR

総合スコア8

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2020/04/07 06:05

前提・実現したいこと

DirectX12でIDXGIFactory6::CreateSwapChainForHwndによるSwapChain作成が失敗します。
なぜ失敗するかと、どこを修正するべきなのかをご教授ください。


前提として、以下の動作は確認しています。

HRESULT hresult = S_FALSE; // ■DXGIFactory作成 IDXGIFactory6* _dxgiFactory = nullptr; hresult = CreateDXGIFactory(IID_PPV_ARGS(&_dxgiFactory)); //hresult == S_OK && _dxgiFactory == 0x0005e0d0 // ■D3D12Device作成 ID3D12Device* _dev = nullptr; hresult = D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_1, IID_PPV_ARGS(&_dev)); //hresult == S_OK && _dxgiFactory == 0x00117380 // ■Windowクラス作成 WNDCLASSEX w = {}; w.cbSize = sizeof(WNDCLASSEX); w.lpfnWndProc = (WNDPROC)WindowProcedure; w.lpszClassName = _T("DX12Sample"); w.hInstance = GetModuleHandle(nullptr); RegisterClassEx(&w); RECT wrc = {0,0,720, 640}; AdjustWindowRect(&wrc, WS_OVERLAPPEDWINDOW, false); HWND hwnd = CreateWindow( w.lpszClassName, _T("Dx12テスト"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, wrc.right - wrc.left, wrc.bottom - wrc.top, nullptr, nullptr, w.hInstance, nullptr ); ShowWindow(hwnd, SW_SHOW); //ウィンドウが表示される  //whnd == 0x001909a8 && hwnd.unused == 0 // ■SwapChainDesc作成 DXGI_SWAP_CHAIN_DESC1 swapchainDesc = {}; swapchainDesc.Width = window_width; swapchainDesc.Height = window_height; swapchainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapchainDesc.Stereo = false; swapchainDesc.SampleDesc.Count = 1; swapchainDesc.SampleDesc.Quality = 0; swapchainDesc.BufferUsage = DXGI_USAGE_BACK_BUFFER; swapchainDesc.BufferCount = 2; swapchainDesc.Scaling = DXGI_SCALING_NONE; swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapchainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; swapchainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

該当のソースコード

IDXGISwapChain4* _swapchain = nullptr; hresult = _dxgiFactory->CreateSwapChainForHwnd( _cmdQueue, hwnd, &swapchainDesc, nullptr, nullptr, (IDXGISwapChain1**)&_swapchain ); //hresultは未定義となる。 //_swapchainはNULLとなる。

試したこと

_swapchainの型をIDXGISwapChain1*に変更しても、症状は変わりませんでした。
ShowWindow(hwnd,SW_SHOW);を、該当のCreateSwapChainForHwndの後に実行しても症状は変わりませんでした。
他に確認するべきところがあればご教授ください。

補足情報(FW/ツールのバージョンなど)

VisualStudio2019(v142) Ver 4.8.03761
Visual C++ 2019 - 00435-20001-35491-AA423
DirectX12 ver26.21.14.4219

参考資料
DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで
https://www.shoeisha.co.jp/book/detail/9784798161938

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

本題と逸れますが、↓は、

c++

1IDXGISwapChain4* _swapchain = nullptr; 2hresult = _dxgiFactory->CreateSwapChainForHwnd( 3 _cmdQueue, 4 hwnd, 5 &swapchainDesc, 6 nullptr, 7 nullptr, 8 (IDXGISwapChain1**)&_swapchain 9);

↓が正しいように思えますがどうでしょう?

c++

1IDXGISwapChain1* _swapchain = nullptr; 2hresult = _dxgiFactory->CreateSwapChainForHwnd( 3 _cmdQueue, 4 hwnd, 5 &swapchainDesc, 6 nullptr, 7 nullptr, 8 &_swapchain 9); 10IDXGISwapChain4* _swapchain4; 11_swapchain->QueryInterface( IID_PPV_ARGS( &this->spIDXGISwapChain4 ) );

CreateSwapChainForHwnd() は IDXGISwapChain4 の CoClass を作る(つまり仮想関数表の内容が IDXGISwapChain4 のメンバ関数群になる)保証が無いからです。故に引数型が IDXGISwapChain1** になっているのだと思います。CreateSwapChainForHwnd() が様々なCOMインターフェース型を得られる仕様だとしたら、IUnknown::QueryInterface(REFIID,void**) と同じ仮引数型になっている筈です。

CreateSwapChainForHwnd() で IDXGISwapChain4 を得てそれ固有の仮想関数 SetHDRMetaData() を呼んだら動きました。ので、内部で IDXGISwapChain4 の CoClass を new して返している事が分かります。
が偶然に過ぎず、COMの作法に沿っていないです。ので QueryInterface() を使って堅牢なコードにするのが正しく思えます。

投稿2024/09/02 15:55

ButaDon

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

解決しました。
swapchainDesc.SwapEffectの値をDXGI_SWAP_EFFECT_DISCARDからDXGI_SWAP_EFFECT_FLIP_DISCARDにしたら成功しました。

ドキュメントを見ると、UWPをターゲットにしているときはDXGI_SWAP_EFFECT_DISCARDもしくはDXGI_SWAP_EFFECT_SEQUENTIALではなく、DXGI_EFFECT_FLIPDISCARDもしくはDXGI_EFFECTFLIP_SEQUENTIALでなければいけないようです。

UWPをターゲットにしたつもりはなかったのですが、参考までに。

参考URL:DXGI_SWAP_EFFECT enumeration
https://docs.microsoft.com/ja-jp/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_effect

投稿2020/04/17 07:44

BelLwaLkeR

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問