gsdx-ogl: add a loader to replay gs file. Quite shaky but probably enough for debug :)

git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5052 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2012-01-06 21:43:39 +00:00
parent 53a5089d7b
commit 21724ddbf8
6 changed files with 370 additions and 68 deletions

View File

@ -8,6 +8,8 @@ endif(NOT TOP_CMAKE_WAS_SOURCED)
# plugin name # plugin name
set(Output GSdx-0.1.16) set(Output GSdx-0.1.16)
set(Replay pcsx2_GSReplayLoader)
set(Static GSdx-static)
set(CommonFlags set(CommonFlags
-D_LINUX -D_LINUX
@ -179,38 +181,47 @@ set(GSdxHeaders
xbyak/xbyak_util.h xbyak/xbyak_util.h
) )
# add additional include directories
include_directories(.) include_directories(.)
# add library add_library(${Output} SHARED ${GSdxSources} ${GSdxHeaders})
add_library(${Output} SHARED
${GSdxSources} add_library(${Static} STATIC ${GSdxSources} ${GSdxHeaders})
${GSdxHeaders}
) add_executable(${Replay} linux_replay.cpp)
# link target with X11
target_link_libraries(${Output} ${X11_LIBRARIES}) target_link_libraries(${Output} ${X11_LIBRARIES})
target_link_libraries(${Output} ${GLEW_LIBRARY})
target_link_libraries(${Output} ${OPENGL_LIBRARIES})
if(projectSDL) if(projectSDL)
target_link_libraries(${Output} ${SDL_LIBRARY}) target_link_libraries(${Output} ${SDL_LIBRARY})
endif(projectSDL) endif(projectSDL)
# link target with glew target_link_libraries(${Replay} ${OPENGL_LIBRARIES})
target_link_libraries(${Output} ${GLEW_LIBRARY}) target_link_libraries(${Replay} ${X11_LIBRARIES})
target_link_libraries(${Replay} ${GLEW_LIBRARY})
target_link_libraries(${Replay} ${GTK2_LIBRARIES})
target_link_libraries(${Replay} ${Static})
# User flags options
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "") if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}") target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "") endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
if(PACKAGE_MODE) if(PACKAGE_MODE)
install(TARGETS ${Replay} DESTINATION bin)
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR}) install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${PLUGIN_DIR}) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${PLUGIN_DIR}) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${PLUGIN_DIR}) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/tfx.glsl DESTINATION ${PLUGIN_DIR}) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/tfx.glsl DESTINATION ${PLUGIN_DIR})
else(PACKAGE_MODE) else(PACKAGE_MODE)
install(TARGETS ${Replay} DESTINATION ${CMAKE_SOURCE_DIR}/bin)
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)

View File

@ -1084,3 +1084,190 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow
} }
#endif #endif
#ifdef _LINUX
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
// lpszCmdLine:
// First parameter is the renderer.
// Second parameter is the gs file to load and run.
//EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
#if 0
int renderer = -1;
{
char* start = lpszCmdLine;
char* end = NULL;
long n = strtol(lpszCmdLine, &end, 10);
if(end > start) {renderer = n; lpszCmdLine = end;}
}
while(*lpszCmdLine == ' ') lpszCmdLine++;
::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
#endif
if(FILE* fp = fopen(lpszCmdLine, "rb"))
{
//Console console("GSdx", true);
GSinit();
uint8 regs[0x2000];
GSsetBaseMem(regs);
s_vsync = !!theApp.GetConfig("vsync", 0);
void* hWnd = NULL;
_GSopen((void**)&hWnd, "", renderer);
uint32 crc;
fread(&crc, 4, 1, fp);
GSsetGameCRC(crc, 0);
GSFreezeData fd;
fread(&fd.size, 4, 1, fp);
fd.data = new uint8[fd.size];
fread(fd.data, fd.size, 1, fp);
GSfreeze(FREEZE_LOAD, &fd);
delete [] fd.data;
fread(regs, 0x2000, 1, fp);
long start = ftell(fp);
GSvsync(1);
struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};
list<Packet*> packets;
vector<uint8> buff;
int type;
while((type = fgetc(fp)) != EOF)
{
Packet* p = new Packet();
p->type = (uint8)type;
switch(type)
{
case 0:
p->param = (uint8)fgetc(fp);
fread(&p->size, 4, 1, fp);
switch(p->param)
{
case 0:
p->buff.resize(0x4000);
p->addr = 0x4000 - p->size;
fread(&p->buff[p->addr], p->size, 1, fp);
break;
case 1:
case 2:
case 3:
p->buff.resize(p->size);
fread(&p->buff[0], p->size, 1, fp);
break;
}
break;
case 1:
p->param = (uint8)fgetc(fp);
break;
case 2:
fread(&p->size, 4, 1, fp);
break;
case 3:
p->buff.resize(0x2000);
fread(&p->buff[0], 0x2000, 1, fp);
break;
}
packets.push_back(p);
}
sleep(30);
// FIXME too slow :p
// sleep(100);
//while(IsWindowVisible(hWnd))
//FIXME map?
while(true)
{
for(auto i = packets.begin(); i != packets.end(); i++)
{
Packet* p = *i;
switch(p->type)
{
case 0:
switch(p->param)
{
case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
}
break;
case 1:
GSvsync(p->param);
break;
case 2:
if(buff.size() < p->size) buff.resize(p->size);
GSreadFIFO2(&buff[0], p->size / 16);
break;
case 3:
memcpy(regs, &p->buff[0], 0x2000);
break;
}
}
}
for(auto i = packets.begin(); i != packets.end(); i++)
{
delete *i;
}
packets.clear();
sleep(100);
GSclose();
GSshutdown();
fclose(fp);
}
}
#endif

