none
DirectX 11のデバイスの作成ができない

    質問

  • ソースコードはこちらです。

    https://github.com/Shirley-Chan/GetGPU/blob/master/GetGPU/ExeVersion/Main.cpp

    D3D11CreateDevice関数の第2引数にD3D_DRIVER_TYPE_HARDWAREを与えると、hrにE_INVALIDARGの値が入ってしまい、これをD3D_DRIVER_TYPE_UNKNOWNに切り替えたらS_OKになってしまいます。

    この原因は何なんでしょうか?

    ちなみにデバッグを行っているPCのグラフィックスアダプターは

    Intel HD Graphics 630

    NVIDIA GeForce GTX 1060

    の2つです。

    2018年4月11日 10:04

すべての返信

  • D3D11CreateDeviceドキュメントのRemarksセクションにある通りではないでしょうか?

    In Direct3D 11, if you are trying to create a hardware or a software device, set pAdapter != NULL which constrains the other inputs to be:

    • DriverType must be D3D_DRIVER_TYPE_UNKNOWN

    第1引数pAdapter != NULL の場合は第2引数DriverTypeはD3D_DRIVER_TYPE_UNKNOWNでなければならないと記されています。

    なお、前スレッドで解決後に指摘していますがComPtrの使い方が間違っているため永久に解放されることがない箇所があります。あと気が向いたの書いたコードがあるので貼り付けておきます。

    #include <filesystem>	// std::experimental::filesystem::path, std::experimental::filesystem::current_path
    #include <optional>		// std::optional
    #include <string>		// std::char_traits
    #include <wrl/client.h>
    #include <dxgi.h>
    #pragma comment(lib, "dxgi.lib")
    #if __has_include(<d3d12.h>)
    #include <d3d12.h>
    #endif
    #include <d3d11.h>
    #pragma comment(lib, "d3d11.lib")
    #include <xmllite.h>
    #pragma comment(lib, "xmllite.lib")
    #include <Shlwapi.h>
    #pragma comment(lib, "Shlwapi.lib")
    namespace fs = std::experimental::filesystem;
    template<class T> using ComPtr = Microsoft::WRL::ComPtr<T>;
    
    static inline void check(HRESULT hr) {
    	if (FAILED(hr))
    		throw std::runtime_error{ "error" };
    }
    
    static std::optional<D3D_FEATURE_LEVEL> TryCreate(ComPtr<IDXGIAdapter1>& adapter) {
    	static const D3D_FEATURE_LEVEL levels[]{
    #ifdef __d3d12_h__
    		D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0,
    #endif
    		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,
    	};
    
    #ifdef __d3d12_h__
    	static const auto d3d12CreateDevice = [] {
    		auto d3d12 = LoadLibraryW(L"d3d12.dll");
    		return d3d12 ? reinterpret_cast<PFN_D3D12_CREATE_DEVICE>(GetProcAddress(d3d12, "D3D12CreateDevice")) : nullptr;
    	}();
    	if (d3d12CreateDevice) {
    		for (auto level : levels)
    			if (SUCCEEDED(d3d12CreateDevice(adapter.Get(), level, __uuidof(ID3D12Device), nullptr)))
    				return level;
    	} else
    #endif
    	if (D3D_FEATURE_LEVEL level; SUCCEEDED(D3D11CreateDevice(adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, levels, UINT(std::size(levels)), D3D11_SDK_VERSION, nullptr, &level, nullptr)))
    		return level;
    	return std::nullopt;
    }
    
    static constexpr double ToDouble(const D3D_FEATURE_LEVEL level) {
    	return level / 0x1000 + level % 0x1000 / 0x0100 / 10.0;
    }
    static_assert(ToDouble(D3D_FEATURE_LEVEL_11_1) == 11.1);
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int) {
    	try {
    		auto const path = 0 < std::char_traits<TCHAR>::length(lpCmdLine) ? fs::path{ lpCmdLine } : fs::current_path();
    		ComPtr<IStream> stream;
    		check(SHCreateStreamOnFileEx((path / L"gpu.xml").c_str(), STGM_CREATE | STGM_WRITE, 0, 0, nullptr, &stream));
    		ComPtr<IXmlWriter> writer;
    		check(CreateXmlWriter(IID_PPV_ARGS(&writer), nullptr));
    		check(writer->SetOutput(stream.Get()));
    		check(writer->SetProperty(XmlWriterProperty_Indent, true));
    		check(writer->WriteStartDocument(XmlStandalone_Omit));
    		check(writer->WriteStartElement(nullptr, L"gpulist", nullptr));
    
    		ComPtr<IDXGIFactory1> factory;
    		check(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
    		auto found = false;
    		for (unsigned int index = 0;; index++) {
    			ComPtr<IDXGIAdapter1> adapter;
    			auto result = factory->EnumAdapters1(index, &adapter);
    			if (result == DXGI_ERROR_NOT_FOUND)
    				break;
    			check(result);
    			DXGI_ADAPTER_DESC1 desc;
    			check(adapter->GetDesc1(&desc));
    			if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
    				continue;
    			if (auto level = TryCreate(adapter)) {
    				found = true;
    				check(writer->WriteStartElement(nullptr, L"gpuinfo", nullptr));
    				check(writer->WriteElementString(nullptr, L"name", nullptr, desc.Description));
    				check(writer->WriteElementString(nullptr, L"dedicatedvideomemory", nullptr, std::to_wstring(desc.DedicatedVideoMemory).c_str()));
    				check(writer->WriteElementString(nullptr, L"dedicatedsystemmemory", nullptr, std::to_wstring(desc.DedicatedSystemMemory).c_str()));
    				check(writer->WriteElementString(nullptr, L"sharedsystemmemory", nullptr, std::to_wstring(desc.SharedSystemMemory).c_str()));
    				check(writer->WriteElementString(nullptr, L"hardwareid", nullptr, std::to_wstring(index).c_str()));
    				check(writer->WriteElementString(nullptr, L"maxfeaturelevel", nullptr, std::to_wstring(ToDouble(*level)).c_str()));
    				check(writer->WriteEndElement());
    			}
    		}
    		if (!found)
    			throw std::runtime_error{ "This computer is installed no hardware device compatibled DirectX use hardware adapter.Warning : This tool can not judge compatibled warp device mode." };
    
    		check(writer->WriteEndElement());
    		check(writer->WriteEndDocument());
    		check(writer->Flush());
    	}
    	catch (const std::exception& e) {
    		return MessageBoxA(NULL, e.what(), "エラー", MB_ICONERROR | MB_OK);
    	}
    	return 0;
    }
    2018年4月11日 10:33
  • 引数の件

    完全に見落としてた&忘れてました

    最後に1からDirectX叩いたのもう3年くらい前で、それからはずっとライブラリ化したもの使ってたので…

    そしてそのコードは今どこのフォルダにあるのか分からなくなってしまってますし…(単にデータ整理が下手なだけ)

    ComPtrの件について

    久々にMSDNフォーラム来たので今気づきました。本日中に対応します。

    2018年4月11日 11:12
  • shirley-chan さん、こんにちは。フォーラム オペレーターの立花です。
    MSDN フォーラムへのご投稿ありがとうございます。

    フォーラム オペレーターからのお願いです。

    同じ問題であとから参照された方が情報をすぐに得られるように
    参考となった投稿には [回答としてマーク] をご設定ください。
    回答いただいた方のモチベーションの向上にもつながります。

    ご協力のほど、どうぞよろしくお願いいたします。

    あと、回答いただいたらお礼も記載してくださいね。


    参考になった投稿には回答としてマークの設定にご協力ください
    MSDN/TechNet Community Support 立花楓

    2018年4月12日 0:46
    モデレータ