gsdx-ogl: linux only

* Fix some issue on wnd management, mix between sdl/ogl render
* create new gsdx option for ogl debug
  + debug_ogl_dump: start frame to dump when not 0
  + debug_ogl_dump_length: length of the dump
  + debug_ogl_shader: print shader debug
  Note current dump option must be fixed to use linux path.


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5067 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2012-01-12 07:29:31 +00:00
parent 14b0572b61
commit cfedf41441
5 changed files with 132 additions and 250 deletions

View File

@ -243,7 +243,7 @@ endif(projectSDL)
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
target_link_libraries(${Replay} "${USER_CMAKE_LD_FLAGS}")
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
if(PACKAGE_MODE)

View File

@ -1087,6 +1087,17 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow
#ifdef _LINUX
#include <sys/time.h>
#include <sys/timeb.h> // ftime(), struct timeb
inline unsigned long timeGetTime()
{
timeb t;
ftime(&t);
return (unsigned long)(t.time*1000 + t.millitm);
}
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
@ -1206,14 +1217,14 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
}
sleep(1);
// FIXME too slow :p
// sleep(100);
//while(IsWindowVisible(hWnd))
//FIXME map?
bool finished = false;
while(!finished)
{
unsigned long start = timeGetTime();
unsigned long frame_number = 0;
for(auto i = packets.begin(); i != packets.end(); i++)
{
Packet* p = *i;
@ -1235,6 +1246,7 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
case 1:
GSvsync(p->param);
frame_number++;
break;
@ -1253,11 +1265,15 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
break;
}
}
unsigned long end = timeGetTime();
fprintf(stderr, "The %d frames of the scene was render on %dms\n", frame_number, end - start);
fprintf(stderr, "A means of %fms by frame\n", (float)(end - start)/(float)frame_number);
sleep(5);
sleep(1);
finished = true;
}
for(auto i = packets.begin(); i != packets.end(); i++)
{
delete *i;

View File

@ -21,45 +21,15 @@
#include "GSDeviceOGL.h"
// Various Note: separate build of shader
// ************************** BUILD METHOD 1
// 1/ create a stand alone prog
// uint CreateShaderProgramv( enum type, sizei count, const char **strings );
// 2/ Create various prog pipeline (maybe 1 foreach combination or only 1)
// glGenProgramPipelines
// 3/ Attach a program to a pipeline
// void UseProgramStages( uint pipeline, bitfield stages, uint program );
// ...
// ...
// 5/ Before the use of the program, we can validate it. (mandatory or not ?)
// glValidateProgramPipeline
//
// ************************** BUILD METHOD 2
// Humm, there is another solutions. You can setup function pointer in GLSL and configure them with OPENGL. shader_subroutine. glUseProgram must be replace with glUseProgramInstance in this case (and instance must be managed)
//GL EXT: Overview
//GL EXT:
//GL EXT: This extension adds support to shaders for "indirect subroutine calls",
//GL EXT: where a single shader can include many subroutines and dynamically select
//GL EXT: through the API which subroutine is called from each call site.
//GL EXT: Switching subroutines dynamically in this fashion can avoid the cost of
//GL EXT: recompiling and managing multiple shaders, while still retaining most of
//GL EXT: the performance of specialized shaders.
//
#define LOUD_DEBUGGING
#define SHADER_DEBUG
#define DUMP_START (500)
#define DUMP_LENGTH (5)
//#define LOUD_DEBUGGING
//#define PRINT_FRAME_NUMBER
//#define ONLY_LINES
// It seems dual blending does not work on AMD !!!
#define DISABLE_DUAL_BLEND
#ifdef DUMP_START
static uint32 g_draw_count = 0;
static uint32 g_frame_count = 0;
#endif
static uint32 g_frame_count = 1;
GSDeviceOGL::GSDeviceOGL()
@ -231,10 +201,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glGenFramebuffers(1, &m_fbo);
glGenFramebuffers(1, &m_fbo_read);
// Setup FBO fragment output
// OMSetFBO(m_fbo);
// glDrawBuffer(GL_COLOR_ATTACHMENT0);
// OMSetFBO(0);
// ****************************************************************
// Vertex buffer state
@ -518,28 +484,30 @@ void GSDeviceOGL::Flip()
#ifdef PRINT_FRAME_NUMBER
fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count);
#endif
#ifdef DUMP_START
g_frame_count++;
#ifdef OGL_DEBUG
if (theApp.GetConfig("debug_ogl_dump", 0) != 0)
g_frame_count++;
#endif
}
void GSDeviceOGL::DrawPrimitive()
{
#ifdef DUMP_START
#ifdef OGL_DEBUG
bool dump_me = false;
if ( (g_frame_count > DUMP_START && g_frame_count < (DUMP_START+DUMP_LENGTH)) )
dump_me = true;
uint32 start = theApp.GetConfig("debug_ogl_dump", 0);
uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5);
if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true;
#endif
// DUMP INPUT
#ifdef DUMP_START
#ifdef OGL_DEBUG
if ( dump_me ) {
for (auto i = 0 ; i < 3 ; i++) {
if (m_state.ps_srv[i] != NULL) {
m_state.ps_srv[i]->Save(format("/tmp/in_%d__%d.bmp", g_draw_count, i));
m_state.ps_srv[i]->Save(format("/tmp/in_f%d__d%d__%d.bmp", g_frame_count, g_draw_count, i));
}
}
if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/in_current_out_%d.bmp", g_draw_count));
//if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/in_current_out_%d.bmp", g_draw_count));
//if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_in_%d.bmp", g_draw_count));
fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count);
@ -553,9 +521,9 @@ void GSDeviceOGL::DrawPrimitive()
m_state.vb->draw_arrays();
// DUMP OUTPUT
#ifdef DUMP_START
#ifdef OGL_DEBUG
if ( dump_me ) {
if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_%d.bmp", g_draw_count));
if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_f%d__d%d.bmp", g_frame_count, g_draw_count));
//if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_out_%d.bmp", g_draw_count));
fprintf(stderr, "\n");
@ -926,9 +894,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
//
#ifdef DUMP_START
fprintf(stderr, "draw date!!!\n");
#endif
DrawPrimitive();
//
@ -1067,21 +1032,6 @@ void GSDeviceOGL::PSSetShader(GLuint ps)
}
}
}
#if 0
if (m_srv_changed)
{
m_ctx->PSSetShaderResources(0, 3, m_state.ps_srv);
m_srv_changed = false;
}
if(m_ss_changed)
{
m_ctx->PSSetSamplers(0, 3, m_state.ps_ss);
m_ss_changed = false;
}
#endif
}
void GSDeviceOGL::OMSetFBO(GLuint fbo)
@ -1164,9 +1114,6 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
{
m_state.scissor = r;
glScissor( r.x, r.y, r.width(), r.height() );
#if 0
m_ctx->RSSetScissorRects(1, r);
#endif
}
}
@ -1176,7 +1123,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
// Build a header string
// *****************************************************
// First select the version (must be the first line so we need to generate it
std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: enable\n#extension GL_ARB_separate_shader_objects : enable\n";
std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: require\n#extension GL_ARB_separate_shader_objects : require\n";
//std::string version = "#version 420\n";
// Allow to puts several shader in 1 files
@ -1248,19 +1195,19 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
free(header_str);
free(sources_array);
#ifdef SHADER_DEBUG
// Print a nice debug log
GLint log_length = 0;
glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length);
if (theApp.GetConfig("debug_ogl_shader", 1) == 1) {
// Print a nice debug log
GLint log_length = 0;
glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length);
char* log = (char*)malloc(log_length);
glGetProgramInfoLog(*program, log_length, NULL, log);
char* log = (char*)malloc(log_length);
glGetProgramInfoLog(*program, log_length, NULL, log);
fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program);
fprintf(stderr, "\n%s", macro_sel.c_str());
fprintf(stderr, "%s\n", log);
free(log);
#endif
fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program);
fprintf(stderr, "\n%s", macro_sel.c_str());
fprintf(stderr, "%s\n", log);
free(log);
}
}
void GSDeviceOGL::CheckDebugLog()

