GSdx: Fix some vsync enable bugs. Add "GSsetExclusive" API, which is meant to be a hint for setting exclusive fullscreen mode in DX10 (no plans to support it in DX9 due to complications that would require significant changes to DX9 resource management).

I don't have DX10 so this is (as usual!) untested.  I'll be adding support for it to PCSX2 soon.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2301 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-12-04 03:24:59 +00:00
parent 3092808d04
commit a3dee78c6c
8 changed files with 82 additions and 17 deletions

View File

@ -41,6 +41,7 @@ static uint8* s_basemem = NULL;
static int s_renderer = -1;
static bool s_framelimit = true;
static bool s_vsync = false;
static bool s_exclusive = true;
EXPORT_C_(uint32) PS2EgetLibType()
{
@ -240,8 +241,6 @@ static INT32 _GSopen(void* dsp, char* title, int renderer)
EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags )
{
theApp.SetConfig("windowed", flags & 1);
int renderer = theApp.GetConfig("renderer", 0);
if( flags & 4 )
{
@ -250,14 +249,16 @@ EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags )
INT32 retval = _GSopen( dsp, NULL, renderer );
s_gs->SetAspectRatio(0); // PCSX2 manages the aspect ratios
return retval;
}
EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt)
{
int renderer;
s_vsync = !!theApp.GetConfig("vsync", 0);
if(mt == 2)
{
// pcsx2 sent a switch renderer request
@ -463,6 +464,13 @@ EXPORT_C GSsetVsync(int enabled)
s_gs->SetVsync(s_vsync);
}
EXPORT_C GSsetExclusive(int enabled)
{
s_exclusive = !!enabled;
if( s_gs )
s_gs->SetVsync(s_vsync);
}
EXPORT_C GSsetFrameLimit(int limit)
{
s_framelimit = !!limit;

View File

@ -66,18 +66,19 @@ bool GSDevice10::Create(GSWnd* wnd)
scd.OutputWindow = (HWND)m_wnd->GetHandle();
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.Windowed = !!theApp.GetConfig("windowed", 1);
// Crashes when 2 threads work on the swapchain, as in pcsx2/wx when it provides us
// an external window handle (which could be attached to any thread other than the GS one).
// (but if we're managing our own window then it's safe to enable)
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
// will be issued after all other initializations are complete.
// NOTE : This flag can be enabled for both managed and unmanaged windows, as soon as
// PCSX2-side properly implements DXGIFactory mess to disable the internal alt-enter crap
// that DirectX10 forces upon us (and thus causes threading issues because the window
// message pump isn't on the same thread as the MTGS).
scd.Windowed = TRUE;
uint32 flags = /*m_wnd->IsManaged() ?*/ D3D10_CREATE_DEVICE_SINGLETHREADED /*: 0*/;
// NOTE : D3D10_CREATE_DEVICE_SINGLETHREADED
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
uint32 flags = D3D10_CREATE_DEVICE_SINGLETHREADED;
#ifdef DEBUG
flags |= D3D10_CREATE_DEVICE_DEBUG;
@ -264,7 +265,13 @@ bool GSDevice10::Create(GSWnd* wnd)
m_dev->CreateBlendState(&blend, &m_date.bs);
//
// Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style
// emulators will issue the flip themselves later on.
if(m_wnd->IsManaged())
{
SetExclusive( !theApp.GetConfig("windowed", 1) );
}
return true;
}
@ -289,6 +296,25 @@ bool GSDevice10::Reset(int w, int h)
return true;
}
void GSDevice10::SetExclusive(bool isExcl)
{
if(!m_swapchain) return;
// TODO : Support for alternative display modes, by finishing this code below:
// Video mode info should be pulled form config/ini.
/*DXGI_MODE_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.RefreshRate = 0; // must be zero for best results.
m_swapchain->ResizeTarget(&desc);
*/
HRESULT hr = m_swapchain->SetFullscreenState( isExcl, NULL );
if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
fprintf(stderr, "(GSdx10) SetExclusive(%s) failed; request unavailable.", isExcl ? "true" : "false");
}
void GSDevice10::Flip()
{
m_swapchain->Present(m_vsync, 0);

View File

@ -115,6 +115,8 @@ public:
GSDevice10();
virtual ~GSDevice10();
void SetExclusive(bool isExcl);
bool Create(GSWnd* wnd);
bool CreateTextureFX();
bool Reset(int w, int h);

View File

@ -66,6 +66,7 @@ bool GSDevice11::Create(GSWnd* wnd)
scd.OutputWindow = (HWND)m_wnd->GetHandle();
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
@ -256,6 +257,11 @@ bool GSDevice11::Create(GSWnd* wnd)
//
if(m_wnd->IsManaged())
{
SetExclusive( !theApp.GetConfig("windowed", 1) );
}
return true;
}
@ -279,6 +285,25 @@ bool GSDevice11::Reset(int w, int h)
return true;
}
void GSDevice11::SetExclusive(bool isExcl)
{
if(!m_swapchain) return;
// TODO : Support for alternative display modes, by finishing this code below:
// Video mode info should be pulled form config/ini.
/*DXGI_MODE_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.RefreshRate = 0; // must be zero for best results.
m_swapchain->ResizeTarget(&desc);
*/
HRESULT hr = m_swapchain->SetFullscreenState( isExcl, NULL );
if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
fprintf(stderr, "(GSdx10) SetExclusive(%s) failed; request unavailable.", isExcl ? "true" : "false");
}
void GSDevice11::Flip()
{
m_swapchain->Present(m_vsync, 0);

View File

@ -122,6 +122,8 @@ public:
bool Reset(int w, int h);
void Flip();
void SetExclusive(bool isExcl);
void DrawPrimitive();
void ClearRenderTarget(GSTexture* t, const GSVector4& c);

View File

@ -246,7 +246,7 @@ bool GSDevice9::Reset(int w, int h)
HRESULT hr;
int mode = theApp.GetConfig("windowed", 1) ? Windowed : Fullscreen;
int mode = (!m_wnd->IsManaged() || theApp.GetConfig("windowed", 1)) ? Windowed : Fullscreen;
if(mode == DontCare)
{
mode = m_pp.Windowed ? Windowed : Fullscreen;
@ -300,7 +300,7 @@ bool GSDevice9::Reset(int w, int h)
if(m_vsync)
{
m_pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
m_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // was D3DPRESENT_INTERVAL_DEFAULT, but ONE is like more "forceful"!
}
// m_pp.Flags |= D3DPRESENTFLAG_VIDEO; // enables tv-out (but I don't think anyone would still use a regular tv...)
@ -309,7 +309,7 @@ bool GSDevice9::Reset(int w, int h)
int mh = theApp.GetConfig("ModeHeight", 0);
int mrr = theApp.GetConfig("ModeRefreshRate", 0);
if(mode == Fullscreen && mw > 0 && mh > 0 && mrr >= 0)
if(!m_wnd->IsManaged() && mode == Fullscreen && mw > 0 && mh > 0 && mrr >= 0)
{
m_pp.Windowed = FALSE;
m_pp.BackBufferWidth = mw;

View File

@ -98,6 +98,7 @@ public:
void SetAspectRatio(int aspect) { m_aspectratio = aspect; }
void SetVsync(bool enabled);
void SetFrameLimit(bool limit);
virtual void SetExclusive(bool isExcl) {}
// TODO : Implement proper locking here *if needed* (not sure yet if it is) --air
uint8* GetTextureBufferLock() { return m_tex_buff; }

View File

@ -35,6 +35,7 @@ EXPORTS
GSsetFrameSkip
GSsetFrameLimit
GSsetVsync
GSsetExclusive
GSgetLastTag
GSReplay
GSBenchmark