View File

@ -195,7 +195,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
s = glGetString(GL_VERSION); s = glGetString(GL_VERSION);
if (s == NULL) return false; if (s == NULL) return false;
GLuint dot; GLuint dot = 0;
while (s[dot] != '\0' && s[dot] != '.') dot++; while (s[dot] != '\0' && s[dot] != '.') dot++;
if (dot == 0) return false; if (dot == 0) return false;

View File

@ -331,6 +331,74 @@ GSWnd::~GSWnd()
} }
} }
bool GSWnd::CreateContext(int major, int minor)
{
if ( !m_XDisplay || !m_Xwindow )
{
fprintf( stderr, "Wrong X11 display/window\n" );
exit(1);
}
// Get visual information
static int attrListDbl[] =
{
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_DOUBLEBUFFER , True,
None
};
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
int fbcount = 0;
GLXFBConfig *fbc = glXChooseFBConfig(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl, &fbcount);
if (!fbc || fbcount < 1) return false;
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB");
if (!glXCreateContextAttribsARB) return false;
// Create a context
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
// FIXME : Request a debug context to ease opengl development
// Note: don't support deprecated feature (pre openg 3.1)
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None
};
m_context = glXCreateContextAttribsARB(m_XDisplay, fbc[0], 0, true, context_attribs);
if (!m_context) return false;
XSync( m_XDisplay, false);
}
void GSWnd::AttachContext()
{
glXMakeCurrent(m_XDisplay, m_Xwindow, m_context);
}
void GSWnd::DetachContext()
{
glXMakeCurrent(m_XDisplay, None, NULL);
}
void GSWnd::CheckContext()
{
int glxMajorVersion, glxMinorVersion;
glXQueryVersion(m_XDisplay, &glxMajorVersion, &glxMinorVersion);
if (glXIsDirect(m_XDisplay, m_context))
fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion);
else
fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It will be slow\n", glxMajorVersion, glxMinorVersion);
}
bool GSWnd::Attach(void* handle, bool managed) bool GSWnd::Attach(void* handle, bool managed)
{ {
m_Xwindow = *(Window*)handle; m_Xwindow = *(Window*)handle;
@ -340,60 +408,12 @@ bool GSWnd::Attach(void* handle, bool managed)
if (m_renderer != 2) { if (m_renderer != 2) {
m_XDisplay = XOpenDisplay(NULL); m_XDisplay = XOpenDisplay(NULL);
if ( !m_XDisplay ) // Note: 4.2 crash on latest nvidia drivers!
{ if (!CreateContext(3, 3)) return false;
fprintf( stderr, "Failed to open X display\n" );
exit(1);
}
// Get visual information
static int attrListDbl[] =
{
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_DOUBLEBUFFER , True,
None
};
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
int fbcount = 0;
GLXFBConfig *fbc = glXChooseFBConfig(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl, &fbcount);
if (!fbc || fbcount < 1) return false;
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); AttachContext();
if (!glXCreateContextAttribsARB) return false;
// Create a context
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
// Note: 4.2 crash on latest nvidia drivers!
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
// FIXME : Request a debug context to ease opengl development
// Note: don't support deprecated feature (pre openg 3.1)
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None
};
m_context = glXCreateContextAttribsARB(m_XDisplay, fbc[0], 0, true, context_attribs);
XSync( m_XDisplay, false);
if (!m_context) return false;
glXMakeCurrent(m_XDisplay, m_Xwindow, m_context);
// Check the status
int glxMajorVersion, glxMinorVersion;
glXQueryVersion(m_XDisplay, &glxMajorVersion, &glxMinorVersion);
if (glXIsDirect(m_XDisplay, m_context))
fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion);
else
fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It will be slow\n", glxMajorVersion, glxMinorVersion);
CheckContext();
} }
return true; return true;
@ -412,7 +432,7 @@ void GSWnd::Detach()
} }
#endif #endif
} else { } else {
glXMakeCurrent(m_XDisplay, None, NULL); DetachContext();
if (m_context) glXDestroyContext(m_XDisplay, m_context); if (m_context) glXDestroyContext(m_XDisplay, m_context);
} }
if (m_XDisplay) { if (m_XDisplay) {
@ -462,7 +482,43 @@ bool GSWnd::Create(const string& title, int w, int h)
return (m_window != NULL); return (m_window != NULL);
#else #else
return false;
// note this part must be only executed when replaying .gs debug file
m_managed = true;
m_XDisplay = XOpenDisplay(NULL);
int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_DEPTH_SIZE, 24,
None
};
XVisualInfo* vi = glXChooseVisual(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl);
/* create a color map */
XSetWindowAttributes attr;
attr.colormap = XCreateColormap(m_XDisplay, RootWindow(m_XDisplay, vi->screen),
vi->visual, AllocNone);
attr.border_pixel = 0;
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask |
EnterWindowMask | LeaveWindowMask | FocusChangeMask ;
// Create a window at the last position/size
m_Xwindow = XCreateWindow(m_XDisplay, RootWindow(m_XDisplay, vi->screen),
0 , 0 , w, h, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &attr);
XMapWindow (m_XDisplay, m_Xwindow);
XFree(vi);
if (!CreateContext(3, 3)) return false;
AttachContext();
return (m_Xwindow != 0);
#endif #endif
} }
@ -480,7 +536,8 @@ Display* GSWnd::GetDisplay()
return wminfo.subsystem == SDL_SYSWM_X11 ? wminfo.info.x11.display : NULL; return wminfo.subsystem == SDL_SYSWM_X11 ? wminfo.info.x11.display : NULL;
#else #else
return NULL; // note this part must be only executed when replaying .gs debug file
return m_XDisplay;
#endif #endif
} }

