Merge pull request #506 from Armada651/d3dfullscreen
D3D: Add exclusive fullscreen support.
This commit is contained in:
commit
8e865f3848
|
@ -31,6 +31,7 @@ void Host_Message(int Id);
|
|||
void Host_NotifyMapLoaded();
|
||||
void Host_RefreshDSPDebuggerWindow();
|
||||
void Host_RequestRenderWindowSize(int width, int height);
|
||||
void Host_RequestFullscreen(bool enable_fullscreen);
|
||||
void Host_SetStartupDebuggingParameters();
|
||||
void Host_SetWiiMoteConnectionState(int _State);
|
||||
void Host_ShowJitResults(unsigned int address);
|
||||
|
|
|
@ -78,57 +78,6 @@ extern "C" {
|
|||
#include "DolphinWX/resources/Dolphin.c" // NOLINT: Dolphin icon
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
// I could not use FindItemByHWND() instead of this, it crashed on that occasion I used it */
|
||||
HWND MSWGetParent_(HWND Parent)
|
||||
{
|
||||
return GetParent(Parent);
|
||||
}
|
||||
#endif
|
||||
|
||||
// ---------------
|
||||
// The CPanel class to receive MSWWindowProc messages from the video backend.
|
||||
|
||||
BEGIN_EVENT_TABLE(CPanel, wxPanel)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
CPanel::CPanel(
|
||||
wxWindow *parent,
|
||||
wxWindowID id
|
||||
)
|
||||
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, 0) // disables wxTAB_TRAVERSAL because it was breaking hotkeys
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
WXLRESULT CPanel::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||
{
|
||||
switch (nMsg)
|
||||
{
|
||||
case WM_USER:
|
||||
switch (wParam)
|
||||
{
|
||||
case WM_USER_STOP:
|
||||
main_frame->DoStop();
|
||||
break;
|
||||
|
||||
case WM_USER_SETCURSOR:
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
|
||||
main_frame->RendererHasFocus() && Core::GetState() == Core::CORE_RUN)
|
||||
SetCursor(wxCURSOR_BLANK);
|
||||
else
|
||||
SetCursor(wxNullCursor);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// By default let wxWidgets do what it normally does with this event
|
||||
return wxPanel::MSWWindowProc(nMsg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
CRenderFrame::CRenderFrame(wxFrame* parent, wxWindowID id, const wxString& title,
|
||||
const wxPoint& pos, const wxSize& size, long style)
|
||||
|
@ -213,6 +162,23 @@ WXLRESULT CRenderFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPa
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_USER:
|
||||
switch (wParam)
|
||||
{
|
||||
case WM_USER_STOP:
|
||||
main_frame->DoStop();
|
||||
break;
|
||||
|
||||
case WM_USER_SETCURSOR:
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
|
||||
main_frame->RendererHasFocus() && Core::GetState() == Core::CORE_RUN)
|
||||
SetCursor(wxCURSOR_BLANK);
|
||||
else
|
||||
SetCursor(wxNullCursor);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
// Let Core finish initializing before accepting any WM_CLOSE messages
|
||||
if (!Core::IsRunning()) break;
|
||||
|
@ -350,7 +316,7 @@ CFrame::CFrame(wxFrame* parent,
|
|||
, m_LogWindow(nullptr), m_LogConfigWindow(nullptr)
|
||||
, m_FifoPlayerDlg(nullptr), UseDebugger(_UseDebugger)
|
||||
, m_bBatchMode(_BatchMode), m_bEdit(false), m_bTabSplit(false), m_bNoDocking(false)
|
||||
, m_bGameLoading(false), m_bClosing(false)
|
||||
, m_bGameLoading(false), m_bClosing(false), m_confirmStop(false)
|
||||
{
|
||||
for (int i = 0; i <= IDM_CODEWINDOW - IDM_LOGWINDOW; i++)
|
||||
bFloatWindow[i] = false;
|
||||
|
@ -384,7 +350,7 @@ CFrame::CFrame(wxFrame* parent,
|
|||
// ---------------
|
||||
// Main panel
|
||||
// This panel is the parent for rendering and it holds the gamelistctrl
|
||||
m_Panel = new CPanel(this, IDM_MPANEL);
|
||||
m_Panel = new wxPanel(this, IDM_MPANEL, wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_GameListCtrl = new CGameListCtrl(m_Panel, LIST_CTRL,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
|
@ -484,7 +450,7 @@ bool CFrame::RendererIsFullscreen()
|
|||
|
||||
if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
|
||||
{
|
||||
fullscreen = m_RenderFrame->IsFullScreen();
|
||||
fullscreen = m_RenderFrame->IsFullScreen() && g_Config.bFullscreen;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
@ -674,6 +640,21 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
|||
}
|
||||
break;
|
||||
|
||||
case IDM_FULLSCREENREQUEST:
|
||||
{
|
||||
bool enable_fullscreen = event.GetInt() == 0 ? false : true;
|
||||
ToggleDisplayMode(enable_fullscreen);
|
||||
if (m_RenderFrame != nullptr)
|
||||
m_RenderFrame->ShowFullScreen(enable_fullscreen);
|
||||
|
||||
// If the stop dialog initiated this fullscreen switch then we need
|
||||
// to pause the emulator after we've completed the switch.
|
||||
// TODO: Allow the renderer to switch fullscreen modes while paused.
|
||||
if (m_confirmStop)
|
||||
Core::SetState(Core::CORE_PAUSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_USER_CREATE:
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
|
||||
m_RenderParent->SetCursor(wxCURSOR_BLANK);
|
||||
|
@ -756,7 +737,11 @@ bool CFrame::RendererHasFocus()
|
|||
if (m_RenderParent == nullptr)
|
||||
return false;
|
||||
#ifdef _WIN32
|
||||
if (m_RenderParent->GetParent()->GetHWND() == GetForegroundWindow())
|
||||
HWND window = GetForegroundWindow();
|
||||
if (window == nullptr)
|
||||
return false;
|
||||
|
||||
if (m_RenderFrame->GetHWND() == window)
|
||||
return true;
|
||||
#else
|
||||
wxWindow *window = wxWindow::FindFocus();
|
||||
|
@ -1202,25 +1187,47 @@ void CFrame::OnMouse(wxMouseEvent& event)
|
|||
event.Skip();
|
||||
}
|
||||
|
||||
void CFrame::DoFullscreen(bool bF)
|
||||
void CFrame::DoFullscreen(bool enable_fullscreen)
|
||||
{
|
||||
ToggleDisplayMode(bF);
|
||||
if (!g_Config.bBorderlessFullscreen &&
|
||||
!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain &&
|
||||
Core::GetState() != Core::CORE_RUN)
|
||||
{
|
||||
// A responsive renderer is required for exclusive fullscreen, but the
|
||||
// renderer can only respond in the running state. Therefore we ignore
|
||||
// fullscreen switches if we support exclusive fullscreen, but the
|
||||
// renderer is not running.
|
||||
// TODO: Allow the renderer to switch fullscreen modes while paused.
|
||||
return;
|
||||
}
|
||||
|
||||
ToggleDisplayMode(enable_fullscreen);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
NSView *view = (NSView *) m_RenderFrame->GetHandle();
|
||||
NSWindow *window = [view window];
|
||||
|
||||
if (bF != RendererIsFullscreen())
|
||||
if (enable_fullscreen != RendererIsFullscreen())
|
||||
{
|
||||
[window toggleFullScreen:nil];
|
||||
}
|
||||
#else
|
||||
m_RenderFrame->ShowFullScreen(bF, wxFULLSCREEN_ALL);
|
||||
if (enable_fullscreen)
|
||||
{
|
||||
m_RenderFrame->ShowFullScreen(true, wxFULLSCREEN_ALL);
|
||||
}
|
||||
else if (g_Config.bBorderlessFullscreen ||
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain)
|
||||
{
|
||||
// Exiting exclusive fullscreen should be done from a Renderer callback.
|
||||
// Therefore we don't exit fullscreen from here if we support exclusive mode.
|
||||
m_RenderFrame->ShowFullScreen(false, wxFULLSCREEN_ALL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain)
|
||||
{
|
||||
if (bF)
|
||||
if (enable_fullscreen)
|
||||
{
|
||||
// Save the current mode before going to fullscreen
|
||||
AuiCurrent = m_Mgr->SavePerspective();
|
||||
|
@ -1236,6 +1243,8 @@ void CFrame::DoFullscreen(bool bF)
|
|||
{
|
||||
m_RenderFrame->Raise();
|
||||
}
|
||||
|
||||
g_Config.bFullscreen = enable_fullscreen;
|
||||
}
|
||||
|
||||
const CGameListCtrl *CFrame::GetGameListCtrl() const
|
||||
|
|
|
@ -50,24 +50,6 @@ class wxListEvent;
|
|||
class wxMenuItem;
|
||||
class wxWindow;
|
||||
|
||||
// The CPanel class to receive MSWWindowProc messages from the video backend.
|
||||
class CPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
CPanel(
|
||||
wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY
|
||||
);
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
#ifdef _WIN32
|
||||
// Receive WndProc messages
|
||||
WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
||||
#endif
|
||||
};
|
||||
|
||||
class CRenderFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
|
@ -177,7 +159,7 @@ private:
|
|||
CGameListCtrl* m_GameListCtrl;
|
||||
wxPanel* m_Panel;
|
||||
CRenderFrame* m_RenderFrame;
|
||||
wxPanel* m_RenderParent;
|
||||
wxWindow* m_RenderParent;
|
||||
CLogWindow* m_LogWindow;
|
||||
LogConfigWindow* m_LogConfigWindow;
|
||||
FifoPlayerDlg* m_FifoPlayerDlg;
|
||||
|
@ -188,6 +170,7 @@ private:
|
|||
bool m_bNoDocking;
|
||||
bool m_bGameLoading;
|
||||
bool m_bClosing;
|
||||
bool m_confirmStop;
|
||||
|
||||
std::vector<std::string> drives;
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ Core::GetWindowHandle().
|
|||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef SM_XVIRTUALSCREEN
|
||||
|
@ -119,8 +120,6 @@ extern "C" {
|
|||
class InputPlugin;
|
||||
class wxFrame;
|
||||
|
||||
static bool confirmStop = false;
|
||||
|
||||
// Create menu items
|
||||
// ---------------------
|
||||
void CFrame::CreateMenu()
|
||||
|
@ -976,7 +975,7 @@ void CFrame::StartGame(const std::string& filename)
|
|||
m_RenderFrame->Bind(wxEVT_CLOSE_WINDOW, &CFrame::OnRenderParentClose, this);
|
||||
m_RenderFrame->Bind(wxEVT_ACTIVATE, &CFrame::OnActive, this);
|
||||
m_RenderFrame->Bind(wxEVT_MOVE, &CFrame::OnRenderParentMove, this);
|
||||
m_RenderParent = new CPanel(m_RenderFrame, wxID_ANY);
|
||||
m_RenderParent = m_RenderFrame;
|
||||
m_RenderFrame->Show();
|
||||
}
|
||||
|
||||
|
@ -1082,11 +1081,11 @@ void CFrame::DoStop()
|
|||
{
|
||||
if (!Core::IsRunningAndStarted())
|
||||
return;
|
||||
if (confirmStop)
|
||||
if (m_confirmStop)
|
||||
return;
|
||||
|
||||
// don't let this function run again until it finishes, or is aborted.
|
||||
confirmStop = true;
|
||||
m_confirmStop = true;
|
||||
|
||||
m_bGameLoading = false;
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED ||
|
||||
|
@ -1100,8 +1099,21 @@ void CFrame::DoStop()
|
|||
// Ask for confirmation in case the user accidentally clicked Stop / Escape
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop)
|
||||
{
|
||||
// Pause the state during confirmation and restore it afterwards
|
||||
Core::EState state = Core::GetState();
|
||||
Core::SetState(Core::CORE_PAUSE);
|
||||
|
||||
// If exclusive fullscreen is not enabled then we can pause the emulation
|
||||
// before we've exited fullscreen. If not then we need to exit fullscreen first.
|
||||
if (!RendererIsFullscreen() || g_Config.bBorderlessFullscreen ||
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain)
|
||||
{
|
||||
Core::SetState(Core::CORE_PAUSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoFullscreen(false);
|
||||
}
|
||||
|
||||
wxMessageDialog m_StopDlg(
|
||||
this,
|
||||
_("Do you want to stop the current emulation?"),
|
||||
|
@ -1113,7 +1125,7 @@ void CFrame::DoStop()
|
|||
if (Ret != wxID_YES)
|
||||
{
|
||||
Core::SetState(state);
|
||||
confirmStop = false;
|
||||
m_confirmStop = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1135,7 +1147,7 @@ void CFrame::OnStopped()
|
|||
{
|
||||
wxEndBusyCursor();
|
||||
|
||||
confirmStop = false;
|
||||
m_confirmStop = false;
|
||||
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver)
|
||||
|
|
|
@ -256,6 +256,7 @@ enum
|
|||
IDM_WINDOWSIZEREQUEST,
|
||||
IDM_STOPPED,
|
||||
IDM_HOST_MESSAGE,
|
||||
IDM_FULLSCREENREQUEST,
|
||||
|
||||
IDM_MPANEL, ID_STATUSBAR,
|
||||
|
||||
|
|
|
@ -627,6 +627,13 @@ void Host_RequestRenderWindowSize(int width, int height)
|
|||
main_frame->GetEventHandler()->AddPendingEvent(event);
|
||||
}
|
||||
|
||||
void Host_RequestFullscreen(bool enable_fullscreen)
|
||||
{
|
||||
wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_FULLSCREENREQUEST);
|
||||
event.SetInt(enable_fullscreen ? 1 : 0);
|
||||
main_frame->GetEventHandler()->AddPendingEvent(event);
|
||||
}
|
||||
|
||||
void Host_SetStartupDebuggingParameters()
|
||||
{
|
||||
SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||
|
|
|
@ -94,6 +94,9 @@ void Host_GetRenderWindowSize(int& x, int& y, int& width, int& height)
|
|||
}
|
||||
|
||||
void Host_RequestRenderWindowSize(int width, int height) {}
|
||||
|
||||
void Host_RequestFullscreen(bool enable_fullscreen) {}
|
||||
|
||||
void Host_SetStartupDebuggingParameters()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ void Host_GetRenderWindowSize(int& x, int& y, int& width, int& height)
|
|||
}
|
||||
|
||||
void Host_RequestRenderWindowSize(int width, int height) {}
|
||||
|
||||
void Host_RequestFullscreen(bool enable_fullscreen) {}
|
||||
|
||||
void Host_SetStartupDebuggingParameters()
|
||||
{
|
||||
SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||
|
|
|
@ -113,7 +113,7 @@ static wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of
|
|||
static wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked.");
|
||||
static wxString fast_depth_calc_desc = wxTRANSLATE("Use a less accurate algorithm to calculate depth values.\nCauses issues in a few games but might give a decent speedup.\n\nIf unsure, leave this checked.");
|
||||
static wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked.");
|
||||
static wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked.");
|
||||
static wxString borderless_fullscreen_desc = wxTRANSLATE("Implement fullscreen mode with a borderless window spanning the whole screen instead of using exclusive mode.\nAllows for faster transitions between fullscreen and windowed mode, but increases input latency, makes movement less smooth and slightly decreases performance.\nExclusive mode is required to support Nvidia 3D Vision.\n\nIf unsure, leave this unchecked.");
|
||||
static wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528.");
|
||||
static wxString efb_access_desc = wxTRANSLATE("Ignore any requests of the CPU to read from or write to the EFB.\nImproves performance in some games, but might disable some gameplay-related features or graphical effects.\n\nIf unsure, leave this unchecked.");
|
||||
static wxString efb_emulate_format_changes_desc = wxTRANSLATE("Ignore any changes to the EFB format.\nImproves performance in many games without any negative effect. Causes graphical defects in a small number of other games though.\n\nIf unsure, leave this checked.");
|
||||
|
@ -417,7 +417,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
|||
szr_enh->Add(choice_ppshader);
|
||||
}
|
||||
|
||||
// Scaled copy, PL, Bilinear filter, 3D Vision
|
||||
// Scaled copy, PL, Bilinear filter
|
||||
szr_enh->Add(CreateCheckBox(page_enh, _("Scaled EFB Copy"), wxGetTranslation(scaled_efb_copy_desc), vconfig.bCopyEFBScaled));
|
||||
szr_enh->Add(CreateCheckBox(page_enh, _("Per-Pixel Lighting"), wxGetTranslation(pixel_lighting_desc), vconfig.bEnablePixelLighting));
|
||||
szr_enh->Add(CreateCheckBox(page_enh, _("Force Texture Filtering"), wxGetTranslation(force_filtering_desc), vconfig.bForceFiltering));
|
||||
|
@ -425,12 +425,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
|||
szr_enh->Add(CreateCheckBox(page_enh, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack));
|
||||
szr_enh->Add(CreateCheckBox(page_enh, _("Disable Fog"), wxGetTranslation(disable_fog_desc), vconfig.bDisableFog));
|
||||
|
||||
// 3D Vision
|
||||
_3d_vision = CreateCheckBox(page_enh, _("3D Vision"), wxGetTranslation(_3d_vision_desc), vconfig.b3DVision);
|
||||
_3d_vision->Show(vconfig.backend_info.bSupports3DVision);
|
||||
szr_enh->Add(_3d_vision);
|
||||
// TODO: Add anaglyph 3d here
|
||||
|
||||
wxStaticBoxSizer* const group_enh = new wxStaticBoxSizer(wxVERTICAL, page_enh, _("Enhancements"));
|
||||
group_enh->Add(szr_enh, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
szr_enh_main->Add(group_enh, 0, wxEXPAND | wxALL, 5);
|
||||
|
@ -584,6 +578,11 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
|||
szr_misc->Add(cb_prog_scan);
|
||||
}
|
||||
|
||||
// Borderless Fullscreen
|
||||
borderless_fullscreen = CreateCheckBox(page_advanced, _("Borderless Fullscreen"), wxGetTranslation(borderless_fullscreen_desc), vconfig.bBorderlessFullscreen);
|
||||
borderless_fullscreen->Show(vconfig.backend_info.bSupportsExclusiveFullscreen);
|
||||
szr_misc->Add(borderless_fullscreen);
|
||||
|
||||
wxStaticBoxSizer* const group_misc = new wxStaticBoxSizer(wxVERTICAL, page_advanced, _("Misc"));
|
||||
szr_advanced->Add(group_misc, 0, wxEXPAND | wxALL, 5);
|
||||
group_misc->Add(szr_misc, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
|
|
|
@ -155,9 +155,9 @@ protected:
|
|||
choice_aamode->Enable(vconfig.backend_info.AAModes.size() > 1);
|
||||
text_aamode->Enable(vconfig.backend_info.AAModes.size() > 1);
|
||||
|
||||
// 3D vision
|
||||
_3d_vision->Enable(vconfig.backend_info.bSupports3DVision);
|
||||
_3d_vision->Show(vconfig.backend_info.bSupports3DVision);
|
||||
// Borderless Fullscreen
|
||||
borderless_fullscreen->Enable(vconfig.backend_info.bSupportsExclusiveFullscreen);
|
||||
borderless_fullscreen->Show(vconfig.backend_info.bSupportsExclusiveFullscreen);
|
||||
|
||||
// EFB copy
|
||||
efbcopy_texture->Enable(vconfig.bEFBCopyEnable);
|
||||
|
@ -188,7 +188,7 @@ protected:
|
|||
wxStaticText* text_aamode;
|
||||
SettingChoice* choice_aamode;
|
||||
|
||||
SettingCheckBox* _3d_vision;
|
||||
SettingCheckBox* borderless_fullscreen;
|
||||
|
||||
SettingRadioButton* efbcopy_texture;
|
||||
SettingRadioButton* efbcopy_ram;
|
||||
|
|
|
@ -264,20 +264,28 @@ HRESULT Create(HWND wnd)
|
|||
swap_chain_desc.OutputWindow = wnd;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Windowed = TRUE;
|
||||
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 = xres;
|
||||
mode_desc.Height = yres;
|
||||
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);
|
||||
|
||||
// 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 (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
|
||||
|
@ -308,6 +316,13 @@ HRESULT Create(HWND wnd)
|
|||
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);
|
||||
|
@ -342,6 +357,9 @@ HRESULT Create(HWND wnd)
|
|||
|
||||
void Close()
|
||||
{
|
||||
// we can't release the swapchain while in fullscreen.
|
||||
swapchain->SetFullscreenState(false, nullptr);
|
||||
|
||||
// release all bound resources
|
||||
context->ClearState();
|
||||
SAFE_RELEASE(backbuf);
|
||||
|
@ -474,6 +492,24 @@ void Present()
|
|||
swapchain->Present((UINT)g_ActiveConfig.IsVSync(), 0);
|
||||
}
|
||||
|
||||
HRESULT SetFullscreenState(bool enable_fullscreen)
|
||||
{
|
||||
return swapchain->SetFullscreenState(enable_fullscreen, nullptr);
|
||||
}
|
||||
|
||||
HRESULT GetFullscreenState(bool* fullscreen_state)
|
||||
{
|
||||
if (fullscreen_state == nullptr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
BOOL state;
|
||||
HRESULT hr = swapchain->GetFullscreenState(&state, nullptr);
|
||||
*fullscreen_state = !!state;
|
||||
return hr;
|
||||
}
|
||||
|
||||
} // namespace D3D
|
||||
|
||||
} // namespace DX11
|
||||
|
|
|
@ -58,6 +58,9 @@ bool BGRATexturesSupported();
|
|||
|
||||
unsigned int GetMaxTextureSize();
|
||||
|
||||
HRESULT SetFullscreenState(bool enable_fullscreen);
|
||||
HRESULT GetFullscreenState(bool* fullscreen_state);
|
||||
|
||||
// Ihis function will assign a name to the given resource.
|
||||
// The DirectX debug layer will make it easier to identify resources that way,
|
||||
// e.g. when listing up all resources who have unreleased references.
|
||||
|
|
|
@ -42,6 +42,8 @@ static u32 s_LastAA = 0;
|
|||
|
||||
static Television s_television;
|
||||
|
||||
static bool s_last_fullscreen_mode = false;
|
||||
|
||||
ID3D11Buffer* access_efb_cbuf = nullptr;
|
||||
ID3D11BlendState* clearblendstates[4] = {nullptr};
|
||||
ID3D11DepthStencilState* cleardepthstates[3] = {nullptr};
|
||||
|
@ -936,6 +938,22 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
SetWindowSize(fbWidth, fbHeight);
|
||||
|
||||
const bool windowResized = CheckForResize();
|
||||
const bool fullscreen = g_ActiveConfig.ExclusiveFullscreenEnabled() &&
|
||||
!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain;
|
||||
|
||||
bool fullscreen_changed = s_last_fullscreen_mode != fullscreen;
|
||||
|
||||
bool fullscreen_state;
|
||||
if (SUCCEEDED(D3D::GetFullscreenState(&fullscreen_state)))
|
||||
{
|
||||
if (fullscreen_state != fullscreen && Host_RendererHasFocus())
|
||||
{
|
||||
// The current fullscreen state does not match the configuration,
|
||||
// this may happen when the renderer frame loses focus. When the
|
||||
// render frame is in focus again we can re-apply the configuration.
|
||||
fullscreen_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool xfbchanged = false;
|
||||
|
||||
|
@ -951,17 +969,31 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
// Flip/present backbuffer to frontbuffer here
|
||||
D3D::Present();
|
||||
|
||||
// resize the back buffers NOW to avoid flickering
|
||||
// Resize the back buffers NOW to avoid flickering
|
||||
if (xfbchanged ||
|
||||
windowResized ||
|
||||
fullscreen_changed ||
|
||||
s_LastEFBScale != g_ActiveConfig.iEFBScale ||
|
||||
s_LastAA != g_ActiveConfig.iMultisampleMode)
|
||||
{
|
||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||
PixelShaderCache::InvalidateMSAAShaders();
|
||||
|
||||
if (windowResized)
|
||||
if (windowResized || fullscreen_changed)
|
||||
{
|
||||
// Apply fullscreen state
|
||||
if (fullscreen_changed)
|
||||
{
|
||||
s_last_fullscreen_mode = fullscreen;
|
||||
D3D::SetFullscreenState(fullscreen);
|
||||
|
||||
// Notify the host that it is safe to exit fullscreen
|
||||
if (!fullscreen)
|
||||
{
|
||||
Host_RequestFullscreen(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Aren't we still holding a reference to the back buffer right now?
|
||||
D3D::Reset();
|
||||
SAFE_RELEASE(s_screenshot_texture);
|
||||
|
|
|
@ -84,7 +84,7 @@ void InitBackendInfo()
|
|||
g_Config.backend_info.APIType = API_D3D;
|
||||
g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats
|
||||
g_Config.backend_info.bUseMinimalMipCount = true;
|
||||
g_Config.backend_info.bSupports3DVision = false;
|
||||
g_Config.backend_info.bSupportsExclusiveFullscreen = true;
|
||||
g_Config.backend_info.bSupportsDualSourceBlend = true;
|
||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||
g_Config.backend_info.bSupportsOversizedViewports = false;
|
||||
|
|
|
@ -143,7 +143,7 @@ static void InitBackendInfo()
|
|||
g_Config.backend_info.APIType = API_OPENGL;
|
||||
g_Config.backend_info.bUseRGBATextures = true;
|
||||
g_Config.backend_info.bUseMinimalMipCount = false;
|
||||
g_Config.backend_info.bSupports3DVision = false;
|
||||
g_Config.backend_info.bSupportsExclusiveFullscreen = false;
|
||||
//g_Config.backend_info.bSupportsDualSourceBlend = true; // is gpu dependent and must be set in renderer
|
||||
//g_Config.backend_info.bSupportsEarlyZ = true; // is gpu dependent and must be set in renderer
|
||||
g_Config.backend_info.bSupportsOversizedViewports = true;
|
||||
|
|
|
@ -236,15 +236,7 @@ int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffe
|
|||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return x;
|
||||
|
||||
if (g_ActiveConfig.b3DVision)
|
||||
{
|
||||
// This works, yet the version in the else doesn't. No idea why.
|
||||
return x * (int)backbuffer_width / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
|
||||
int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height)
|
||||
|
@ -252,13 +244,5 @@ int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuff
|
|||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return y;
|
||||
|
||||
if (g_ActiveConfig.b3DVision)
|
||||
{
|
||||
// This works, yet the version in the else doesn't. No idea why.
|
||||
return y * (int)backbuffer_height / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ void UpdateActiveConfig()
|
|||
VideoConfig::VideoConfig()
|
||||
{
|
||||
bRunning = false;
|
||||
bFullscreen = false;
|
||||
|
||||
// Needed for the first frame, I think
|
||||
fAspectRatioHackW = 1;
|
||||
|
@ -37,7 +38,7 @@ VideoConfig::VideoConfig()
|
|||
backend_info.APIType = API_NONE;
|
||||
backend_info.bUseRGBATextures = false;
|
||||
backend_info.bUseMinimalMipCount = false;
|
||||
backend_info.bSupports3DVision = false;
|
||||
backend_info.bSupportsExclusiveFullscreen = false;
|
||||
}
|
||||
|
||||
void VideoConfig::Load(const std::string& ini_file)
|
||||
|
@ -82,12 +83,12 @@ void VideoConfig::Load(const std::string& ini_file)
|
|||
settings->Get("DisableFog", &bDisableFog, 0);
|
||||
settings->Get("OMPDecoder", &bOMPDecoder, false);
|
||||
settings->Get("EnableShaderDebugging", &bEnableShaderDebugging, false);
|
||||
settings->Get("BorderlessFullscreen", &bBorderlessFullscreen, false);
|
||||
|
||||
IniFile::Section* enhancements = iniFile.GetOrCreateSection("Enhancements");
|
||||
enhancements->Get("ForceFiltering", &bForceFiltering, 0);
|
||||
enhancements->Get("MaxAnisotropy", &iMaxAnisotropy, 0); // NOTE - this is x in (1 << x)
|
||||
enhancements->Get("PostProcessingShader", &sPostProcessingShader, "");
|
||||
enhancements->Get("Enable3dVision", &b3DVision, false);
|
||||
|
||||
IniFile::Section* hacks = iniFile.GetOrCreateSection("Hacks");
|
||||
hacks->Get("EFBAccessEnable", &bEFBAccessEnable, true);
|
||||
|
@ -183,7 +184,6 @@ void VideoConfig::GameIniLoad()
|
|||
CHECK_SETTING("Video_Enhancements", "ForceFiltering", bForceFiltering);
|
||||
CHECK_SETTING("Video_Enhancements", "MaxAnisotropy", iMaxAnisotropy); // NOTE - this is x in (1 << x)
|
||||
CHECK_SETTING("Video_Enhancements", "PostProcessingShader", sPostProcessingShader);
|
||||
CHECK_SETTING("Video_Enhancements", "Enable3dVision", b3DVision);
|
||||
|
||||
CHECK_SETTING("Video_Hacks", "EFBAccessEnable", bEFBAccessEnable);
|
||||
CHECK_SETTING("Video_Hacks", "EFBCopyEnable", bEFBCopyEnable);
|
||||
|
@ -209,7 +209,7 @@ void VideoConfig::VerifyValidity()
|
|||
// TODO: Check iMaxAnisotropy value
|
||||
if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1)) iAdapter = 0;
|
||||
if (iMultisampleMode < 0 || iMultisampleMode >= (int)backend_info.AAModes.size()) iMultisampleMode = 0;
|
||||
if (!backend_info.bSupports3DVision) b3DVision = false;
|
||||
if (!backend_info.bSupportsExclusiveFullscreen) bBorderlessFullscreen = true;
|
||||
}
|
||||
|
||||
void VideoConfig::Save(const std::string& ini_file)
|
||||
|
@ -254,12 +254,12 @@ void VideoConfig::Save(const std::string& ini_file)
|
|||
settings->Set("DisableFog", bDisableFog);
|
||||
settings->Set("OMPDecoder", bOMPDecoder);
|
||||
settings->Set("EnableShaderDebugging", bEnableShaderDebugging);
|
||||
settings->Set("BorderlessFullscreen", bBorderlessFullscreen);
|
||||
|
||||
IniFile::Section* enhancements = iniFile.GetOrCreateSection("Enhancements");
|
||||
enhancements->Set("ForceFiltering", bForceFiltering);
|
||||
enhancements->Set("MaxAnisotropy", iMaxAnisotropy);
|
||||
enhancements->Set("PostProcessingShader", sPostProcessingShader);
|
||||
enhancements->Set("Enable3dVision", b3DVision);
|
||||
|
||||
IniFile::Section* hacks = iniFile.GetOrCreateSection("Hacks");
|
||||
hacks->Set("EFBAccessEnable", bEFBAccessEnable);
|
||||
|
|
|
@ -57,7 +57,7 @@ struct VideoConfig final
|
|||
|
||||
// General
|
||||
bool bVSync;
|
||||
|
||||
bool bFullscreen;
|
||||
bool bRunning;
|
||||
bool bWidescreenHack;
|
||||
int iAspectRatio;
|
||||
|
@ -100,7 +100,7 @@ struct VideoConfig final
|
|||
bool bAnaglyphStereo;
|
||||
int iAnaglyphStereoSeparation;
|
||||
int iAnaglyphFocalAngle;
|
||||
bool b3DVision;
|
||||
bool bBorderlessFullscreen;
|
||||
|
||||
// Hacks
|
||||
bool bEFBAccessEnable;
|
||||
|
@ -139,7 +139,7 @@ struct VideoConfig final
|
|||
|
||||
bool bUseRGBATextures; // used for D3D in TextureCache
|
||||
bool bUseMinimalMipCount;
|
||||
bool bSupports3DVision;
|
||||
bool bSupportsExclusiveFullscreen;
|
||||
bool bSupportsDualSourceBlend;
|
||||
bool bSupportsPrimitiveRestart;
|
||||
bool bSupportsOversizedViewports;
|
||||
|
@ -152,6 +152,7 @@ struct VideoConfig final
|
|||
bool VirtualXFBEnabled() const { return bUseXFB && !bUseRealXFB; }
|
||||
bool EFBCopiesToTextureEnabled() const { return bEFBCopyEnable && bCopyEFBToTexture; }
|
||||
bool EFBCopiesToRamEnabled() const { return bEFBCopyEnable && !bCopyEFBToTexture; }
|
||||
bool ExclusiveFullscreenEnabled() const { return bFullscreen && !bBorderlessFullscreen; }
|
||||
};
|
||||
|
||||
extern VideoConfig g_Config;
|
||||
|
|
Loading…
Reference in New Issue