From 9a76be6edc53bb6ebfb6eb5a8258b086069a8921 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 14 Jun 2010 19:20:41 +0000 Subject: [PATCH] Add proper adapter enumeration in the DX11 plugin. Set default video mode format to DXGI_FORMAT_R8G8B8A8_UNORM. This might fix FRAPS recording, but also decrease FPS; test both, please. Add numerous TODOs git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5695 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_VideoDX11/Plugin_VideoDX11.vcproj | 12 ++-- .../Plugins/Plugin_VideoDX11/Src/D3DBase.cpp | 62 ++++++++++++++----- .../Plugin_VideoDX11/Src/D3DTexture.cpp | 7 ++- .../Plugin_VideoDX11/Src/DlgSettings.cpp | 54 ++++++++++++++-- .../Plugin_VideoDX11/Src/EmuWindow.cpp | 1 + .../Plugin_VideoDX11/Src/FBManager.cpp | 8 +-- .../Plugins/Plugin_VideoDX11/Src/resource.h | 2 +- .../Plugins/Plugin_VideoDX11/Src/resource.rc | 20 +++--- 8 files changed, 124 insertions(+), 42 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj index 89bfba3d5f..da59800ec8 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj @@ -91,7 +91,7 @@ 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 adapter"), _T("Dolphin Direct3D 11 plugin"), 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 output"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR); + } + + // this will need to be changed once multisampling gets implemented + 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 plugin"), MB_OK | MB_ICONERROR); +// TODO: Enable these two lines, they're breaking stuff for SOME reason right now +// xres = swap_chain_desc.BufferDesc.Width; +// yres = swap_chain_desc.BufferDesc.Height; #if defined(_DEBUG) || defined(DEBUGFAST) D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED); #else D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED; #endif - hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, device_flags, NULL, 0, D3D11_SDK_VERSION, &sd, &swapchain, &device, &featlevel, &context); + hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); if (FAILED(hr) || !device || !context || !swapchain) { MessageBox(wnd, _T("Failed to initialize Direct3D."), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR); @@ -305,6 +336,9 @@ HRESULT Create(HWND wnd) return E_FAIL; } SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); + factory->Release(); + output->Release(); + adapter->Release(); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp index 266c97d25a..d554db5a56 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp @@ -42,11 +42,12 @@ void ReplaceTexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int } else if (usage == D3D11_USAGE_DEFAULT) { - if (texbufsize < 4*width*height) + if (texbufsize < 4*4*pitch*height) { + // TODO: This memory needs to be freed as well.. if (texbuf) delete[] texbuf; - texbuf = new char[4*width*height]; - texbufsize = 4*width*height; + texbuf = new char[4*4*pitch*height]; + texbufsize = 4*4*pitch*height; } outptr = (void*)texbuf; destPitch = width * 4; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp index 17d6785a0f..2766833e50 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include #include #include "resource.h" @@ -22,10 +23,9 @@ #include "FileUtil.h" #include "D3DBase.h" - #include "VideoConfig.h" - #include "TextureCache.h" +using std::vector; const char* aspect_ratio_names[4] = { "Auto", @@ -34,13 +34,54 @@ const char* aspect_ratio_names[4] = { "Stretch to Window", }; +vector CreateAdapterList() +{ + vector adapters; + IDXGIFactory* factory; + IDXGIAdapter* ad; + HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); + if (FAILED(hr)) MessageBox(NULL, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR); + + while (factory->EnumAdapters(adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND) + adapters.push_back(ad); + + if (adapters.size() == 0) MessageBox(NULL, _T("Couldn't find any devices!"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR); + factory->Release(); + return adapters; +} + +void DestroyAdapterList(vector &adapters) +{ + while (!adapters.empty()) + { + adapters.back()->Release(); + adapters.pop_back(); + } +} + struct TabDirect3D : public W32Util::Tab { void Init(HWND hDlg) { WCHAR tempwstr[2000]; + HRESULT hr; - for (int i = 0; i < 4; i++) + vector adapters = CreateAdapterList(); + for (vector::iterator it = adapters.begin();it != adapters.end();++it) + { + DXGI_ADAPTER_DESC desc; + hr = (*it)->GetDesc(&desc); + if (SUCCEEDED(hr)) ComboBox_AddString(GetDlgItem(hDlg, IDC_ADAPTER), desc.Description); + else + { + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "Unknown device", -1, tempwstr, 2000); + ComboBox_AddString(GetDlgItem(hDlg, IDC_ADAPTER), tempwstr); + } + } + DestroyAdapterList(adapters); + ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ADAPTER), g_Config.iAdapter); + + for (unsigned int i = 0; i < 4; i++) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aspect_ratio_names[i], -1, tempwstr, 2000); ComboBox_AddString(GetDlgItem(hDlg, IDC_ASPECTRATIO), tempwstr); @@ -80,6 +121,9 @@ struct TabDirect3D : public W32Util::Tab case IDC_ASPECTRATIO: g_Config.iAspectRatio = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ASPECTRATIO)); break; + case IDC_ADAPTER: + g_Config.iAdapter = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ADAPTER)); + break; case IDC_VSYNC: g_Config.bVSync = Button_GetCheck(GetDlgItem(hDlg, IDC_VSYNC)) ? true : false; break; @@ -212,9 +256,9 @@ void DlgSettings_Show(HINSTANCE hInstance, HWND _hParent) #ifdef DEBUGFAST sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin (DEBUGFAST)")); #elif defined _DEBUG - sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin")); -#else sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin (DEBUG)")); +#else + sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin")); #endif if ((tfoe != g_Config.bTexFmtOverlayEnable) || diff --git a/Source/Plugins/Plugin_VideoDX11/Src/EmuWindow.cpp b/Source/Plugins/Plugin_VideoDX11/Src/EmuWindow.cpp index 1f7ff18960..e30e8f1a29 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/EmuWindow.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/EmuWindow.cpp @@ -207,6 +207,7 @@ HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title) // TODO: // 1. Remove redundant window manipulation, // 2. Make DX11 in fullscreen can be overlapped by other dialogs + // 3. Request window sizes which actually make the client area map to a common resolution HWND Ret; int x=0, y=0, width=640, height=480; g_VideoInitialize.pRequestWindowSize(x, y, width, height); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FBManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FBManager.cpp index 35f4b8327d..35b4d8a2f6 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FBManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/FBManager.cpp @@ -46,14 +46,14 @@ void FramebufferManager::Create() HRESULT hr; // create framebuffer color texture - m_efb.color_tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM); + m_efb.color_tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); CHECK(m_efb.color_tex != NULL, "create EFB color texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view"); // create a staging texture for Renderer::AccessEFB - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ); hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf); CHECK(hr==S_OK, "create EFB color staging buffer"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)"); @@ -221,7 +221,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex)) { SAFE_RELEASE(it->xfbSource.tex); - it->xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM); + it->xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); if (it->xfbSource.tex == NULL) PanicAlert("Failed to create XFB texture\n"); } xfbTex = it->xfbSource.tex; @@ -239,7 +239,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight { VirtualXFB newVirt; - newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM); + newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); if (newVirt.xfbSource.tex == NULL) PanicAlert("Failed to create a new virtual XFB"); newVirt.xfbAddr = xfbAddr; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.h b/Source/Plugins/Plugin_VideoDX11/Src/resource.h index cb6b999cf0..d4951e6a60 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.h @@ -5,7 +5,7 @@ #define IDD_ABOUT 102 #define IDD_SETTINGS 103 #define IDD_ADVANCED 105 -//#define IDC_ADAPTER 1001 +#define IDC_ADAPTER 1001 //#define IDC_ANTIALIASMODE 1002 //#define IDC_RESOLUTION 1003 #define IDC_VSYNC 1006 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc index 539bfb2945..ed7eb17951 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc @@ -40,15 +40,17 @@ IDD_SETTINGS DIALOGEX 0, 0, 244, 183 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_BORDER | WS_SYSMENU FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - CONTROL "&V-Sync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,10,36,8 - CONTROL "&Widescreen Hack",IDC_WIDESCREEN_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,161,10,67,10 - LTEXT "&Aspect Ratio:",IDC_STATIC,9,25,48,8 - COMBOBOX IDC_ASPECTRATIO,60,23,89,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "&Enable CPU->EFB access ",IDC_EFB_ACCESS_ENABLE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,45,94,11 - CONTROL "Enable &Safe Texture Cache",IDC_SAFE_TEXTURE_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,59,108,11 - CONTROL "Safe",IDC_SAFE_TEXTURE_CACHE_SAFE,"Button",BS_AUTORADIOBUTTON,20,72,32,10 - CONTROL "Normal",IDC_SAFE_TEXTURE_CACHE_NORMAL,"Button",BS_AUTORADIOBUTTON,52,72,40,10 - CONTROL "Fast",IDC_SAFE_TEXTURE_CACHE_FAST,"Button",BS_AUTORADIOBUTTON,92,72,32,10 + LTEXT "A&dapter:",IDC_STATIC,9,10,48,8 + COMBOBOX IDC_ADAPTER,60,8,169,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "&V-Sync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,25,36,8 + CONTROL "&Widescreen Hack",IDC_WIDESCREEN_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,161,25,67,10 + LTEXT "&Aspect Ratio:",IDC_STATIC,9,40,48,8 + COMBOBOX IDC_ASPECTRATIO,60,38,89,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "&Enable CPU->EFB access ",IDC_EFB_ACCESS_ENABLE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,60,94,11 + CONTROL "Enable &Safe Texture Cache",IDC_SAFE_TEXTURE_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,74,108,11 + CONTROL "Safe",IDC_SAFE_TEXTURE_CACHE_SAFE,"Button",BS_AUTORADIOBUTTON,20,87,32,10 + CONTROL "Normal",IDC_SAFE_TEXTURE_CACHE_NORMAL,"Button",BS_AUTORADIOBUTTON,52,87,40,10 + CONTROL "Fast",IDC_SAFE_TEXTURE_CACHE_FAST,"Button",BS_AUTORADIOBUTTON,92,87,32,10 END IDD_ADVANCED DIALOGEX 0, 0, 244, 200