Attached is the third version of the patch. This adds the following
functionality to VirtualGL 2.3.2:
- Advertise support for the GLX Swap Control extensions
(GLX_EXT_swap_control, GLX_SGI_swap_control).
- Modify glXQueryDrawable() to intercept the attributes
'GLX_SWAP_INTERVAL_EXT' and 'GLX_MAX_SWAP_INTERVAL_EXT' and return our
simulated interval values.
- Modify glXSwapBuffers() to simulate the "sync to vblank"
functionality.
- Add glXSwapIntervalEXT() to set the glxSwapInterval (required for the
GLX_EXT_swap_control extension).
- Modify glXSwapIntervalEXT() to set the glxSwapInterval (required for
the GLX_SGI_swap_control extension).
- Modify VGLConfig to expose the "Emulated Monitor Refresh Rate"
setting.
- Modify VGLRUN to override the default value (60) of the "Emulated
Monitor Refresh Rate" setting.
---
Thanks,
Dyweni
On 2013-06-04 15:16, Dyweni - VirtualGL-Users wrote:
Hi DRC,
You are correct. Running vglrun with '-sp -fps 60' limits the 3D
rendering rate as you described. The 3D rendering rate follows the
-fps
value. I didn't realize that -sp would lock the two rates together.
I have another patch coming soon that implements GLX_SGI_swap_control
/
glXSwapIntervalSGI and perfects the delay within glXSwapBuffers.
---
Thanks,
Dyweni
On 2013-06-04 14:13, DRC wrote:
Dyweni,
I await your response on this before I proceed any further. I need
to
resolve the matter of whether you simply forgot to disable frame
spoiling (which is what I suspect, since your previous messages made
no
mention of using the -sp switch to vglrun or setting VGL_SPOIL to 0)
or
whether, for whatever reason, disabling it did not lock the 3D
rendering
rate to VGL_FPS (and if that's the case, I'm not sure I understand
how
that could happen.)
You have to disable frame spoiling in order for the -fps option to
limit
the actual 3D rendering rate:
Did you pass 'sp' to vglrun?
vglrun -sp -fps {f} {application}
I am more keen on the idea of implementing GLX_EXT_swap_control as
opposed to implementing a separate frame rate governor, and I will
look
at your patch in detail. However, I also want to understand whether
doing the above (using the existing frame rate governor without
frame
spoiling) accomplishes a similar effect and, if not, why not.
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users
From 94981a5365268e73a278e33ef5ac14fbe8d90b63 Mon Sep 17 00:00:00 2001
From: root <r...@phenom.dyweni.com>
Date: Sun, 2 Jun 2013 15:47:23 -0500
Subject: [PATCH 1/2] VirtualGL: Add support for GLX Swap Control Extensions
This add support for the following:
- GLX_EXT_swap_control
- GLX_SGI_swap_control
---
.../work/VirtualGL-2.3.2/common/glx.h | 5 ++
.../work/VirtualGL-2.3.2/common/rr.h | 1 +
.../work/VirtualGL-2.3.2/server/faker-glx.cpp | 98 ++++++++++++++++++++--
.../work/VirtualGL-2.3.2/server/faker-mapfile.c | 1 +
.../work/VirtualGL-2.3.2/server/faker-sym.cpp | 1 +
.../work/VirtualGL-2.3.2/server/faker-sym.h | 2 +
.../work/VirtualGL-2.3.2/server/fakerconfig.cpp | 3 +
.../work/VirtualGL-2.3.2/server/vglconfig.cpp | 25 +++++-
.../work/VirtualGL-2.3.2/server/vglrun | 3 +
9 files changed, 130 insertions(+), 9 deletions(-)
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
index 962c79c..d11c87f 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
@@ -131,6 +131,9 @@ extern "C" {
#define GLX_PBUFFER_WIDTH 0x8041
#endif
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+
#ifndef GLX_ARB_get_proc_address
typedef void (*__GLXextFuncPtr)(void);
#endif
@@ -195,6 +198,8 @@ extern Bool glXQueryVersion(Display *dpy, int *major, int *minor);
extern void glXSwapBuffers(Display *dpy, GLXDrawable drawable);
+extern void glXSwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval);
+
extern void glXUseXFont(Font font, int first, int count, int list_base);
extern void glXWaitGL(void);
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
index 817b7e1..3cd9912 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
@@ -154,6 +154,7 @@ typedef struct _FakerConfig
double flushdelay;
int forcealpha;
double fps;
+ double fps3d;
double gamma;
unsigned char gamma_lut[256];
unsigned short gamma_lut16[65536];
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
index 11fc0eb..a756901 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
@@ -158,6 +158,9 @@ GLXDrawable ServerDrawable(Display *dpy, GLXDrawable draw)
extern "C" {
+static int glxSwapInterval = 1;
+static int glxMaxSwapInterval = 8;
+
// Return a set of Pbuffer-compatible FB configs from the 3D X server that
// contain the desired GLX attributes.
@@ -860,7 +863,7 @@ void glXFreeContextEXT(Display *dpy, GLXContext ctx)
// properly report the extensions and GLX version it supports.
static const char *glxextensions=
- "GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGI_make_current_read GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SUN_get_transparent_index GLX_ARB_create_context GLX_ARB_create_context_profile";
+ "GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGI_make_current_read GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SUN_get_transparent_index GLX_ARB_create_context GLX_ARB_create_context_profile GLX_EXT_swap_control GLX_SGI_swap_control";
const char *glXGetClientString(Display *dpy, int name)
{
@@ -1198,6 +1201,7 @@ void (*glXGetProcAddressARB(const GLubyte *procName))(void)
checkfaked(glXQueryExtension)
checkfaked(glXQueryVersion)
checkfaked(glXSwapBuffers)
+ checkfaked(glXSwapIntervalEXT);
checkfaked(glXUseXFont)
checkfaked(glXWaitGL)
@@ -1645,6 +1649,15 @@ void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
TRY();
+ // Intercept SWAP CONTROL attributes
+ if (attribute == GLX_SWAP_INTERVAL_EXT) {
+ *value = glxSwapInterval;
+ goto done;
+ } else if (attribute == GLX_MAX_SWAP_INTERVAL_EXT) {
+ *value = glxMaxSwapInterval;
+ goto done;
+ }
+
if(winh.isoverlay(dpy, draw))
{
_glXQueryDrawable(dpy, draw, attribute, value);
@@ -1726,17 +1739,44 @@ void glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
}
+
+#include <sys/time.h>
+#include <unistd.h>
+
+/* return current time (in seconds) */
+static double
+current_time(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return (double) tv.tv_sec * 1000000 + tv.tv_usec;
+}
+
+
// If the application is rendering to the back buffer, VirtualGL will read
// back and send the buffer whenever glXSwapBuffers() is called.
void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
{
pbwin *pbw=NULL;
+ static int frames = 0;
+ static double last = -1.0, last2 = -1.0;
+ double delay;
+ GLfloat seconds;
+ GLfloat fps;
opentrace(glXSwapBuffers); prargd(dpy); prargx(drawable); starttrace();
TRY();
+ if (last < 0.0)
+ last2 = last = current_time();
+
if(winh.isoverlay(dpy, drawable))
{
_glXSwapBuffers(dpy, drawable);
@@ -1751,6 +1791,24 @@ void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
}
else _glXSwapBuffers(_localdpy, drawable);
+ if (glxSwapInterval > 0)
+ {
+ delay = (1000000 / (fconfig.fps3d / glxSwapInterval)) - (current_time() - last);
+ if (delay > 0)
+ usleep(delay);
+ last = current_time();
+ }
+
+ frames++;
+ if (current_time() - last2 >= 5000000)
+ {
+ seconds = (current_time() - last2) / 1000000;
+ fps = frames / seconds;
+ printf("FAKER_GLX: %d frames in %3.1f seconds = %6.3f FPS (interval %i, max %i)\n", frames, seconds, fps, glxSwapInterval, glxMaxSwapInterval);
+ last2 = current_time();
+ frames = 0;
+ }
+
CATCH();
done:
@@ -1760,6 +1818,31 @@ void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
}
+// Sets the GLX SWAP CONTROL INTERVAL
+void glXSwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval)
+{
+
+ opentrace(glXMakeCurrent); prargd(dpy); prargx(drawable); prargi(interval);
+ starttrace();
+
+ TRY();
+
+ // don't set internval if beyond max interval
+ if (interval > glxMaxSwapInterval)
+ goto done;
+
+ // set the interval
+ glxSwapInterval = interval;
+
+ CATCH();
+
+ done:
+
+ stoptrace(); prargi(glxSwapInterval);
+ closetrace();
+}
+
+
// Returns the transparent index from the overlay visual on the 2D X server
int glXGetTransparentIndexSUN(Display *dpy, Window overlay,
@@ -1846,15 +1929,16 @@ Bool glXResetFrameCountNV(Display *dpy, int screen)
}
-// Recent releases of the nVidia drivers always try to send this function to
-// the 2D X server for some reason, and some apps don't bother to ask VirtualGL
-// whether it supports GLX_SGI_swap_control, so we have to interpose this
-// function out of existence (it isn't relevant with Pbuffers, anyhow.)
+// Set the emulated GLX Swap Interval.
int glXSwapIntervalSGI(int interval)
{
- if(fconfig.trace)
- rrout.print("[VGL] glXSwapIntervalSGI() [NOT SUPPORTED]\n");
+ // don't set internval if beyond max interval
+ if (interval > glxMaxSwapInterval)
+ return 1;
+
+ // now set the interval
+ glxSwapInterval = interval;
return 0;
}
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
index 21337ee..eba7c5c 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
@@ -13,6 +13,7 @@
glXQueryExtension;
glXQueryVersion;
glXSwapBuffers;
+ glXSwapIntervalEXT;
glXUseXFont;
glXWaitGL;
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
index 6532867..2d84b07 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
@@ -168,6 +168,7 @@ static int __vgl_loadglsymbols(void *dllhnd)
lsym(glXQueryExtension)
lsym(glXQueryVersion)
lsym(glXSwapBuffers)
+ lsym(glXSwapIntervalEXT);
lsym(glXUseXFont)
lsym(glXWaitGL)
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
index 30fbb7c..97617fb 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
@@ -179,6 +179,8 @@ funcdef3(Bool, glXQueryVersion, Display *, dpy, int *, major, int *, minor,
funcdef2(void, glXSwapBuffers, Display *, dpy, GLXDrawable, drawable,);
+funcdef3(void, glXSwapIntervalEXT, Display *, dpy, GLXDrawable, drawable, int, interval,);
+
funcdef4(void, glXUseXFont, Font, font, int, first, int, count, int,
list_base,);
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
index 90e31f4..bbabcb6 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
@@ -160,6 +160,7 @@ static void fconfig_init(void)
fconfig.compress=-1;
strncpy(fconfig.config, VGLCONFIG_PATH, MAXSTR);
fconfig.forcealpha=-1;
+ fconfig.fps3d=60;
fconfig_setgamma(fconfig, 1.0);
fconfig.glflushtrigger=1;
fconfig.gui=1;
@@ -307,6 +308,7 @@ void fconfig_reloadenv(void)
}
fetchenv_bool("VGL_FORCEALPHA", forcealpha);
fetchenv_dbl("VGL_FPS", fps, 0.0, 1000000.0);
+ fetchenv_dbl("VGL_FPS3D", fps3d, 0.0, 1000000.0);
if((env=getenv("VGL_GAMMA"))!=NULL && strlen(env)>0)
{
if(!strcmp(env, "1"))
@@ -548,6 +550,7 @@ void fconfig_print(FakerConfig &fc)
prconfint(compress);
prconfstr(config);
prconfdbl(fps);
+ prconfdbl(fps3d);
prconfdbl(flushdelay);
prconfint(forcealpha);
prconfdbl(gamma);
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
index 6389c60..47583b8 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
@@ -39,7 +39,7 @@ Fl_Choice *compchoice=NULL, *sampchoice=NULL,
*stereochoice=NULL, *profchoice=NULL;
Fl_Light_Button *spoilbutton=NULL, *ifbutton=NULL;
Fl_Value_Slider *qualslider=NULL;
-Fl_Float_Input *gammainput=NULL, *fpsinput;
+Fl_Float_Input *gammainput=NULL, *fpsinput, *fps3dinput;
Fl_Check_Button *fpsbutton=NULL;
int ppid=-1;
@@ -162,6 +162,13 @@ void SetFPS(void)
fpsinput->value(temps);
}
+void SetFPS3D(void)
+{
+ char temps[20];
+ snprintf(temps, 19, "%.2f", fconfig.fps3d);
+ fps3dinput->value(temps);
+}
+
// Callbacks
@@ -254,6 +261,15 @@ void FPSCB(Fl_Widget *w, void *data)
input->value(temps);
}
+void FPS3DCB(Fl_Widget *w, void *data)
+{
+ Fl_Float_Input *input=(Fl_Float_Input *)w;
+ fconfig.fps3d=atof(input->value());
+ char temps[20];
+ snprintf(temps, 19, "%.2f", fconfig.fps3d);
+ input->value(temps);
+}
+
// Menus
@@ -340,7 +356,7 @@ void init(int argc, char **argv)
{
char temps[20];
- errifnot(win=new Fl_Double_Window(485, 340, "VirtualGL Configuration"));
+ errifnot(win=new Fl_Double_Window(485, 375, "VirtualGL Configuration"));
if(strlen(fconfig.transport)>0)
{
@@ -411,6 +427,11 @@ void init(int argc, char **argv)
fpsinput->callback(FPSCB, 0);
SetFPS();
+ errifnot(fps3dinput=new Fl_Float_Input(240, 340, 85, 25,
+ "Emulate Monitor Refresh Rate: "));
+ fps3dinput->callback(FPS3DCB, 0);
+ SetFPS3D();
+
win->end();
win->show(argc, argv);
}
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
index 1b620e4..1dd4f31 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
@@ -59,6 +59,8 @@ usage()
echo
echo "-fps <f> : Limit client/server frame rate to <f> frames/sec"
echo
+ echo "-fps3d <f>: Emulate Monitor Refresh Rate [default = 60]"
+ echo
echo "-gamma <g>: Set gamma correction factor to <g> (see docs)"
echo
echo "-ge : Fool application into thinking that LD_PRELOAD is unset"
@@ -165,6 +167,7 @@ do
-v*) VGL_VERBOSE=0 ; export VGL_VERBOSE ;;
+v*) VGL_VERBOSE=1 ; export VGL_VERBOSE ;;
-fps) VGL_FPS=$2 ; export VGL_FPS ; shift ;;
+ -fps3d) VGL_FPS3D=$2 ; export VGL_FPS3D ; shift ;;
-ms) VGL_SAMPLES=$2 ; export VGL_SAMPLES ; shift ;;
-ld) LD_LIBRARY_PATH=$2:$LD_LIBRARY_PATH ;
export LD_LIBRARY_PATH ; shift ;;
--
1.8.1.5
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users