From a820423c4bd63dd31060de2c7fd966f26c588fcc Mon Sep 17 00:00:00 2001 From: gabest11 Date: Thu, 24 Feb 2011 23:46:26 +0000 Subject: [PATCH] GSdx: SDL works on linux now, there are still random crashes though. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4357 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GS.cpp | 16 +++++++ plugins/GSdx/GSDevice11.cpp | 20 ++++----- plugins/GSdx/GSDeviceSDL.cpp | 70 +++++++++++++++--------------- plugins/GSdx/GSPerfMon.cpp | 2 +- plugins/GSdx/GSRenderer.cpp | 5 ++- plugins/GSdx/GSWnd.cpp | 82 +++++++++++++++++++++++++++++++++++- plugins/GSdx/GSWnd.h | 32 +++++++++++++- plugins/GSdx/GSdx.gcc.cbp | 3 +- 8 files changed, 176 insertions(+), 54 deletions(-) diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 805e8a0d3..35f962aa1 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -131,6 +131,16 @@ EXPORT_C_(int) GSinit() return -1; } +#else + + if(!SDL_WasInit(SDL_INIT_VIDEO)) + { + if(SDL_Init(SDL_INIT_VIDEO) < 0) + { + return -1; + } + } + #endif return 0; @@ -153,6 +163,10 @@ EXPORT_C GSshutdown() s_hr = E_FAIL; } +#else + + SDL_Quit(); + #endif } @@ -296,9 +310,11 @@ EXPORT_C_(int) GSopen2(void** dsp, uint32 flags) if(flags & 4) { +#ifdef _WINDOWS D3D_FEATURE_LEVEL level; renderer = GSUtil::CheckDirect3D11Level(level) && level >= D3D_FEATURE_LEVEL_10_0 ? 4 : 1; // dx11 / dx9 sw +#endif } int retval = _GSopen(dsp, NULL, renderer); diff --git a/plugins/GSdx/GSDevice11.cpp b/plugins/GSdx/GSDevice11.cpp index ac3d81fb2..c8b5c2a0b 100644 --- a/plugins/GSdx/GSDevice11.cpp +++ b/plugins/GSdx/GSDevice11.cpp @@ -53,7 +53,7 @@ bool GSDevice11::Create(GSWnd* wnd) D3D11_BUFFER_DESC bd; D3D11_SAMPLER_DESC sd; D3D11_DEPTH_STENCIL_DESC dsd; - D3D11_RASTERIZER_DESC rd; + D3D11_RASTERIZER_DESC rd; D3D11_BLEND_DESC bsd; memset(&scd, 0, sizeof(scd)); @@ -164,11 +164,11 @@ bool GSDevice11::Create(GSWnd* wnd) memset(&bd, 0, sizeof(bd)); - bd.ByteWidth = sizeof(MergeConstantBuffer); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bd.ByteWidth = sizeof(MergeConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); + hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); for(int i = 0; i < countof(m_merge.ps); i++) { @@ -192,11 +192,11 @@ bool GSDevice11::Create(GSWnd* wnd) memset(&bd, 0, sizeof(bd)); - bd.ByteWidth = sizeof(InterlaceConstantBuffer); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bd.ByteWidth = sizeof(InterlaceConstantBuffer); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); + hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); for(int i = 0; i < countof(m_interlace.ps); i++) { @@ -278,7 +278,7 @@ bool GSDevice11::Create(GSWnd* wnd) if(m_wnd->IsManaged()) { - SetExclusive(!theApp.GetConfig("windowed", 1)); + SetExclusive(!!theApp.GetConfig("windowed", 1)); } return true; diff --git a/plugins/GSdx/GSDeviceSDL.cpp b/plugins/GSdx/GSDeviceSDL.cpp index 84fec16d6..4e5f2404d 100644 --- a/plugins/GSdx/GSDeviceSDL.cpp +++ b/plugins/GSdx/GSDeviceSDL.cpp @@ -55,32 +55,7 @@ GSDeviceSDL::~GSDeviceSDL() bool GSDeviceSDL::Create(GSWnd* wnd) { - if(!SDL_WasInit(SDL_INIT_VIDEO)) - { - if(SDL_Init(SDL_INIT_VIDEO) < 0) // ok here? - { - return false; - } - - m_init = true; - } - - #if 1 //def _WINDOWS - - m_window = SDL_CreateWindowFrom(wnd->GetHandle()); - - #else - - // TODO: linux sould use wnd->GetHandle() too - - m_window = SDL_CreateWindow("GSdx", 0, 0, 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); - - #endif - - if(m_window == NULL) - { - return false; - } + m_window = (SDL_Window*)wnd->GetHandle(); return GSDeviceSW::Create(wnd); } @@ -117,6 +92,9 @@ bool GSDeviceSDL::Reset(int w, int h) return false; } + SDL_RenderClear(m_renderer); + SDL_RenderPresent(m_renderer); + m_format = SDL_PIXELFORMAT_ARGB8888; SDL_RendererInfo info; @@ -181,22 +159,40 @@ void GSDeviceSDL::Present(GSTexture* st, GSTexture* dt, const GSVector4& dr, int if(m_format == SDL_PIXELFORMAT_ARGB8888) { - for(int j = s.y; j > 0; j--, sm.bits += sm.pitch, dm.bits += dm.pitch) + if(((int)dm.bits & 15) == 0 && (dm.pitch & 15) == 0) { - GSVector4i* RESTRICT src = (GSVector4i*)sm.bits; - GSVector4i* RESTRICT dst = (GSVector4i*)dm.bits; - - for(int i = s.x >> 2; i > 0; i--, dst++, src++) + for(int j = s.y; j > 0; j--, sm.bits += sm.pitch, dm.bits += dm.pitch) { - *dst = ((*src & 0x00ff0000) >> 16) | ((*src & 0x000000ff) << 16) | (*src & 0x0000ff00); + GSVector4i* RESTRICT src = (GSVector4i*)sm.bits; + GSVector4i* RESTRICT dst = (GSVector4i*)dm.bits; + + for(int i = s.x >> 2; i > 0; i--, dst++, src++) + { + *dst = ((*src & 0x00ff0000) >> 16) | ((*src & 0x000000ff) << 16) | (*src & 0x0000ff00); + } + + uint32* RESTRICT src2 = (uint32*)src; + uint32* RESTRICT dst2 = (uint32*)dst; + + for(int i = s.x & 3; i > 0; i--, dst2++, src2++) + { + *dst2 = ((*src2 & 0x00ff0000) >> 16) | ((*src2 & 0x000000ff) << 16) | (*src2 & 0x0000ff00); + } } + } + else + { + // VirtualBox/Ubuntu does not return an aligned pointer - uint32* RESTRICT src2 = (uint32*)src; - uint32* RESTRICT dst2 = (uint32*)dst; - - for(int i = s.x & 3; i > 0; i--) + for(int j = s.y; j > 0; j--, sm.bits += sm.pitch, dm.bits += dm.pitch) { - *dst2 = ((*src2 & 0x00ff0000) >> 16) | ((*src2 & 0x000000ff) << 16) | (*src2 & 0x0000ff00); + uint32* RESTRICT src = (uint32*)sm.bits; + uint32* RESTRICT dst = (uint32*)dm.bits; + + for(int i = s.x; i > 0; i--, dst++, src++) + { + *dst = ((*src & 0x00ff0000) >> 16) | ((*src & 0x000000ff) << 16) | (*src & 0x0000ff00); + } } } } diff --git a/plugins/GSdx/GSPerfMon.cpp b/plugins/GSdx/GSPerfMon.cpp index 16e5cf572..724cc4132 100644 --- a/plugins/GSdx/GSPerfMon.cpp +++ b/plugins/GSdx/GSPerfMon.cpp @@ -41,7 +41,7 @@ void GSPerfMon::Put(counter_t c, double val) if(m_lastframe != 0) { - m_counters[c] += now - m_lastframe; + m_counters[c] += (now - m_lastframe) * 1000 / CLOCKS_PER_SEC; } m_lastframe = now; diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 49d6bcb50..8ec44e315 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -319,8 +319,11 @@ void GSRenderer::VSync(int field) #else if (m_wnd.IsManaged()) #endif - {//GSdx owns the window's title, be verbose. + { + //GSdx owns the window's title, be verbose. + string s2 = m_regs->SMODE2.INT ? (string("Interlaced ") + (m_regs->SMODE2.FFMD ? "(frame)" : "(field)")) : "Progressive"; + s = format( "%lld | %d x %d | %.2f fps (%d%%) | %s - %s | %s | %d/%d/%d | %d%% CPU | %.2f | %.2f", m_perfmon.GetFrame(), r.width(), r.height(), fps, (int)(100.0 * fps / GetFPS()), diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 099308e5a..087c95bff 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -212,6 +212,7 @@ void GSWnd::HideFrame() #else +/* GSWnd::GSWnd() : m_display(NULL) , m_window(0) @@ -271,7 +272,15 @@ bool GSWnd::SetWindowText(const char* title) { if(!m_managed) return false; - // TODO + XTextProperty p; + + p.value = (unsigned char*)title; + p.encoding = XA_STRING; + p.format = 8; + p.nitems = strlen(title); + + XSetWMName(m_display, m_window, &p); + XFlush(m_display); return m_frame; } @@ -300,5 +309,76 @@ void GSWnd::HideFrame() m_frame = false; } +*/ + +GSWnd::GSWnd() + : m_window(NULL) +{ +} + +GSWnd::~GSWnd() +{ + if(m_window != NULL) + { + SDL_DestroyWindow(m_window); + } +} + +bool GSWnd::Create(const string& title, int w, int h) +{ + if(m_window != NULL) return false; + + if(w <= 0 || h <= 0) {w = 640; h = 480;} + + m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + + return true; +} + +Display* GSWnd::GetDisplay() +{ + SDL_SysWMinfo wminfo; + + memset(&wminfo, 0, sizeof(wminfo)); + + wminfo.version.major = SDL_MAJOR_VERSION; + wminfo.version.minor = SDL_MINOR_VERSION; + + SDL_GetWindowWMInfo(m_window, &wminfo); + + return wminfo.subsystem == SDL_SYSWM_X11 ? wminfo.info.x11.display : NULL; +} + +GSVector4i GSWnd::GetClientRect() +{ + // TODO + + return GSVector4i(0, 0, 640, 480); +} + +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. + +bool GSWnd::SetWindowText(const char* title) +{ + SDL_SetWindowTitle(m_window, title); + + return true; +} + +void GSWnd::Show() +{ + SDL_ShowWindow(m_window); +} + +void GSWnd::Hide() +{ + SDL_HideWindow(m_window); +} + +void GSWnd::HideFrame() +{ + // TODO +} #endif diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index c7557fbee..e719e4286 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -55,8 +55,10 @@ public: }; #else - +/* #include +#include +#include class GSWnd { @@ -84,6 +86,32 @@ public: void Hide(); void HideFrame(); }; +*/ +#include +#include "../../3rdparty/SDL-1.3.0-5387/include/SDL.h" +#include "../../3rdparty/SDL-1.3.0-5387/include/SDL_syswm.h" + +class GSWnd +{ + SDL_Window* m_window; + +public: + GSWnd(); + virtual ~GSWnd(); + + bool Create(const string& title, int w, int h); + bool Attach(void* handle, bool managed = true) {return false;} + void Detach() {} + bool IsManaged() const {return true;} + + Display* GetDisplay(); + void* GetHandle() {return m_window;} + GSVector4i GetClientRect(); + bool SetWindowText(const char* title); + + void Show(); + void Hide(); + void HideFrame(); +}; #endif - diff --git a/plugins/GSdx/GSdx.gcc.cbp b/plugins/GSdx/GSdx.gcc.cbp index 816c9f2c4..d2d8409c9 100644 --- a/plugins/GSdx/GSdx.gcc.cbp +++ b/plugins/GSdx/GSdx.gcc.cbp @@ -12,7 +12,7 @@