// Initialize the DirectX resources required to run.
void Graphics::Initialize(void)
{
    ASSERT(s_SwapChain1 == nullptr, "Graphics has already been initialized");

    Microsoft::WRL::ComPtr<ID3D12Device> pDevice;

#if _DEBUG
    Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface;
    if (SUCCEEDED(D3D12GetDebugInterface(MY_IID_PPV_ARGS(&debugInterface))))
        debugInterface->EnableDebugLayer();
    else
        Utility::Print("WARNING:  Unable to enable D3D12 debug validation layer\n");
#endif

#ifdef DXIL
    EnableExperimentalShaderModels();
#endif

    // Obtain the DXGI factory
    Microsoft::WRL::ComPtr<IDXGIFactory4> dxgiFactory;
    ASSERT_SUCCEEDED(CreateDXGIFactory2(0, MY_IID_PPV_ARGS(&dxgiFactory)));

    // Create the D3D graphics device
    Microsoft::WRL::ComPtr<IDXGIAdapter1> pAdapter;

    static const bool bUseWarpDriver = false;

    if (!bUseWarpDriver)
    {
        SIZE_T MaxSize = 0;

        for (uint32_t Idx = 0; DXGI_ERROR_NOT_FOUND != dxgiFactory->EnumAdapters1(Idx, &pAdapter); ++Idx)
        {
            DXGI_ADAPTER_DESC1 desc;
            pAdapter->GetDesc1(&desc);
            if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
                continue;

            if (desc.DedicatedVideoMemory > MaxSize && SUCCEEDED(D3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, MY_IID_PPV_ARGS(&pDevice))))
            {
                pAdapter->GetDesc1(&desc);
                Utility::Printf(L"D3D12-capable hardware found:  %s (%u MB)\n", desc.Description, desc.DedicatedVideoMemory >> 20);
                MaxSize = desc.DedicatedVideoMemory;
            }
        }
예제 #2
0
void Scene::onInit()
{
	this->mpZBufferDSV.Reset();
	this->mpZBuffer.Reset();
	this->mpBackBufferRTV.Reset();
	this->mpBackBuffer.Reset();
	this->mpImmediateContext.Reset();
	this->mpDevice.Reset();
	this->mpSwapChain.Reset();

	//デバイスなどを作り直す

	//DXGIを使う上で必要となるIDXGIFactory1を作成
	HRESULT hr;
	Microsoft::WRL::ComPtr<IDXGIFactory1> pFactory;
	hr = CreateDXGIFactory1(IID_PPV_ARGS(pFactory.GetAddressOf()));
	if (FAILED(hr)) {
		throw std::runtime_error("IDXGIFactoryクラスの作成に失敗しました。");
	}

	//GPUアダプターを列挙して一番最初に見つかった使えるものを選ぶ
	Microsoft::WRL::ComPtr<IDXGIAdapter1> pAdapterIt;
	for (UINT adapterIndex = 0; S_OK == pFactory->EnumAdapters1(adapterIndex, pAdapterIt.GetAddressOf());  ++adapterIndex) {
		DXGI_ADAPTER_DESC1 desc;
		pAdapterIt->GetDesc1(&desc);
		OutputDebugStringA(  std::string("adapter " + std::to_string(adapterIndex) + "\n").c_str());
		OutputDebugStringW((std::wstring(L"  decription =  ") + desc.Description + L"\n").c_str());
		OutputDebugStringA(  std::string("  VemdorId =  " + std::to_string(desc.VendorId) + "\n").c_str());
		OutputDebugStringA(  std::string("  DeviceId =  " + std::to_string(desc.DeviceId) + "\n").c_str());
		OutputDebugStringA(  std::string("  SubSysId =  " + std::to_string(desc.SubSysId) + "\n").c_str());
		OutputDebugStringA(  std::string("  Revision =  " + std::to_string(desc.Revision) + "\n").c_str());
		OutputDebugStringA(  std::string("  DedicatedVideoMemory =  " + std::to_string(desc.DedicatedVideoMemory) + "\n").c_str());
		OutputDebugStringA(  std::string("  DedicatedSystemMemory =  " + std::to_string(desc.DedicatedSystemMemory) + "\n").c_str());
		OutputDebugStringA(  std::string("  SharedSystemMemory =  " + std::to_string(desc.SharedSystemMemory) + "\n").c_str());
		OutputDebugStringA(  std::string("  AdapterLuid =  high:" + std::to_string(desc.AdapterLuid.HighPart) + " low:" + std::to_string(desc.AdapterLuid.LowPart) + "\n").c_str());
		OutputDebugStringA(  std::string("  Flag = " + std::to_string(desc.Flags) + "\n").c_str());

		if (nullptr == this->mpAdapter) {
			if (desc.Flags ^= DXGI_ADAPTER_FLAG_SOFTWARE) {
				this->mpAdapter = pAdapterIt;
				OutputDebugStringA(std::string("このアダプターを使用します。 adapterIndex = " + std::to_string(adapterIndex) + "\n").c_str());
			}

			//期待通りに動作してくれなかった
			//LARGE_INTEGER version;
			//hr = pAdapterIt->CheckInterfaceSupport(__uuidof(ID3D11Device), &version);
			//DXGI_ERROR_UNSUPPORTED;
			//if (S_OK == hr) {
			//	pAdapter = pAdapterIt;
			//	OutputDebugStringA(std::string("このアダプターを使用します。 adapterIndex = " + std::to_string(adapterIndex) + "\n").c_str());
			//}
		}

		//使い終わったら必ずReleaseすること
		pAdapterIt.Reset();
	}

	//ID3D11DeviceとID3D11DeviceContextの作成
	std::array<D3D_FEATURE_LEVEL, 3> featureLevels = { {
			D3D_FEATURE_LEVEL_11_0,
			D3D_FEATURE_LEVEL_10_1,
			D3D_FEATURE_LEVEL_10_0
		} };
	UINT flags = 0;
#ifdef _DEBUG
	flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
	D3D_FEATURE_LEVEL usedLevel;
	hr = D3D11CreateDevice(
		this->mpAdapter.Get(),
		D3D_DRIVER_TYPE_UNKNOWN,
		nullptr,
		flags,
		featureLevels.data(),
		static_cast<UINT>(featureLevels.size()),
		D3D11_SDK_VERSION,
		this->mpDevice.GetAddressOf(),
		&usedLevel,
		this->mpImmediateContext.GetAddressOf()
		);

	if (FAILED(hr)) {
		throw std::runtime_error("ID3D11Deviceの作成に失敗。");
	}

	//IDXGISwapChainの作成
	DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
	swapChainDesc.OutputWindow = Win32Application::hwnd();
	swapChainDesc.BufferCount = 2;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;

	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	//swapChainDesc.Flags = 0;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	//フルスクリーンとウィンドモードの切り替えがしたい場合は、まずウィンドウモードとして生成することを推奨しているみたい
	//https://msdn.microsoft.com/en-us/library/bb174579(v=vs.85).aspx
	swapChainDesc.Windowed = true;

	//希望する画面設定
	swapChainDesc.BufferDesc.Width = this->width();
	swapChainDesc.BufferDesc.Height = this->height();
	swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
	swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
	swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

	//上の画面設定に一番近いものを調べる
	Microsoft::WRL::ComPtr<IDXGIOutput> pOutput;
	if (DXGI_ERROR_NOT_FOUND == this->mpAdapter->EnumOutputs(0, pOutput.GetAddressOf())) {
		throw std::runtime_error("アダプターの出力先が見つかりません。");
	}
	DXGI_MODE_DESC modeDesc;
	hr = pOutput->FindClosestMatchingMode(&swapChainDesc.BufferDesc, &modeDesc, this->mpDevice.Get());
	if (FAILED(hr)) {
		throw std::runtime_error("表示モードの取得に失敗");
	}
	//IDXGISwapChainの作成
	swapChainDesc.BufferDesc = modeDesc;
	hr = pFactory->CreateSwapChain(this->mpDevice.Get(), &swapChainDesc, this->mpSwapChain.GetAddressOf());
	if (FAILED(hr)) {
		throw std::runtime_error("IDXGISwapChainの作成に失敗");
	}

	//ディスプレイの画面モードの一覧を取得する
	//IDXGIOutput* pOutput;
	//this->mpSwapChain->GetContainingOutput(&pOutput);
	//UINT num;
	//UINT flag = DXGI_ENUM_MODES_INTERLACED;
	//pOutput->GetDisplayModeList(swapChainDesc.BufferDesc.Format, flag, &num, nullptr);
	//std::vector<DXGI_MODE_DESC> modeDesces;
	//modeDesces.resize(num);
	//pOutput->GetDisplayModeList(swapChainDesc.BufferDesc.Format, flag, &num, &modeDesces[0]);
	//pOutput->Release();

	//
	//	後はバックバッファのレンダーターゲットビューの作成、必要ならZバッファの作成とビューポートの設定を行う
	//
	initRenderTargetAndDepthStencil(swapChainDesc.BufferDesc.Width, swapChainDesc.BufferDesc.Height);
}