View File

@ -100,8 +100,9 @@ class GSWnd
#else #else
void* m_window; void* m_window;
#endif #endif
Window m_Xwindow; Window m_Xwindow;
Display* m_XDisplay; Display* m_XDisplay;
bool m_managed; bool m_managed;
int m_renderer; int m_renderer;
GLXContext m_context; GLXContext m_context;
@ -123,6 +124,11 @@ public:
void SetWindow(SDL_Window* current_window) { if (current_window) m_window = current_window; } void SetWindow(SDL_Window* current_window) { if (current_window) m_window = current_window; }
#endif #endif
bool CreateContext(int major, int minor);
void AttachContext();
void DetachContext();
void CheckContext();
void Show(); void Show();
void Hide(); void Hide();
void HideFrame(); void HideFrame();

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 20011-2012 Hainaut gregory
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
EXPORT_C GSsetSettingsDir(const char* dir);
EXPORT_C GSReplay(char* lpszCmdLine, int renderer);
void help()
{
fprintf(stderr, "Loader gs file\n");
fprintf(stderr, "ARG1 Ini directory\n");
fprintf(stderr, "ARG2 .gs file\n");
exit(1);
}
int main ( int argc, char *argv[] )
{
if ( argc != 3 ) help();
GSsetSettingsDir(argv[1]);
GSReplay(argv[2], 12);
}