View File

@ -212,105 +212,6 @@ void GSWnd::HideFrame()
#else
/*
GSWnd::GSWnd()
: m_display(NULL)
, m_window(0)
, m_managed(true)
, m_frame(true)
{
}
GSWnd::~GSWnd()
{
if(m_display != NULL)
{
if(m_window != 0)
{
XDestroyWindow(m_display, m_window);
}
XCloseDisplay(m_display);
}
}
bool GSWnd::Create(const string& title, int w, int h)
{
if(m_display != NULL) return false;
if(!XInitThreads()) return false;
m_display = XOpenDisplay(0);
if(m_display == NULL) return false;
m_window = XCreateSimpleWindow(m_display, RootWindow(m_display, 0), 0, 0, 640, 480, 0, BlackPixel(m_display, 0), BlackPixel(m_display, 0));
XFlush(m_display);
return true;
}
GSVector4i GSWnd::GetClientRect()
{
int x, y;
unsigned int w, h;
unsigned int border, depth;
Window root;
XLockDisplay(m_display);
XGetGeometry(m_display, m_window, &root, &x, &y, &w, &h, &border, &depth);
XUnlockDisplay(m_display);
return GSVector4i(0, 0, w, h);
}
// 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)
{
if(!m_managed) return false;
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;
}
void GSWnd::Show()
{
if(!m_managed) return;
XMapWindow(m_display, m_window);
XFlush(m_display);
}
void GSWnd::Hide()
{
if(!m_managed) return;
XUnmapWindow(m_display, m_window);
XFlush(m_display);
}
void GSWnd::HideFrame()
{
if(!m_managed) return;
// TODO
m_frame = false;
}
*/
GSWnd::GSWnd()
: m_window(NULL), m_Xwindow(0), m_XDisplay(NULL)
{
@ -443,7 +344,6 @@ void GSWnd::Detach()
bool GSWnd::Create(const string& title, int w, int h)
{
#ifdef ENABLE_SDL_DEV
if(m_window != NULL) return false;
if(w <= 0 || h <= 0) {
@ -451,75 +351,78 @@ bool GSWnd::Create(const string& title, int w, int h)
h = theApp.GetConfig("ModeHeight", 480);
}
m_managed = true;
if (m_renderer == 2) {
#ifdef ENABLE_SDL_DEV
#ifdef _LINUX
// When you reconfigure the plugins during the play, SDL is shutdown so SDL_GetNumVideoDisplays return 0
// and the plugins is badly closed. NOTE: SDL is initialized in SDL_CreateWindow.
//
// I'm not sure this sanity check is still useful, normally (I hope) SDL_CreateWindow will return a null
// hence a false for this current function.
// For the moment do an init -- Gregory
if(!SDL_WasInit(SDL_INIT_VIDEO))
if(SDL_Init(SDL_INIT_VIDEO) < 0) return false;
// When you reconfigure the plugins during the play, SDL is shutdown so SDL_GetNumVideoDisplays return 0
// and the plugins is badly closed. NOTE: SDL is initialized in SDL_CreateWindow.
//
// I'm not sure this sanity check is still useful, normally (I hope) SDL_CreateWindow will return a null
// hence a false for this current function.
// For the moment do an init -- Gregory
if(!SDL_WasInit(SDL_INIT_VIDEO))
if(SDL_Init(SDL_INIT_VIDEO) < 0) return false;
// Sanity check; if there aren't any video displays available, we can't create a window.
if (SDL_GetNumVideoDisplays() <= 0) return false;
// Sanity check; if there aren't any video displays available, we can't create a window.
if (SDL_GetNumVideoDisplays() <= 0) return false;
#endif
m_managed = true;
m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
// Get the X window from the newly created window
// It would be needed to get the current size
SDL_SysWMinfo wminfo;
memset(&wminfo, 0, sizeof(wminfo));
// Get the X window from the newly created window
// It would be needed to get the current size
SDL_SysWMinfo wminfo;
memset(&wminfo, 0, sizeof(wminfo));
wminfo.version.major = SDL_MAJOR_VERSION;
wminfo.version.minor = SDL_MINOR_VERSION;
wminfo.version.major = SDL_MAJOR_VERSION;
wminfo.version.minor = SDL_MINOR_VERSION;
SDL_GetWindowWMInfo(m_window, &wminfo);
m_Xwindow = wminfo.info.x11.window;
SDL_GetWindowWMInfo(m_window, &wminfo);
m_Xwindow = wminfo.info.x11.window;
return (m_window != NULL);
#else
// 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
return (m_window != NULL);
} else {
// note this part must be only executed when replaying .gs debug file
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);
}
}
Display* GSWnd::GetDisplay()
@ -572,9 +475,11 @@ GSVector4i GSWnd::GetClientRect()
bool GSWnd::SetWindowText(const char* title)
{
#ifdef ENABLE_SDL_DEV
if (!m_managed) return true;
if (m_renderer == 2) {
#ifdef ENABLE_SDL_DEV
// Do not find anyway to check the current fullscreen status
// Better than nothing heuristic, check the window position. Fullscreen = (0,0)
// if(!(m_window->flags & SDL_WINDOW_FULLSCREEN) ) // Do not compile
@ -583,15 +488,27 @@ bool GSWnd::SetWindowText(const char* title)
// but we not use this function anyway.
// FIXME: it does not feel a good solution -- Gregory
// NOte: it might be more thread safe to use a call to XGetGeometry
int x,y = 0;
if (m_renderer == 2) {
int x,y = 0;
SDL_PumpEvents();
SDL_GetWindowPosition(m_window, &x, &y);
if ( x && y )
SDL_SetWindowTitle(m_window, title);
}
#endif
} else {
XTextProperty prop;
memset(&prop, 0, sizeof(prop));
char* ptitle = (char*)title;
if (XStringListToTextProperty(&ptitle, 1, &prop)) {
XSetWMName(m_XDisplay, m_Xwindow, &prop);
}
XFree(prop.value);
XFlush(m_XDisplay);
}
return true;
}

View File

@ -623,9 +623,8 @@ void ps_main()
// FIXME: I'm not sure about the value of others field
// output.c1 = c.a * 2; // used for alpha blending
#ifndef DISABLE_DUAL_BLEND
SV_Target0 = vec4(c.a*2, c.a*2, c.a*2, c.a * 2);
#endif
float alpha = c.a * 2;
if(PS_AOUT != 0) // 16 bit output
{
@ -638,6 +637,9 @@ void ps_main()
if(c.a < 0.5) c.a += 0.5;
}
#ifndef DISABLE_DUAL_BLEND
SV_Target0 = vec4(alpha, alpha, alpha, alpha);
#endif
SV_Target1 = c;
}
#endif