void Close() { // we can't release the swapchain while in fullscreen. swapchain->SetFullscreenState(false, nullptr); // release all bound resources context->ClearState(); SAFE_RELEASE(backbuf); SAFE_RELEASE(swapchain); SAFE_DELETE(stateman); context->Flush(); // immediately destroy device objects SAFE_RELEASE(context); ULONG references = device->Release(); if (references) { ERROR_LOG(VIDEO, "Unreleased references: %i.", references); } else { NOTICE_LOG(VIDEO, "Successfully released all device references!"); } device = nullptr; // unload DLLs UnloadD3D(); UnloadDXGI(); }
void Close() { // release all bound resources context->ClearState(); SAFE_RELEASE(backbuf); SAFE_RELEASE(swapchain); SAFE_DELETE(stateman); context->Flush(); // immediately destroy device objects SAFE_RELEASE(context); ULONG references = device->Release(); if (references) { ERROR_LOG(VIDEO, "Unreleased references: %i.", references); } else { NOTICE_LOG(VIDEO, "Successfully released all device references!"); } device = NULL; // unload DLLs UnloadD3DX(); UnloadD3D(); UnloadDXGI(); }
void Close() { // we can't release the swapchain while in fullscreen. swapchain->SetFullscreenState(false, nullptr); // release all bound resources context->ClearState(); SAFE_RELEASE(backbuf); SAFE_RELEASE(swapchain); SAFE_DELETE(stateman); context->Flush(); // immediately destroy device objects SAFE_RELEASE(context); ULONG references = device->Release(); #if defined(_DEBUG) || defined(DEBUGFAST) if (debug) { --references; // the debug interface increases the refcount of the device, subtract that. if (references) { // print out alive objects, but only if we actually have pending references // note this will also print out internal live objects to the debug console debug->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL); } SAFE_RELEASE(debug) } #endif if (references) { ERROR_LOG(VIDEO, "Unreleased references: %i.", references); } else { NOTICE_LOG(VIDEO, "Successfully released all device references!"); } device = nullptr; // unload DLLs UnloadD3D(); UnloadDXGI(); }
HRESULT Create(HWND wnd) { hWnd = wnd; HRESULT hr; RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DCompiler(); return hr; } IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs!\n") _T("This usually happens when you've set your video adapter to the Nvidia GPU in an Optimus-equipped system.\n") _T("Set Dolphin to use the high-performance graphics in Nvidia's drivers instead and leave Dolphin's video adapter set to the Intel GPU."), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes aa_modes = EnumAAModes(adapter); if (g_Config.iMultisampleMode >= (int)aa_modes.size()) { g_Config.iMultisampleMode = 0; UpdateActiveConfig(); } DXGI_SWAP_CHAIN_DESC swap_chain_desc; memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = !g_ActiveConfig.bFullscreen; DXGI_OUTPUT_DESC out_desc; memset(&out_desc, 0, sizeof(out_desc)); output->GetDesc(&out_desc); DXGI_MODE_DESC mode_desc; memset(&mode_desc, 0, sizeof(mode_desc)); mode_desc.Width = out_desc.DesktopCoordinates.right - out_desc.DesktopCoordinates.left; mode_desc.Height = out_desc.DesktopCoordinates.bottom - out_desc.DesktopCoordinates.top; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, nullptr); if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); if (swap_chain_desc.Windowed) { // forcing buffer resolution to xres and yres.. // this is not a problem as long as we're in windowed mode swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; } #if defined(_DEBUG) || defined(DEBUGFAST) // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) #endif { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) { MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } // prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER // does not work so we disable all monitoring of window messages. However this // may make it more difficult for DXGI to handle display mode changes. hr = factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); if (FAILED(hr)) MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); SAFE_RELEASE(buf); CHECK(backbuf!=nullptr, "Create back buffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), nullptr); // BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; stateman = new StateManager; return S_OK; }
HRESULT Create(HWND wnd) { hWnd = wnd; HRESULT hr; RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DX(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DX(); UnloadD3DCompiler(); return hr; } IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes aa_modes = EnumAAModes(adapter); if (g_Config.iMultisampleMode >= (int)aa_modes.size()) { g_Config.iMultisampleMode = 0; UpdateActiveConfig(); } DXGI_SWAP_CHAIN_DESC swap_chain_desc; memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = TRUE; DXGI_MODE_DESC mode_desc; memset(&mode_desc, 0, sizeof(mode_desc)); mode_desc.Width = xres; mode_desc.Height = yres; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL); if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); // forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported! swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; #if defined(_DEBUG) || defined(DEBUGFAST) // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) #endif { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) { MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); SAFE_RELEASE(buf); CHECK(backbuf!=NULL, "Create back buffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL); // BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; stateman = new StateManager; return S_OK; }
HRESULT Create(HWND wnd) { HRESULT hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DCompiler(); return hr; } hr = PCreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)&s_dxgi_factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); IDXGIAdapter* adapter; hr = s_dxgi_factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = s_dxgi_factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes s_aa_modes = EnumAAModes(adapter); if (std::find_if(s_aa_modes.begin(), s_aa_modes.end(), [](const DXGI_SAMPLE_DESC& desc) { return desc.Count == g_Config.iMultisamples; }) == s_aa_modes.end()) { Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1)); UpdateActiveConfig(); } // Check support for allow tearing, we query the interface for backwards compatibility UINT allow_tearing = FALSE; IDXGIFactory5* factory5; hr = s_dxgi_factory->QueryInterface(&factory5); if (SUCCEEDED(hr)) { hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing, sizeof(allow_tearing)); factory5->Release(); } s_allow_tearing_supported = SUCCEEDED(hr) && allow_tearing; // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. if (g_Config.bEnableValidationLayer) { hr = s_d3d11_create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &device, &s_featlevel, &context); // Debugbreak on D3D error if (SUCCEEDED(hr) && SUCCEEDED(device->QueryInterface(__uuidof(ID3D11Debug), (void**)&s_debug))) { ID3D11InfoQueue* infoQueue = nullptr; if (SUCCEEDED(s_debug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue))) { infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); D3D11_MESSAGE_ID hide[] = {D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS}; D3D11_INFO_QUEUE_FILTER filter = {}; filter.DenyList.NumIDs = sizeof(hide) / sizeof(D3D11_MESSAGE_ID); filter.DenyList.pIDList = hide; infoQueue->AddStorageFilterEntries(&filter); infoQueue->Release(); } } } if (!g_Config.bEnableValidationLayer || FAILED(hr)) { hr = s_d3d11_create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &device, &s_featlevel, &context); } SAFE_RELEASE(adapter); if (FAILED(hr) || (wnd && !CreateSwapChain(wnd))) { MessageBox( wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(s_dxgi_factory); return E_FAIL; } hr = device->QueryInterface<ID3D11Device1>(&device1); if (FAILED(hr)) { WARN_LOG(VIDEO, "Missing Direct3D 11.1 support. Logical operations will not be supported."); g_Config.backend_info.bSupportsLogicOp = false; } // BGRA textures are easier to deal with in TextureCache, but might not be supported UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); s_bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device); g_Config.backend_info.bSupportsBPTCTextures = SupportsBPTCTextures(device); // prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER // does not work so we disable all monitoring of window messages. However this // may make it more difficult for DXGI to handle display mode changes. if (wnd) { hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); if (FAILED(hr)) MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } SetDebugObjectName(context, "device context"); stateman = new StateManager; return S_OK; }